From d40c7577765dd093d409ac756e0b9e05873ef46a Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 10 May 2024 02:29:11 +0200 Subject: [PATCH] fix bug that prevented king from moving because server thought it wanted to castling (but it was not a castling move) --- chess/board_castling_test.go | 31 +++++++++++++++++++++++++++++++ chess/king.go | 26 ++++++++++++++++++++++++++ chess/violation.go | 1 + 3 files changed, 58 insertions(+) diff --git a/chess/board_castling_test.go b/chess/board_castling_test.go index a2ad144..00440f0 100644 --- a/chess/board_castling_test.go +++ b/chess/board_castling_test.go @@ -296,3 +296,34 @@ func Test_Board_BlackCastlesRight_NoRook(t *testing.T) { assert.False(t, valid) } + +func Test_Board_fixBugThatPreventsCastling(t *testing.T) { + board := newBoard() + board.Init() + + //white move + valid, violation := board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 2}, EndSquare: types.Coordinate{Col: 5, Row: 3}}) + assert.True(t, valid) + assert.Empty(t, violation) + //black move + valid, violation = board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 7}, EndSquare: types.Coordinate{Col: 5, Row: 6}}) + assert.True(t, valid) + assert.Empty(t, violation) + //white move + valid, violation = board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 4, Row: 2}, EndSquare: types.Coordinate{Col: 4, Row: 3}}) + assert.True(t, valid) + assert.Empty(t, violation) + //black move + valid, violation = board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 6, Row: 7}, EndSquare: types.Coordinate{Col: 6, Row: 6}}) + assert.True(t, valid) + assert.Empty(t, violation) + //queen moves to check the king + valid, violation = board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 4, Row: 1}, EndSquare: types.Coordinate{Col: 8, Row: 5}}) + assert.True(t, valid) + assert.Empty(t, violation) + + //this moves should be valid but it was not because of a bug + valid, violation = board.CheckAndPlay(&types.Move{StartSquare: types.Coordinate{Col: 5, Row: 8}, EndSquare: types.Coordinate{Col: 5, Row: 7}}) + assert.True(t, valid) + assert.Empty(t, violation) +} diff --git a/chess/king.go b/chess/king.go index b59bc4d..a8b7df2 100644 --- a/chess/king.go +++ b/chess/king.go @@ -30,6 +30,10 @@ func (k King) AfterMoveAction(board *Board, fromSquare types.Coordinate) { } func (k King) HandleCastling(board *Board, move types.Move) (bool, Violation) { + if !k.isMoveCastlingMove(board, move) { + return false, "" + } + if k.hadMovedBefore(board) { return false, "" } @@ -66,6 +70,28 @@ const ( CastlingLeft CastlingDirection = "left" ) +func (k King) isMoveCastlingMove(b *Board, move types.Move) bool { + var destinationSquareForKingRight types.Coordinate + var destinationSquareForKingLeft types.Coordinate + + switch k.Color { + case types.White: + destinationSquareForKingRight = types.Coordinate{Col: 7, Row: 1} + destinationSquareForKingLeft = types.Coordinate{Col: 3, Row: 1} + + case types.Black: + destinationSquareForKingRight = types.Coordinate{Col: 7, Row: 8} + destinationSquareForKingLeft = types.Coordinate{Col: 3, Row: 8} + } + + if move.EndSquare == destinationSquareForKingRight || + move.EndSquare == destinationSquareForKingLeft { + return true + } + + return false +} + func (k King) isCastlingAllowed(b *Board, move types.Move) (bool, CastlingDirection) { var valid = false diff --git a/chess/violation.go b/chess/violation.go index 8cc45c7..1bc22ef 100644 --- a/chess/violation.go +++ b/chess/violation.go @@ -11,6 +11,7 @@ var ( SomethingWentWrong Violation = "something went wrong" CastlingThroughCheck Violation = "king would move through check" CastlingWhileKingInCheck Violation = "king cannot castle while in check" + CastlingKingMovedBefore Violation = "king cannot caslte because he moved before" ) func (v Violation) String() string {