Fix ambiguous knight moves

This commit is contained in:
ekzyis 2024-09-26 06:59:24 +02:00
parent bab667d0ed
commit 4a3315eaa0
2 changed files with 56 additions and 44 deletions

View File

@ -731,12 +731,13 @@ func (b *Board) moveBishop(position string, queen bool) error {
func (b *Board) moveKnight(position string, fromX int, fromY int) error {
var (
x int
y int
xPrev int
yPrev int
piece *Piece
err error
x int
y int
xPrev int
yPrev int
p *Piece
validPrev []*Square
err error
)
if x, y, err = getXY(position); err != nil {
@ -747,73 +748,70 @@ func (b *Board) moveKnight(position string, fromX int, fromY int) error {
xPrev = x + 1
yPrev = y - 2
piece = b.getPiece(xPrev, yPrev)
if checkMove(piece, xPrev, yPrev) {
b.tiles[xPrev][yPrev] = nil
b.tiles[x][y] = piece
return nil
p = b.getPiece(xPrev, yPrev)
if checkMove(p, xPrev, yPrev) {
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
}
xPrev = x + 2
yPrev = y - 1
piece = b.getPiece(xPrev, yPrev)
if checkMove(piece, xPrev, yPrev) {
b.tiles[xPrev][yPrev] = nil
b.tiles[x][y] = piece
return nil
p = b.getPiece(xPrev, yPrev)
if checkMove(p, xPrev, yPrev) {
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
}
xPrev = x + 2
yPrev = y + 1
piece = b.getPiece(xPrev, yPrev)
if checkMove(piece, xPrev, yPrev) {
b.tiles[xPrev][yPrev] = nil
b.tiles[x][y] = piece
return nil
p = b.getPiece(xPrev, yPrev)
if checkMove(p, xPrev, yPrev) {
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
}
xPrev = x + 1
yPrev = y + 2
piece = b.getPiece(xPrev, yPrev)
if checkMove(piece, xPrev, yPrev) {
b.tiles[xPrev][yPrev] = nil
b.tiles[x][y] = piece
return nil
p = b.getPiece(xPrev, yPrev)
if checkMove(p, xPrev, yPrev) {
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
}
xPrev = x - 1
yPrev = y + 2
piece = b.getPiece(xPrev, yPrev)
if checkMove(piece, xPrev, yPrev) {
b.tiles[xPrev][yPrev] = nil
b.tiles[x][y] = piece
return nil
p = b.getPiece(xPrev, yPrev)
if checkMove(p, xPrev, yPrev) {
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
}
xPrev = x - 2
yPrev = y + 1
piece = b.getPiece(xPrev, yPrev)
if checkMove(piece, xPrev, yPrev) {
b.tiles[xPrev][yPrev] = nil
b.tiles[x][y] = piece
return nil
p = b.getPiece(xPrev, yPrev)
if checkMove(p, xPrev, yPrev) {
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
}
xPrev = x - 2
yPrev = y - 1
piece = b.getPiece(xPrev, yPrev)
if checkMove(piece, xPrev, yPrev) {
b.tiles[xPrev][yPrev] = nil
b.tiles[x][y] = piece
return nil
p = b.getPiece(xPrev, yPrev)
if checkMove(p, xPrev, yPrev) {
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
}
xPrev = x - 1
yPrev = y - 2
piece = b.getPiece(xPrev, yPrev)
if checkMove(piece, xPrev, yPrev) {
p = b.getPiece(xPrev, yPrev)
if checkMove(p, xPrev, yPrev) {
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
}
if len(validPrev) > 1 {
return fmt.Errorf("move ambiguous: %d knights can move to %s", len(validPrev), position)
}
if len(validPrev) == 1 {
xPrev = validPrev[0].X
yPrev = validPrev[0].Y
p = b.getPiece(xPrev, yPrev)
b.tiles[x][y] = p
b.tiles[xPrev][yPrev] = nil
b.tiles[x][y] = piece
return nil
}

View File

@ -189,6 +189,20 @@ func TestBoardMoveKnightInvalid(t *testing.T) {
assertMoveError(t, b, "Ne7", "e7 blocked by black pawn")
assertMoveError(t, b, "Nd7", "d7 blocked by black pawn")
// ambiguous moves
b = chess.NewBoard()
assertParse(t, b, "e4 e5 Nf3 d6 Nc3 d5 Nb5 d4")
assertMoveError(t, b, "Nxd4", "move ambiguous: 2 knights can move to d4")
assertMoveError(t, b, "N4xd4", "no knight found that can move to d4")
// disambiguate via file
assertParse(t, b, "Nfxd4")
b = chess.NewBoard()
assertParse(t, b, "e4 e5 Nf3 d6 Nc3 d5 Nb5 d4")
// disambiguate via rank
assertParse(t, b, "N3xd4")
}
func TestBoardMoveKnightCapture(t *testing.T) {