Implemented knight moves
This commit is contained in:
parent
e782935fd7
commit
ca498ebc42
|
@ -107,6 +107,9 @@ func `+`*(a, b: Location): Location = (a.row + b.row, a.col + b.col)
|
|||
func isValid*(a: Location): bool = a.row in 0..7 and a.col in 0..7
|
||||
proc generateMoves(self: ChessBoard, location: Location): seq[Move]
|
||||
|
||||
# Due to our board layout, directions of movement are reversed for white/black so
|
||||
# we need these helpers to avoid going mad with integer tuples and minus signs
|
||||
# everywhere
|
||||
func topLeftDiagonal(piece: Piece): Location {.inline.} = (if piece.color == White: (-1, -1) else: (1, 1))
|
||||
func topRightDiagonal(piece: Piece): Location {.inline.} = (if piece.color == White: (-1, 1) else: (1, -1))
|
||||
func bottomLeftDiagonal(piece: Piece): Location {.inline.} = (if piece.color == White: (1, -1) else: (-1, 1))
|
||||
|
@ -115,8 +118,60 @@ func leftSide(piece: Piece): Location {.inline.} = (if piece.color == White: (0,
|
|||
func rightSide(piece: Piece): Location {.inline.} = (if piece.color == White: (0, 1) else: (0, -1))
|
||||
func topSide(piece: Piece): Location {.inline.} = (if piece.color == White: (-1, 0) else: (1, 0))
|
||||
func bottomSide(piece: Piece): Location {.inline.} = (if piece.color == White: (1, 0) else: (-1, 0))
|
||||
func forward(piece: Piece): Location {.inline.} = (if piece.color == Black: (1, 0) else: (-1, 0))
|
||||
func doublePush(piece: Piece): Location {.inline.} = (if piece.color == Black: (2, 0) else: (-2, 0))
|
||||
func forward(piece: Piece): Location {.inline.} = (if piece.color == White: (-1, 0) else: (1, 0))
|
||||
func doublePush(piece: Piece): Location {.inline.} = (if piece.color == White: (-2, 0) else: (2, 0))
|
||||
|
||||
|
||||
func bottomLeftKnightMove(piece: Piece, long: bool = true): Location {.inline.} =
|
||||
if piece.color == White:
|
||||
if long:
|
||||
return (-2, 1)
|
||||
else:
|
||||
return (1, -2)
|
||||
elif piece.color == Black:
|
||||
if long:
|
||||
return (2, -1)
|
||||
else:
|
||||
return (1, -2)
|
||||
|
||||
|
||||
func bottomRightKnightMove(piece: Piece, long: bool = true): Location {.inline.} =
|
||||
if piece.color == White:
|
||||
if long:
|
||||
return (2, -1)
|
||||
else:
|
||||
return (1, 2)
|
||||
elif piece.color == Black:
|
||||
if long:
|
||||
return (2, 1)
|
||||
else:
|
||||
return (1, 2)
|
||||
|
||||
|
||||
func topLeftKnightMove(piece: Piece, long: bool = true): Location {.inline.} =
|
||||
if piece.color == White:
|
||||
if long:
|
||||
return (-2, -1)
|
||||
else:
|
||||
return (-1, -2)
|
||||
elif piece.color == Black:
|
||||
if long:
|
||||
return (2, 1)
|
||||
else:
|
||||
return (1, 2)
|
||||
|
||||
|
||||
func topRightKnightMove(piece: Piece, long: bool = true): Location {.inline.} =
|
||||
if piece.color == White:
|
||||
if long:
|
||||
return (-2, 1)
|
||||
else:
|
||||
return (-1, 2)
|
||||
elif piece.color == Black:
|
||||
if long:
|
||||
return (2, -1)
|
||||
else:
|
||||
return (-1, 2)
|
||||
|
||||
|
||||
proc getActiveColor*(self: ChessBoard): PieceColor =
|
||||
|
@ -556,7 +611,39 @@ proc generateKingMoves(self: ChessBoard, location: Location): seq[Move] =
|
|||
continue
|
||||
# Target square is empty
|
||||
result.add(Move(startSquare: location, targetSquare: square, piece: piece))
|
||||
|
||||
|
||||
|
||||
proc generateKnightMoves(self: ChessBoard, location: Location): seq[Move] =
|
||||
## Generates moves for the knight in the given location
|
||||
var
|
||||
piece = self.grid[location.row, location.col]
|
||||
doAssert piece.kind == Knight, &"generateKnightMoves called on a {piece.kind}"
|
||||
var directions: seq[Location] = @[piece.bottomLeftKnightMove(),
|
||||
piece.bottomRightKnightMove(),
|
||||
piece.topLeftKnightMove(),
|
||||
piece.topRightKnightMove(),
|
||||
piece.bottomLeftKnightMove(long=false),
|
||||
piece.bottomRightKnightMove(long=false),
|
||||
piece.topLeftKnightMove(long=false),
|
||||
piece.topRightKnightMove(long=false)]
|
||||
for direction in directions:
|
||||
# Jump to this square
|
||||
let square: Location = location + direction
|
||||
# End of board reached
|
||||
if not square.isValid():
|
||||
continue
|
||||
let otherPiece = self.grid[square.row, square.col]
|
||||
# A friendly piece is in the way
|
||||
if otherPiece.color == piece.color:
|
||||
continue
|
||||
if otherPiece.color == piece.color.opposite:
|
||||
# Target square contains an enemy piece: capture
|
||||
# it
|
||||
result.add(Move(startSquare: location, targetSquare: square, piece: piece))
|
||||
continue
|
||||
# Target square is empty
|
||||
result.add(Move(startSquare: location, targetSquare: square, piece: piece))
|
||||
|
||||
|
||||
proc generateMoves(self: ChessBoard, location: Location): seq[Move] =
|
||||
## Returns the list of possible legal chess moves for the
|
||||
|
@ -569,6 +656,8 @@ proc generateMoves(self: ChessBoard, location: Location): seq[Move] =
|
|||
return self.generatePawnMoves(location)
|
||||
of King:
|
||||
return self.generateKingMoves(location)
|
||||
of Knight:
|
||||
return self.generateKnightMoves(location)
|
||||
else:
|
||||
return @[]
|
||||
|
||||
|
|
|
@ -35,3 +35,5 @@ when isMainModule:
|
|||
move = board.makeMove(startSquare, targetSquare)
|
||||
except ValueError:
|
||||
echo &"Error: {getCurrentExceptionMsg()}"
|
||||
if move == emptyMove():
|
||||
echo &"Error: move is illegal"
|
||||
|
|
Loading…
Reference in New Issue