Fix ambiguous rook moves
This commit is contained in:
parent
e6f9c529f8
commit
bab667d0ed
|
@ -553,12 +553,13 @@ func (b *Board) movePawn(position string, fromX int, fromY int) error {
|
||||||
|
|
||||||
func (b *Board) moveRook(position string, queen bool, fromX int, fromY int) error {
|
func (b *Board) moveRook(position string, queen bool, fromX int, fromY int) error {
|
||||||
var (
|
var (
|
||||||
x int
|
x int
|
||||||
y int
|
y int
|
||||||
xPrev int
|
xPrev int
|
||||||
yPrev int
|
yPrev int
|
||||||
piece *Piece
|
p *Piece
|
||||||
err error
|
validPrev []*Square
|
||||||
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
if x, y, err = getXY(position); err != nil {
|
if x, y, err = getXY(position); err != nil {
|
||||||
|
@ -567,21 +568,20 @@ func (b *Board) moveRook(position string, queen bool, fromX int, fromY int) erro
|
||||||
|
|
||||||
checkRookMove := b.validateMove(Rook, fromX, fromY)
|
checkRookMove := b.validateMove(Rook, fromX, fromY)
|
||||||
checkQueenMove := b.validateMove(Queen, fromX, fromY)
|
checkQueenMove := b.validateMove(Queen, fromX, fromY)
|
||||||
|
checkMove := func(p *Piece, xPrev int, yPrev int) bool {
|
||||||
|
return (!queen && checkRookMove(p, xPrev, yPrev)) || (queen && checkQueenMove(p, xPrev, yPrev))
|
||||||
|
}
|
||||||
|
|
||||||
xPrev = x
|
xPrev = x
|
||||||
yPrev = y
|
yPrev = y
|
||||||
for xPrev >= 0 && xPrev < 8 && yPrev >= 0 && yPrev < 8 {
|
for xPrev >= 0 && xPrev < 8 && yPrev >= 0 && yPrev < 8 {
|
||||||
xPrev++
|
xPrev++
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
p = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil {
|
if p != nil {
|
||||||
if (!queen && checkRookMove(piece, xPrev, yPrev)) || (queen && checkQueenMove(piece, xPrev, yPrev)) {
|
if checkMove(p, xPrev, yPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
|
||||||
b.tiles[x][y] = piece
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
// direction blocked by other piece
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,12 +589,10 @@ func (b *Board) moveRook(position string, queen bool, fromX int, fromY int) erro
|
||||||
yPrev = y
|
yPrev = y
|
||||||
for xPrev >= 0 && xPrev < 8 && yPrev >= 0 && yPrev < 8 {
|
for xPrev >= 0 && xPrev < 8 && yPrev >= 0 && yPrev < 8 {
|
||||||
yPrev--
|
yPrev--
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
p = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil {
|
if p != nil {
|
||||||
if (!queen && checkRookMove(piece, xPrev, yPrev)) || (queen && checkQueenMove(piece, xPrev, yPrev)) {
|
if checkMove(p, xPrev, yPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
|
||||||
b.tiles[x][y] = piece
|
|
||||||
return nil
|
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -605,12 +603,10 @@ func (b *Board) moveRook(position string, queen bool, fromX int, fromY int) erro
|
||||||
yPrev = y
|
yPrev = y
|
||||||
for xPrev >= 0 && xPrev < 8 && yPrev >= 0 && yPrev < 8 {
|
for xPrev >= 0 && xPrev < 8 && yPrev >= 0 && yPrev < 8 {
|
||||||
xPrev--
|
xPrev--
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
p = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil {
|
if p != nil {
|
||||||
if (!queen && checkRookMove(piece, xPrev, yPrev)) || (queen && checkQueenMove(piece, xPrev, yPrev)) {
|
if checkMove(p, xPrev, yPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
|
||||||
b.tiles[x][y] = piece
|
|
||||||
return nil
|
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -621,18 +617,29 @@ func (b *Board) moveRook(position string, queen bool, fromX int, fromY int) erro
|
||||||
yPrev = y
|
yPrev = y
|
||||||
for xPrev >= 0 && xPrev < 8 && yPrev >= 0 && yPrev < 8 {
|
for xPrev >= 0 && xPrev < 8 && yPrev >= 0 && yPrev < 8 {
|
||||||
yPrev++
|
yPrev++
|
||||||
piece = b.getPiece(xPrev, yPrev)
|
p = b.getPiece(xPrev, yPrev)
|
||||||
if piece != nil {
|
if p != nil {
|
||||||
if (!queen && checkRookMove(piece, xPrev, yPrev)) || (queen && checkQueenMove(piece, xPrev, yPrev)) {
|
if checkMove(p, xPrev, yPrev) {
|
||||||
b.tiles[xPrev][yPrev] = nil
|
validPrev = append(validPrev, &Square{X: xPrev, Y: yPrev})
|
||||||
b.tiles[x][y] = piece
|
|
||||||
return nil
|
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(validPrev) > 1 {
|
||||||
|
return fmt.Errorf("move ambiguous: %d rooks 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
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return fmt.Errorf("no rook found that can move to %s", position)
|
return fmt.Errorf("no rook found that can move to %s", position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -332,6 +332,14 @@ func TestBoardMoveRookInvalid(t *testing.T) {
|
||||||
|
|
||||||
// path blocked by pawn at d3
|
// path blocked by pawn at d3
|
||||||
assertMoveError(t, b, "Rh3", "no rook found that can move to h3")
|
assertMoveError(t, b, "Rh3", "no rook found that can move to h3")
|
||||||
|
|
||||||
|
// ambiguous moves
|
||||||
|
b = chess.NewBoard()
|
||||||
|
|
||||||
|
assertParse(t, b, "a4 e6 h4 e5 Ra3 e4")
|
||||||
|
|
||||||
|
assertMoveError(t, b, "Rh3", "move ambiguous: 2 rooks can move to h3")
|
||||||
|
assertParse(t, b, "Rhh3")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoardMoveQueen(t *testing.T) {
|
func TestBoardMoveQueen(t *testing.T) {
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package chess
|
||||||
|
|
||||||
|
type Square struct {
|
||||||
|
X int
|
||||||
|
Y int
|
||||||
|
}
|
Loading…
Reference in New Issue