Fix ambiguous knight capture
This commit is contained in:
parent
8f70fcb552
commit
a9a4216d4e
|
@ -285,7 +285,20 @@ func (b *Board) Move(move string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if captureFrom != -1 {
|
if captureFrom != -1 {
|
||||||
move = strings.Split(move, "x")[1]
|
parts := strings.Split(move, "x")
|
||||||
|
piece := parts[0]
|
||||||
|
position := parts[1]
|
||||||
|
if strings.ToLower(piece) == piece {
|
||||||
|
// pawn capture move like exd4
|
||||||
|
move = position
|
||||||
|
} else {
|
||||||
|
// piece capture move like Nbxd4
|
||||||
|
// remove the capture column from the piece
|
||||||
|
move = piece[:1] + position
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// even if captureFrom is not set, it might still be a capture move just unambiguous like Nxe4
|
||||||
|
move = strings.Replace(move, "x", "", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: parse promotions
|
// TODO: parse promotions
|
||||||
|
@ -318,7 +331,7 @@ func (b *Board) Move(move string) error {
|
||||||
case "b":
|
case "b":
|
||||||
return b.moveBishop(targetPosition, false)
|
return b.moveBishop(targetPosition, false)
|
||||||
case "n":
|
case "n":
|
||||||
return b.moveKnight(targetPosition)
|
return b.moveKnight(targetPosition, captureFrom)
|
||||||
case "q":
|
case "q":
|
||||||
return b.moveQueen(targetPosition)
|
return b.moveQueen(targetPosition)
|
||||||
case "k":
|
case "k":
|
||||||
|
@ -640,7 +653,7 @@ func (b *Board) moveBishop(position string, queen bool) error {
|
||||||
return fmt.Errorf("no bishop found that can move to %s", position)
|
return fmt.Errorf("no bishop found that can move to %s", position)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Board) moveKnight(position string) error {
|
func (b *Board) moveKnight(position string, captureFrom int) error {
|
||||||
var (
|
var (
|
||||||
x int
|
x int
|
||||||
y int
|
y int
|
||||||
|
@ -654,10 +667,17 @@ func (b *Board) moveKnight(position string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkMove := func(p *Piece, xPrev int) bool {
|
||||||
|
// capture condition fulfilled if capture
|
||||||
|
capture := captureFrom == -1 || xPrev == captureFrom
|
||||||
|
found := p != nil && p.Name == Knight && p.Color == b.turn
|
||||||
|
return capture && found
|
||||||
|
}
|
||||||
|
|
||||||
xPrev = x + 1
|
xPrev = x + 1
|
||||||
yPrev = y - 2
|
yPrev = y - 2
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
piece = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil && piece.Name == Knight && piece.Color == b.turn {
|
if checkMove(piece, xPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
b.tiles[xPrev][yPrev] = nil
|
||||||
b.tiles[x][y] = piece
|
b.tiles[x][y] = piece
|
||||||
return nil
|
return nil
|
||||||
|
@ -666,7 +686,7 @@ func (b *Board) moveKnight(position string) error {
|
||||||
xPrev = x + 2
|
xPrev = x + 2
|
||||||
yPrev = y - 1
|
yPrev = y - 1
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
piece = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil && piece.Name == Knight && piece.Color == b.turn {
|
if checkMove(piece, xPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
b.tiles[xPrev][yPrev] = nil
|
||||||
b.tiles[x][y] = piece
|
b.tiles[x][y] = piece
|
||||||
return nil
|
return nil
|
||||||
|
@ -675,7 +695,7 @@ func (b *Board) moveKnight(position string) error {
|
||||||
xPrev = x + 2
|
xPrev = x + 2
|
||||||
yPrev = y + 1
|
yPrev = y + 1
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
piece = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil && piece.Name == Knight && piece.Color == b.turn {
|
if checkMove(piece, xPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
b.tiles[xPrev][yPrev] = nil
|
||||||
b.tiles[x][y] = piece
|
b.tiles[x][y] = piece
|
||||||
return nil
|
return nil
|
||||||
|
@ -684,7 +704,7 @@ func (b *Board) moveKnight(position string) error {
|
||||||
xPrev = x + 1
|
xPrev = x + 1
|
||||||
yPrev = y + 2
|
yPrev = y + 2
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
piece = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil && piece.Name == Knight && piece.Color == b.turn {
|
if checkMove(piece, xPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
b.tiles[xPrev][yPrev] = nil
|
||||||
b.tiles[x][y] = piece
|
b.tiles[x][y] = piece
|
||||||
return nil
|
return nil
|
||||||
|
@ -693,7 +713,7 @@ func (b *Board) moveKnight(position string) error {
|
||||||
xPrev = x - 1
|
xPrev = x - 1
|
||||||
yPrev = y + 2
|
yPrev = y + 2
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
piece = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil && piece.Name == Knight && piece.Color == b.turn {
|
if checkMove(piece, xPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
b.tiles[xPrev][yPrev] = nil
|
||||||
b.tiles[x][y] = piece
|
b.tiles[x][y] = piece
|
||||||
return nil
|
return nil
|
||||||
|
@ -702,7 +722,7 @@ func (b *Board) moveKnight(position string) error {
|
||||||
xPrev = x - 2
|
xPrev = x - 2
|
||||||
yPrev = y + 1
|
yPrev = y + 1
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
piece = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil && piece.Name == Knight && piece.Color == b.turn {
|
if checkMove(piece, xPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
b.tiles[xPrev][yPrev] = nil
|
||||||
b.tiles[x][y] = piece
|
b.tiles[x][y] = piece
|
||||||
return nil
|
return nil
|
||||||
|
@ -711,7 +731,7 @@ func (b *Board) moveKnight(position string) error {
|
||||||
xPrev = x - 2
|
xPrev = x - 2
|
||||||
yPrev = y - 1
|
yPrev = y - 1
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
piece = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil && piece.Name == Knight && piece.Color == b.turn {
|
if checkMove(piece, xPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
b.tiles[xPrev][yPrev] = nil
|
||||||
b.tiles[x][y] = piece
|
b.tiles[x][y] = piece
|
||||||
return nil
|
return nil
|
||||||
|
@ -720,7 +740,7 @@ func (b *Board) moveKnight(position string) error {
|
||||||
xPrev = x - 1
|
xPrev = x - 1
|
||||||
yPrev = y - 2
|
yPrev = y - 2
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
piece = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil && piece.Name == Knight && piece.Color == b.turn {
|
if checkMove(piece, xPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
b.tiles[xPrev][yPrev] = nil
|
||||||
b.tiles[x][y] = piece
|
b.tiles[x][y] = piece
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -173,6 +173,38 @@ func TestBoardMoveKnightCapture(t *testing.T) {
|
||||||
assertNoPiece(t, b, "g8")
|
assertNoPiece(t, b, "g8")
|
||||||
assertNoPiece(t, b, "e2")
|
assertNoPiece(t, b, "e2")
|
||||||
assertNoPiece(t, b, "d2")
|
assertNoPiece(t, b, "d2")
|
||||||
|
|
||||||
|
// test ambiguous capture
|
||||||
|
|
||||||
|
b = chess.NewBoard()
|
||||||
|
|
||||||
|
b.Parse("e4 e5 Nf3 d6 Nc3 d5 Nb5 d4 Nbxd4")
|
||||||
|
|
||||||
|
assertPiece(t, b, "e4", chess.Pawn, chess.Light)
|
||||||
|
assertPiece(t, b, "e5", chess.Pawn, chess.Dark)
|
||||||
|
assertPiece(t, b, "d4", chess.Knight, chess.Light)
|
||||||
|
assertPiece(t, b, "f3", chess.Knight, chess.Light)
|
||||||
|
assertNoPiece(t, b, "g1")
|
||||||
|
assertNoPiece(t, b, "b1")
|
||||||
|
assertNoPiece(t, b, "c3")
|
||||||
|
assertNoPiece(t, b, "d6")
|
||||||
|
assertNoPiece(t, b, "d5")
|
||||||
|
assertNoPiece(t, b, "b5")
|
||||||
|
|
||||||
|
b = chess.NewBoard()
|
||||||
|
|
||||||
|
b.Parse("e4 e5 Nf3 d6 Nc3 d5 Nb5 d4 Nfxd4")
|
||||||
|
|
||||||
|
assertPiece(t, b, "e4", chess.Pawn, chess.Light)
|
||||||
|
assertPiece(t, b, "e5", chess.Pawn, chess.Dark)
|
||||||
|
assertPiece(t, b, "d4", chess.Knight, chess.Light)
|
||||||
|
assertPiece(t, b, "b5", chess.Knight, chess.Light)
|
||||||
|
assertNoPiece(t, b, "g1")
|
||||||
|
assertNoPiece(t, b, "b1")
|
||||||
|
assertNoPiece(t, b, "c3")
|
||||||
|
assertNoPiece(t, b, "d6")
|
||||||
|
assertNoPiece(t, b, "d5")
|
||||||
|
assertNoPiece(t, b, "f3")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoardMoveBishop(t *testing.T) {
|
func TestBoardMoveBishop(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue