package chess import ( "mchess_server/types" ) type King struct { Color types.ChessColor } func (k King) GetAllAttackedSquares(board Board, fromSquare types.Coordinate) []types.Coordinate { return k.GetAllNonBlockedMoves(board, fromSquare) } func (k King) GetColor() types.ChessColor { return k.Color } func (k King) GetAllNonBlockedMoves(board Board, fromSquare types.Coordinate) []types.Coordinate { return board.GetNonBlockedKingMoves(fromSquare) } func (k King) AfterMoveAction(board *Board, fromSquare types.Coordinate) { switch k.Color { case types.Black: board.state.BlackKingMoved = true case types.White: board.state.WhiteKingMoved = true } } func (k King) HandleCastling(board *Board, move types.Move) (bool, error) { if k.hadMovedBefore(board) { return false, nil } valid, dir := k.movedOnValidCastlingSquare(board, move) if !valid { return false, nil } switch k.Color { case types.White: board.state.WhiteKingMoved = true case types.Black: board.state.BlackKingMoved = true } k.playCastlingOnBoard(board, move, dir) return true, nil } func (k King) hadMovedBefore(b *Board) bool { var hasMoved bool switch k.Color { case types.White: hasMoved = b.state.WhiteKingMoved case types.Black: hasMoved = b.state.BlackKingMoved } return hasMoved } type CastlingDirection string const ( CastlingRight CastlingDirection = "right" CastlingLeft CastlingDirection = "left" ) func (k King) movedOnValidCastlingSquare(b *Board, move types.Move) (bool, CastlingDirection) { var valid = false switch k.Color { case types.White: castlingSquareRight := types.Coordinate{Col: 7, Row: 1} castlingSquareLeft := types.Coordinate{Col: 3, Row: 1} if move.EndSquare == castlingSquareRight && b.getPieceAt(castlingSquareRight) == nil && b.getPieceAt(*castlingSquareRight.Left(1)) == nil && !b.state.WhiteHRookMoved { return true, CastlingRight } if move.EndSquare == castlingSquareLeft && b.getPieceAt(castlingSquareLeft) == nil && b.getPieceAt(*castlingSquareLeft.Right(1)) == nil && b.getPieceAt(*castlingSquareLeft.Left(1)) == nil && !b.state.WhiteARookMoved { return true, CastlingLeft } case types.Black: castlingSquareRight := types.Coordinate{Col: 7, Row: 8} castlingSquareLeft := types.Coordinate{Col: 3, Row: 8} if move.EndSquare == castlingSquareRight && b.getPieceAt(castlingSquareRight) == nil && b.getPieceAt(*castlingSquareRight.Left(1)) == nil && !b.state.BlackHRookMoved { return true, CastlingRight } if move.EndSquare == castlingSquareLeft && b.getPieceAt(castlingSquareLeft) == nil && b.getPieceAt(*castlingSquareLeft.Right(1)) == nil && b.getPieceAt(*castlingSquareLeft.Left(1)) == nil && !b.state.BlackARookMoved { return true, CastlingLeft } } return valid, CastlingRight } func (k King) playCastlingOnBoard(board *Board, move types.Move, dir CastlingDirection) { onRow := move.StartSquare.Row switch dir { case CastlingRight: delete(board.position, types.Coordinate{Col: 8, Row: onRow}) delete(board.position, types.Coordinate{Col: 5, Row: onRow}) board.position[types.Coordinate{Col: 7, Row: onRow}] = King{Color: k.Color} board.position[types.Coordinate{Col: 6, Row: onRow}] = Rook(k) case CastlingLeft: delete(board.position, types.Coordinate{Col: 1, Row: onRow}) delete(board.position, types.Coordinate{Col: 5, Row: onRow}) board.position[types.Coordinate{Col: 3, Row: onRow}] = King{Color: k.Color} board.position[types.Coordinate{Col: 4, Row: onRow}] = Rook(k) } }