diff --git a/chess/board.go b/chess/board.go index 82e8275..5e592f2 100644 --- a/chess/board.go +++ b/chess/board.go @@ -292,17 +292,20 @@ func (b *Board) Move(move string) error { return err } - if move == "O-O" { + if move == "O-O" || move == "O-O-O" { castle = true if b.turn == Dark { - to = "g8" fromY = 0 + if move == "O-O" { + to = "g8" + } else { + to = "c8" + } } } // TODO: parse ambiguous captures for all pieces // TODO: parse checkmates e.g. e5# - // TODO: parse O-O as kingside castle and O-O-O as queenside castle move_ := func() error { @@ -369,6 +372,10 @@ func parseMove(move string) (string, int, int, string, error) { return "K", 5, 7, "g1", nil } + if move == "O-O-O" { + return "K", 5, 7, "c1", nil + } + if strings.Contains(move, "x") { return parseCaptureMove(move) } @@ -1176,6 +1183,39 @@ func (b *Board) moveKing(position string, castle bool) error { return nil } + + if (b.turn == Light && position == "c1") || (b.turn == Dark && position == "c8") { + // queenside castle + + king := b.getPiece(4, y) + if king == nil || king.Color != b.turn || king.Name != King { + return fmt.Errorf("invalid castle move") + } + + if b.getPiece(3, y) != nil { + return fmt.Errorf("invalid castle move") + } + + if b.getPiece(2, y) != nil { + return fmt.Errorf("invalid castle move") + } + + if b.getPiece(1, y) != nil { + return fmt.Errorf("invalid castle move") + } + + rook := b.getPiece(0, y) + if rook == nil || rook.Color != b.turn || rook.Name != Rook { + return fmt.Errorf("invalid castle move") + } + + b.tiles[2][y] = king + b.tiles[4][y] = nil + b.tiles[3][y] = rook + b.tiles[0][y] = nil + + return nil + } } // ^ diff --git a/chess/board_test.go b/chess/board_test.go index b06a3d4..e2f219c 100644 --- a/chess/board_test.go +++ b/chess/board_test.go @@ -500,6 +500,15 @@ func TestBoardCastle(t *testing.T) { assertPiece(t, b, "g8", chess.King, chess.Dark) assertNoPiece(t, b, "h8") assertNoPiece(t, b, "e8") + + b = chess.NewBoard() + + assertParse(t, b, "e4 e5 Qg4 d6 d3 d5 Be3 d4 Nc3 dxe3 O-O-O") + + assertPiece(t, b, "d1", chess.Rook, chess.Light) + assertPiece(t, b, "c1", chess.King, chess.Light) + assertNoPiece(t, b, "a1") + assertNoPiece(t, b, "e1") } func assertParse(t *testing.T, b *chess.Board, moves string) {