Skip to content

Commit

Permalink
added undo-redo tests
Browse files Browse the repository at this point in the history
added default impl

updated version
  • Loading branch information
matimiodosky committed May 18, 2024
1 parent f1a34f4 commit 35f4217
Show file tree
Hide file tree
Showing 13 changed files with 324 additions and 31 deletions.
2 changes: 1 addition & 1 deletion test-framework/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ plugins {


group = "edu.austral.dissis.chess"
version = "1.3.0"
version = "1.4.0"

repositories {
mavenLocal()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package edu.austral.dissis.chess.test

import edu.austral.dissis.chess.test.game.TestInput

class TestGame(
val title: String,
val initialBoard: TestBoard,
val movements: List<Pair<TestPosition, TestPosition>>,
val inputs: List<TestInput>,
val testResult: TestGameResult,
val finalBoard: TestBoard
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package edu.austral.dissis.chess.test.game

import edu.austral.dissis.chess.test.TestPosition

sealed interface TestInput {
}

data class TestMove(val from: TestPosition, val to: TestPosition) : TestInput

data object Undo : TestInput

data object Redo : TestInput

Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,33 @@ class GameTester(private val runner: TestGameRunner) {
private fun runMoves(
title: String,
runner: TestGameRunner,
moves: List<Pair<TestPosition, TestPosition>>
moves: List<TestInput>
): TestGameRunner {
return moves.fold(runner) { currentRunner, (from, to) ->
when (val result = currentRunner.executeMove(from, to)) {
return moves.fold(runner) { currentRunner, input ->
val result = when (input) {
is Undo -> currentRunner.undo()
is Redo -> currentRunner.redo()
is TestMove -> currentRunner.executeMove(input.from, input.to)
}
when (result) {
is TestMoveSuccess -> result.testGameRunner
is FinalTestMoveResult -> fail(failedMoveMessage(title, from, to, result))
is FinalTestMoveResult -> fail(failedMoveMessage(title, input, result))
}
}
}

private fun assertAllMovesValid(testGame: TestGame) {
val initialRunner = runner.withBoard(testGame.initialBoard)
val resultingRunner = runMoves(testGame.title, initialRunner, testGame.movements)
val resultingRunner = runMoves(testGame.title, initialRunner, testGame.inputs)
checkFinalBoardMatches(resultingRunner.getBoard(), testGame.finalBoard)
}

private fun assertLastMove(testGame: TestGame, checkResult: (FinalTestMoveResult) -> Boolean) {
val initialRunner = runner.withBoard(testGame.initialBoard)
val preparatoryMoves = testGame.movements.dropLast(1)
val lastMove = testGame.movements.last()
val preparatoryMoves = testGame.inputs.dropLast(1)
val lastMove = testGame.inputs.last() as TestMove
val finalRunner = runMoves(testGame.title, initialRunner, preparatoryMoves)
when (val result = finalRunner.executeMove(lastMove.first, lastMove.second)) {
when (val result = finalRunner.executeMove(lastMove.from, lastMove.to)) {
is TestMoveSuccess -> fail("${testGame.title} failed, last move should result in game end but did not")
is FinalTestMoveResult -> {
if (!checkResult(result)) {
Expand Down Expand Up @@ -116,21 +121,25 @@ class GameTester(private val runner: TestGameRunner) {

private fun failedMoveMessage(
title: String,
from: TestPosition,
to: TestPosition,
input: TestInput,
result: FinalTestMoveResult
): String {

// take 1-based int and return a string with the char. a for 1, b for 2, etc.
val fromFile = ('a'.code + from.col -1 ).toChar()
val fromRank = from.row
return when (input) {
is Undo -> "$title failed, undo should not result in game end"
is Redo -> "$title failed, redo should not result in game end"
is TestMove -> {
val fromFile = ('a'.code + input.from.col - 1).toChar()
val fromRank = input.from.row

val toFile = ('a'.code + to.col -1 ).toChar()
val toRank = to.row
val toFile = ('a'.code + input.to.col - 1).toChar()
val toRank = input.to.row

val pieceType = result.finalBoard.pieces[from].toString()
val pieceType = result.finalBoard.pieces[input.from].toString()

return "$title failed, moving $pieceType from $fromFile$fromRank to $toFile$toRank"
"$title failed, moving $pieceType from $fromFile$fromRank to $toFile$toRank"
}
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,13 @@ interface TestGameRunner {

fun executeMove(from: TestPosition, to: TestPosition): TestMoveResult

fun undo(): TestMoveResult {
TODO("not implemented")
}

fun redo(): TestMoveResult {
TODO("not implemented")
}

fun getBoard(): TestBoard
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package edu.austral.dissis.chess.test.gameParser

import edu.austral.dissis.chess.test.*
import edu.austral.dissis.chess.test.game.TestInput
import edu.austral.dissis.chess.test.game.TestMove
import edu.austral.dissis.chess.test.game.Redo
import edu.austral.dissis.chess.test.game.Undo
import edu.austral.dissis.chess.test.parserUtils.MatrixParser

class GameBoardParser {
Expand All @@ -14,14 +18,14 @@ class GameBoardParser {
val title = parseTitle(lines)
val size = parseSize(lines)
val board = parseStartingBoard(lines, size)
val movements = parseMoves(lines)
val inputs = parseInputs(lines)
val result = parseResult(lines)
val finalBoard = parseFinalBoard(lines, size)

return TestGame(
title,
board,
movements,
inputs,
result,
finalBoard
)
Expand Down Expand Up @@ -102,14 +106,16 @@ class GameBoardParser {
return createBoard(size, pieces)
}

private fun parseMoves(lines: List<String>): List<Pair<TestPosition, TestPosition>> {
private fun parseInputs(lines: List<String>): List<TestInput> {
/*
* Format is:
# Moves
1. e2 e4
2. e7 e5
3. g1 f3
1. e2-e4
2. e7-e5
3. UNDO
4. REDO
5. g1-f3
* */
val headerLine = lines.indexOfFirst { it.startsWith("# Moves") }
Expand All @@ -119,8 +125,16 @@ class GameBoardParser {
val moves = lines.subList(headerLine + 1, headerLine + nextEmptyLine)
return moves
.map { it.split(" ")[1] }
.map { it.split("-") }
.map { Pair(TestPosition.fromAlgebraic(it[0]), TestPosition.fromAlgebraic(it[1])) }
.map {
when (it) {
"UNDO" -> Undo
"REDO" -> Redo
else -> {
val parts = it.split("-")
TestMove(TestPosition.fromAlgebraic(parts[0]), TestPosition.fromAlgebraic(parts[1]))
}
}
}
}

private fun parseResult(lines: List<String>): TestGameResult {
Expand Down
47 changes: 47 additions & 0 deletions test-framework/src/main/resources/test_cases/four_redos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 4 redos

# Size
width = 8
height = 8

# Starting board
```
a b c d e f g h
1 | | | | |WK| | | |
2 | | | | |WP| | | |
3 | | | | | | | | |
4 | | | | | | | | |
5 | | | | | | | | |
6 | | | | | | | | |
7 | | | | |BP| | | |
8 | | | | |BK| | | |
```
# Moves
1. e2-e3
2. e7-e6
3. e3-e4
4. e6-e5
5. UNDO
6. UNDO
7. UNDO
8. UNDO
9. REDO
10. REDO
11. REDO
12. REDO

# Result
`ALL_MOVES_VALID`

# Final board
```
a b c d e f g h
1 | | | | |WK| | | |
2 | | | | | | | | |
3 | | | | | | | | |
4 | | | | |WP| | | |
5 | | | | |BP| | | |
6 | | | | | | | | |
7 | | | | | | | | |
8 | | | | |BK| | | |
```
39 changes: 39 additions & 0 deletions test-framework/src/main/resources/test_cases/redo_pawn_movement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Redo Pawn Movement

# Size
width = 8
height = 8

# Starting board
```
a b c d e f g h
1 | | | | |WK| | | |
2 | | | | |WP| | | |
3 | | | | | | | | |
4 | | | | | | | | |
5 | | | | | | | | |
6 | | | | | | | | |
7 | | | | | | | | |
8 | | | | |BK| | | |
```
# Moves
1. e2-e4
2. UNDO
3. REDO


# Result
`ALL_MOVES_VALID`

# Final board
```
a b c d e f g h
1 | | | | |WK| | | |
2 | | | | | | | | |
3 | | | | | | | | |
4 | | | | |WP| | | |
5 | | | | | | | | |
6 | | | | | | | | |
7 | | | | | | | | |
8 | | | | |BK| | | |
```
38 changes: 38 additions & 0 deletions test-framework/src/main/resources/test_cases/undo_pawn_movement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Undo Pawn Movement

# Size
width = 8
height = 8

# Starting board
```
a b c d e f g h
1 | | | | |WK| | | |
2 | | | | |WP| | | |
3 | | | | | | | | |
4 | | | | | | | | |
5 | | | | | | | | |
6 | | | | | | | | |
7 | | | | | | | | |
8 | | | | |BK| | | |
```
# Moves
1. e2-e4
2. UNDO


# Result
`ALL_MOVES_VALID`

# Final board
```
a b c d e f g h
1 | | | | |WK| | | |
2 | | | | |WP| | | |
3 | | | | | | | | |
4 | | | | | | | | |
5 | | | | | | | | |
6 | | | | | | | | |
7 | | | | | | | | |
8 | | | | |BK| | | |
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Undo pawn movement still white turn

# Size
width = 8
height = 8

# Starting board
```
a b c d e f g h
1 | | | | |WK| | | |
2 | | | | |WP| | | |
3 | | | | | | | | |
4 | | | | | | | | |
5 | | | | | | | | |
6 | | | | | | | | |
7 | | | | |BP| | | |
8 | | | | |BK| | | |
```
# Moves
1. e2-e3
2. e7-e6
3. UNDO
4. e7-e5


# Result
`ALL_MOVES_VALID`

# Final board
```
a b c d e f g h
1 | | | | |WK| | | |
2 | | | | | | | | |
3 | | | | |WP| | | |
4 | | | | | | | | |
5 | | | | |BP| | | |
6 | | | | | | | | |
7 | | | | | | | | |
8 | | | | |BK| | | |
```
Loading

0 comments on commit 35f4217

Please sign in to comment.