From c0bb9e152aef9d6ef0d6a2bbac50d94eda6a7b86 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 17 Jan 2024 22:52:44 +0100 Subject: [PATCH] Introduce checkmate check and send out 'gameEnded' message --- chess/board.go | 8 +++--- chess/board_test.go | 70 ++++++++++++++++++++++----------------------- chess/game.go | 14 ++++----- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/chess/board.go b/chess/board.go index 7a4b7ab..7d6a730 100644 --- a/chess/board.go +++ b/chess/board.go @@ -57,7 +57,7 @@ func (b *Board) Init() { b.position[types.Coordinate{Row: 8, Col: 8}] = Rook{Color: types.Black} } -func (b *Board) CheckAndPlay(move types.Move) (bool, Violation) { +func (b *Board) CheckAndPlay(move *types.Move) (bool, Violation) { tempBoard := b.getCopyOfBoard() //Check start square of move @@ -80,7 +80,7 @@ func (b *Board) CheckAndPlay(move types.Move) (bool, Violation) { } } - wasSpecialMove, err := tempBoard.handleSpecialMove(move) + wasSpecialMove, err := tempBoard.handleSpecialMove(*move) if err != nil { return false, InvalidMove } @@ -109,7 +109,7 @@ func (b *Board) CheckAndPlay(move types.Move) (bool, Violation) { b.position = tempBoard.position b.history = tempBoard.history b.colorToMove = b.colorToMove.Opposite() - b.appendMoveToHistory(move) + b.appendMoveToHistory(*move) pieceAtStartSquare.AfterMoveAction(b, move.StartSquare) @@ -255,7 +255,7 @@ func (b *Board) isColorCheckmated(color types.ChessColor) bool { } for _, move := range movesToCheck { - valid, _ := copyOfBoard.CheckAndPlay(move) + valid, _ := copyOfBoard.CheckAndPlay(&move) if valid { return false } diff --git a/chess/board_test.go b/chess/board_test.go index 8032008..be48f64 100644 --- a/chess/board_test.go +++ b/chess/board_test.go @@ -20,7 +20,7 @@ func Test_CheckMove_validPawnMove(t *testing.T) { EndSquare: types.Coordinate{Col: 1, Row: 3}, } - good, _ := board.CheckAndPlay(move) + good, _ := board.CheckAndPlay(&move) assert.True(t, good) //we take the pawn @@ -28,7 +28,7 @@ func Test_CheckMove_validPawnMove(t *testing.T) { StartSquare: types.Coordinate{Col: 2, Row: 4}, EndSquare: types.Coordinate{Col: 1, Row: 3}, } - good, _ = board.CheckAndPlay(secondMove) + good, _ = board.CheckAndPlay(&secondMove) assert.True(t, good) } @@ -45,7 +45,7 @@ func Test_CheckMove_enPassant(t *testing.T) { EndSquare: types.Coordinate{Col: 5, Row: 4}, } - good, reason := board.CheckAndPlay(move) + good, reason := board.CheckAndPlay(&move) assert.True(t, good) assert.Empty(t, reason) assert.Equal(t, Pawn{Color: types.White}, board.position[types.Coordinate{Col: 5, Row: 4}]) @@ -54,7 +54,7 @@ func Test_CheckMove_enPassant(t *testing.T) { StartSquare: types.Coordinate{Col: 6, Row: 4}, EndSquare: types.Coordinate{Col: 5, Row: 3}, } - good, reason = board.CheckAndPlay(newMove) + good, reason = board.CheckAndPlay(&newMove) assert.True(t, good) assert.Empty(t, reason) // the black pawn is on its correct square @@ -77,7 +77,7 @@ func Test_CheckMove_invalidPawnMoves(t *testing.T) { StartSquare: types.Coordinate{Col: 2, Row: 5}, EndSquare: types.Coordinate{Col: 2, Row: 6}, } - legalMove, _ := board.CheckAndPlay(move) + legalMove, _ := board.CheckAndPlay(&move) assert.False(t, legalMove) }) @@ -93,7 +93,7 @@ func Test_CheckMove_invalidPawnMoves(t *testing.T) { StartSquare: types.Coordinate{Col: 2, Row: 5}, EndSquare: types.Coordinate{Col: 3, Row: 5}, } - legal, _ := board.CheckAndPlay(move) + legal, _ := board.CheckAndPlay(&move) assert.False(t, legal) assert.Equal(t, boardBeforeMove, board) @@ -102,7 +102,7 @@ func Test_CheckMove_invalidPawnMoves(t *testing.T) { StartSquare: types.Coordinate{Col: 2, Row: 5}, EndSquare: types.Coordinate{Col: 1, Row: 5}, } - legal, _ = board.CheckAndPlay(move) + legal, _ = board.CheckAndPlay(&move) assert.False(t, legal) assert.Equal(t, boardBeforeMove, board) @@ -111,7 +111,7 @@ func Test_CheckMove_invalidPawnMoves(t *testing.T) { StartSquare: types.Coordinate{Col: 2, Row: 5}, EndSquare: types.Coordinate{Col: 6, Row: 5}, } - legal, _ = board.CheckAndPlay(move) + legal, _ = board.CheckAndPlay(&move) assert.False(t, legal) assert.Equal(t, boardBeforeMove, board) @@ -130,7 +130,7 @@ func Test_CheckMove_invalidPawnMoves(t *testing.T) { StartSquare: types.Coordinate{Col: 2, Row: 6}, EndSquare: types.Coordinate{Col: 2, Row: 7}, } - good, _ := board.CheckAndPlay(move) + good, _ := board.CheckAndPlay(&move) assert.False(t, good) assert.Equal(t, boardBeforeMove, board) @@ -151,7 +151,7 @@ func Test_CheckMove_validPromotion(t *testing.T) { EndSquare: types.Coordinate{Col: 1, Row: 8}, PromotionToPiece: &shortName, } - good, reason := board.CheckAndPlay(move) + good, reason := board.CheckAndPlay(&move) assert.Empty(t, reason) assert.True(t, good) @@ -179,13 +179,13 @@ func Test_CheckMove_HistoryWorks(t *testing.T) { EndSquare: types.Coordinate{Col: 1, Row: 4}, } - good, _ := board.CheckAndPlay(firstMove) + good, _ := board.CheckAndPlay(&firstMove) assert.True(t, good) - good, _ = board.CheckAndPlay(secondMove) + good, _ = board.CheckAndPlay(&secondMove) assert.True(t, good) - good, _ = board.CheckAndPlay(thirdMove) + good, _ = board.CheckAndPlay(&thirdMove) assert.True(t, good) expectedHistory := []types.Move{ @@ -221,13 +221,13 @@ func Test_Promotion_BlackKing(t *testing.T) { board.position[types.Coordinate{Col: 8, Row: 8}] = Rook{Color: types.Black} //Make dummy move for white - board.CheckAndPlay(types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) + board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) move := types.Move{ StartSquare: types.Coordinate{Col: 5, Row: 8}, EndSquare: types.Coordinate{Col: 7, Row: 8}, } - good, reason := board.CheckAndPlay(move) + good, reason := board.CheckAndPlay(&move) assert.True(t, good) assert.Empty(t, reason) @@ -246,13 +246,13 @@ func Test_Promotion_BlackKing(t *testing.T) { board.position[types.Coordinate{Col: 8, Row: 8}] = Rook{Color: types.Black} //Make dummy move for white - board.CheckAndPlay(types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) + board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) move := types.Move{ StartSquare: types.Coordinate{Col: 5, Row: 8}, EndSquare: types.Coordinate{Col: 3, Row: 8}, } - good, reason := board.CheckAndPlay(move) + good, reason := board.CheckAndPlay(&move) assert.True(t, good) assert.Empty(t, reason) @@ -272,25 +272,25 @@ func Test_Promotion_BlackKing(t *testing.T) { board.position[types.Coordinate{Col: 8, Row: 8}] = Rook{Color: types.Black} //Make dummy move for white - board.CheckAndPlay(types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) + board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) //Move black - board.CheckAndPlay(types.Move{StartSquare: types.Coordinate{Col: 5, Row: 8}, EndSquare: types.Coordinate{Col: 4, Row: 8}}) + board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 8}, EndSquare: types.Coordinate{Col: 4, Row: 8}}) //Make dummy move for white - board.CheckAndPlay(types.Move{StartSquare: types.Coordinate{Col: 5, Row: 2}, EndSquare: types.Coordinate{Col: 5, Row: 1}}) + board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 2}, EndSquare: types.Coordinate{Col: 5, Row: 1}}) //Move black back - board.CheckAndPlay(types.Move{StartSquare: types.Coordinate{Col: 4, Row: 8}, EndSquare: types.Coordinate{Col: 5, Row: 8}}) + board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 4, Row: 8}, EndSquare: types.Coordinate{Col: 5, Row: 8}}) //Make dummy move for white - board.CheckAndPlay(types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) + board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) move := types.Move{ StartSquare: types.Coordinate{Col: 5, Row: 8}, EndSquare: types.Coordinate{Col: 3, Row: 8}, } - good, _ := board.CheckAndPlay(move) + good, _ := board.CheckAndPlay(&move) assert.False(t, good) }) @@ -304,13 +304,13 @@ func Test_Promotion_BlackKing(t *testing.T) { board.position[types.Coordinate{Col: 7, Row: 8}] = Bishop{Color: types.Black} //Make dummy move for white - board.CheckAndPlay(types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) + board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) move := types.Move{ StartSquare: types.Coordinate{Col: 5, Row: 8}, EndSquare: types.Coordinate{Col: 7, Row: 8}, } - good, _ := board.CheckAndPlay(move) + good, _ := board.CheckAndPlay(&move) assert.False(t, good) }) @@ -324,13 +324,13 @@ func Test_Promotion_BlackKing(t *testing.T) { board.position[types.Coordinate{Col: 4, Row: 8}] = Bishop{Color: types.Black} //Make dummy move for white - board.CheckAndPlay(types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) + board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) move := types.Move{ StartSquare: types.Coordinate{Col: 5, Row: 8}, EndSquare: types.Coordinate{Col: 3, Row: 8}, } - good, _ := board.CheckAndPlay(move) + good, _ := board.CheckAndPlay(&move) assert.False(t, good) }) @@ -344,13 +344,13 @@ func Test_Promotion_BlackKing(t *testing.T) { board.position[types.Coordinate{Col: 3, Row: 8}] = Bishop{Color: types.Black} //Make dummy move for white - board.CheckAndPlay(types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) + board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) move := types.Move{ StartSquare: types.Coordinate{Col: 5, Row: 8}, EndSquare: types.Coordinate{Col: 3, Row: 8}, } - good, _ := board.CheckAndPlay(move) + good, _ := board.CheckAndPlay(&move) assert.False(t, good) }) @@ -364,13 +364,13 @@ func Test_Promotion_BlackKing(t *testing.T) { board.position[types.Coordinate{Col: 2, Row: 8}] = Bishop{Color: types.Black} //Make dummy move for white - board.CheckAndPlay(types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) + board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 1}, EndSquare: types.Coordinate{Col: 5, Row: 2}}) move := types.Move{ StartSquare: types.Coordinate{Col: 5, Row: 8}, EndSquare: types.Coordinate{Col: 3, Row: 8}, } - good, _ := board.CheckAndPlay(move) + good, _ := board.CheckAndPlay(&move) assert.False(t, good) }) } @@ -390,7 +390,7 @@ func Test_Board_HasGameEnded(t *testing.T) { EndSquare: types.Coordinate{Col: 8, Row: 6}, ColorMoved: types.White, } - valid, violation := board.CheckAndPlay(whiteMove) + valid, violation := board.CheckAndPlay(&whiteMove) assert.True(t, valid) assert.Empty(t, violation) @@ -406,7 +406,7 @@ func Test_Board_HasGameEnded(t *testing.T) { EndSquare: types.Coordinate{Col: 1, Row: 8}, ColorMoved: types.Black, } - valid, violation := board.CheckAndPlay(blackMove) + valid, violation := board.CheckAndPlay(&blackMove) assert.True(t, valid) assert.Empty(t, violation) @@ -416,7 +416,7 @@ func Test_Board_HasGameEnded(t *testing.T) { ColorMoved: types.White, } - valid, violation = board.CheckAndPlay(checkmateMove) + valid, violation = board.CheckAndPlay(&checkmateMove) assert.True(t, valid) assert.Empty(t, violation) @@ -441,7 +441,7 @@ func Test_Board_HasGameEnded_RookBlocks(t *testing.T) { EndSquare: types.Coordinate{Col: 8, Row: 8}, ColorMoved: types.White, } - valid, violation := board.CheckAndPlay(whiteMove) + valid, violation := board.CheckAndPlay(&whiteMove) assert.True(t, valid) assert.Empty(t, violation) diff --git a/chess/game.go b/chess/game.go index 1580264..09b6a57 100644 --- a/chess/game.go +++ b/chess/game.go @@ -110,7 +110,7 @@ func (game *Game) Handle() { game.gameState = CheckMove case CheckMove: - valid, ruleViolation := game.board.CheckAndPlay(receivedMove) + valid, ruleViolation := game.board.CheckAndPlay(&receivedMove) if !valid { invalidMoveMessage, err := api.GetInvalidMoveMessage(receivedMove, ruleViolation.String()) @@ -123,12 +123,6 @@ func (game *Game) Handle() { continue } - gameEnded, reason := game.board.HasGameEnded(receivedMove) - if gameEnded { - gameEndReason = reason - continue - } - game.gameState = CheckPlayerChange case CheckPlayerChange: @@ -144,6 +138,12 @@ func (game *Game) Handle() { return } + if gameEnded, reason := game.board.HasGameEnded(receivedMove); gameEnded { + gameEndReason = reason + game.gameState = GameEnded + continue + } + game.gameState = PlayerToMove case GameEnded: