Add kingside castle

This commit is contained in:
ekzyis 2024-09-26 10:21:09 +02:00
parent be247e1f46
commit 7aa65f4ec0
2 changed files with 73 additions and 2 deletions

View File

@ -278,6 +278,7 @@ func (b *Board) Move(move string) error {
fromX int fromX int
fromY int fromY int
promotion string promotion string
castle = false
collisionPiece *Piece collisionPiece *Piece
err error err error
) )
@ -291,6 +292,14 @@ func (b *Board) Move(move string) error {
return err return err
} }
if move == "O-O" {
castle = true
if b.turn == Dark {
to = "g8"
fromY = 0
}
}
// TODO: parse ambiguous captures for all pieces // TODO: parse ambiguous captures for all pieces
// TODO: parse checkmates e.g. e5# // TODO: parse checkmates e.g. e5#
// TODO: parse O-O as kingside castle and O-O-O as queenside castle // TODO: parse O-O as kingside castle and O-O-O as queenside castle
@ -316,7 +325,7 @@ func (b *Board) Move(move string) error {
case "q": case "q":
return b.moveQueen(to) return b.moveQueen(to)
case "k": case "k":
return b.moveKing(to) return b.moveKing(to, castle)
default: default:
return fmt.Errorf("invalid move %s: %v", move, err) return fmt.Errorf("invalid move %s: %v", move, err)
} }
@ -356,6 +365,10 @@ func parseMove(move string) (string, int, int, string, error) {
from string from string
) )
if move == "O-O" {
return "K", 5, 7, "g1", nil
}
if strings.Contains(move, "x") { if strings.Contains(move, "x") {
return parseCaptureMove(move) return parseCaptureMove(move)
} }
@ -1113,7 +1126,7 @@ func (b *Board) moveQueen(position string) error {
return fmt.Errorf("no queen found that can move to %s", position) return fmt.Errorf("no queen found that can move to %s", position)
} }
func (b *Board) moveKing(position string) error { func (b *Board) moveKing(position string, castle bool) error {
var ( var (
x int x int
y int y int
@ -1127,6 +1140,44 @@ func (b *Board) moveKing(position string) error {
return err return err
} }
if castle {
// TODO: check if castle is allowed
y := 7
if b.turn == Dark {
y = 0
}
if (b.turn == Light && position == "g1") || (b.turn == Dark && position == "g8") {
// kingside 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(5, y) != nil {
return fmt.Errorf("invalid castle move")
}
if b.getPiece(6, y) != nil {
return fmt.Errorf("invalid castle move")
}
rook := b.getPiece(7, y)
if rook == nil || rook.Color != b.turn || rook.Name != Rook {
return fmt.Errorf("invalid castle move")
}
b.tiles[6][y] = king
b.tiles[4][y] = nil
b.tiles[5][y] = rook
b.tiles[7][y] = nil
return nil
}
}
// ^ // ^
xPrev = x + 0 xPrev = x + 0
yPrev = y - 1 yPrev = y - 1

View File

@ -482,6 +482,26 @@ func TestBoardPin(t *testing.T) {
assertMoveError(t, b, "Ne4", "invalid move Ne4: king is in check") assertMoveError(t, b, "Ne4", "invalid move Ne4: king is in check")
} }
func TestBoardCastle(t *testing.T) {
t.Parallel()
b := chess.NewBoard()
assertParse(t, b, "e4 e5 Nf3 Nf6 Be2 Be7 O-O")
assertPiece(t, b, "f1", chess.Rook, chess.Light)
assertPiece(t, b, "g1", chess.King, chess.Light)
assertNoPiece(t, b, "h1")
assertNoPiece(t, b, "e1")
assertParse(t, b, "O-O")
assertPiece(t, b, "f8", chess.Rook, chess.Dark)
assertPiece(t, b, "g8", chess.King, chess.Dark)
assertNoPiece(t, b, "h8")
assertNoPiece(t, b, "e8")
}
func assertParse(t *testing.T, b *chess.Board, moves string) { func assertParse(t *testing.T, b *chess.Board, moves string) {
assert.NoError(t, b.Parse(moves)) assert.NoError(t, b.Parse(moves))
} }