Minor fixes to flags and other things

This commit is contained in:
Mattia Giambirtone 2023-11-13 11:03:54 +01:00
parent 9047e3a53d
commit a4954a971b
1 changed files with 28 additions and 27 deletions

View File

@ -70,7 +70,7 @@ type
## A chess move
startSquare*: Location
targetSquare*: Location
flag*: uint16
flags*: uint16
Position* = ref object
@ -566,30 +566,30 @@ func isPromotion*(move: Move): bool {.inline.} =
## Returns whether the given move is a
## pawn promotion
for promotion in [PromoteToBishop, PromoteToKnight, PromoteToRook, PromoteToQueen]:
if (move.flag and promotion.uint16) != 0:
if (move.flags and promotion.uint16) != 0:
return true
func getPromotionType*(move: Move): MoveFlag {.inline.} =
## Returns the promotion type of the given move.
## The return value of this function is only valid
## The return value of this function is only valid
## if isPromotion() returns true
for promotion in [PromoteToBishop, PromoteToKnight, PromoteToRook, PromoteToQueen]:
if (move.flag and promotion.uint16) != 0:
if (move.flags and promotion.uint16) != 0:
return promotion
func isCapture*(move: Move): bool {.inline.} =
## Returns whether the given move is a
## cature
result = (move.flag and Capture.uint16) != 0
result = (move.flags and Capture.uint16) != 0
func isCastling*(move: Move): bool {.inline.} =
## Returns whether the given move is a
## castle
for flag in [CastleLong, CastleShort]:
if (move.flag and flag.uint16) != 0:
if (move.flags and flag.uint16) != 0:
return true
@ -598,20 +598,20 @@ func getCastlingType*(move: Move): MoveFlag {.inline.} =
## The return value of this function is only valid
## if isCastling() returns true
for flag in [CastleLong, CastleShort]:
if (move.flag and flag.uint16) != 0:
if (move.flags and flag.uint16) != 0:
return flag
func isEnPassant*(move: Move): bool {.inline.} =
## Returns whether the given move is an
## en passant capture
result = (move.flag and EnPassant.uint16) != 0
result = (move.flags and EnPassant.uint16) != 0
func isDoublePush*(move: Move): bool {.inline.} =
## Returns whether the given move is a
## double pawn push
result = (move.flag and DoublePush.uint16) != 0
result = (move.flags and DoublePush.uint16) != 0
proc inCheck*(self: ChessBoard, color: PieceColor = None): bool =
@ -782,7 +782,7 @@ proc generatePawnMoves(self: ChessBoard, location: Location): seq[Move] =
flags: seq[MoveFlag] = @[]
doAssert piece.kind == Pawn, &"generatePawnMoves called on a {piece.kind}"
# Pawns can move forward one square
let forward = (piece.color.topSide() + location)
let forward = piece.color.topSide() + location
# Only if the square is empty though
if forward.isValid() and self.grid[forward.row, forward.col].color == None:
locations.add(forward)
@ -799,6 +799,7 @@ proc generatePawnMoves(self: ChessBoard, location: Location): seq[Move] =
# square, but only to capture or for en passant
for diagonal in [location + piece.color.topRightDiagonal(), location + piece.color.topLeftDiagonal()]:
if diagonal.isValid():
let otherPiece = self.grid[diagonal.row, diagonal.col]
if diagonal == self.position.enPassantSquare and self.grid[enPassantPawn.row, enPassantPawn.col].color == self.getActiveColor().opposite():
# Ensure en passant doesn't create a check
let king = self.getKing(piece.color)
@ -820,7 +821,7 @@ proc generatePawnMoves(self: ChessBoard, location: Location): seq[Move] =
if ok:
locations.add(diagonal)
flags.add(EnPassant)
elif self.grid[diagonal.row, diagonal.col].color == piece.color.opposite() and self.grid[diagonal.row, diagonal.col].kind != King:
elif otherPiece.color == piece.color.opposite() and otherPiece.kind != King:
locations.add(diagonal)
flags.add(Capture)
var
@ -849,9 +850,9 @@ proc generatePawnMoves(self: ChessBoard, location: Location): seq[Move] =
if target.row == piece.color.getLastRow():
# Pawn reached the other side of the board: generate all potential piece promotions
for promotionType in [PromoteToKnight, PromoteToBishop, PromoteToRook, PromoteToQueen]:
result.add(Move(startSquare: location, targetSquare: target, flag: promotionType.uint16 and flag.uint16))
result.add(Move(startSquare: location, targetSquare: target, flags: promotionType.uint16 or flag.uint16))
continue
result.add(Move(startSquare: location, targetSquare: target, flag: flag.uint16))
result.add(Move(startSquare: location, targetSquare: target, flags: flag.uint16))
proc generateSlidingMoves(self: ChessBoard, location: Location): seq[Move] =
@ -891,13 +892,13 @@ proc generateSlidingMoves(self: ChessBoard, location: Location): seq[Move] =
if otherPiece.color == piece.color:
break
if checked and square notin resolutions:
continue
break
if otherPiece.color == piece.color.opposite:
# Target square contains an enemy piece: capture
# it and stop going any further
if otherPiece.kind != King:
# Can't capture the king
result.add(Move(startSquare: location, targetSquare: square, flag: Capture.uint16))
result.add(Move(startSquare: location, targetSquare: square, flags: Capture.uint16))
break
# Target square is empty
result.add(Move(startSquare: location, targetSquare: square))
@ -945,7 +946,7 @@ proc generateKingMoves(self: ChessBoard, location: Location): seq[Move] =
continue
# Target square is empty or contains an enemy piece:
# All good for us!
result.add(Move(startSquare: location, targetSquare: square, flag: flag.uint16))
result.add(Move(startSquare: location, targetSquare: square, flags: flag.uint16))
proc generateKnightMoves(self: ChessBoard, location: Location): seq[Move] =
@ -983,7 +984,7 @@ proc generateKnightMoves(self: ChessBoard, location: Location): seq[Move] =
if otherPiece.color != None:
# Target square contains an enemy piece: capture
# it
result.add(Move(startSquare: location, targetSquare: square, flag: Capture.uint16))
result.add(Move(startSquare: location, targetSquare: square, flags: Capture.uint16))
else:
# Target square is empty
result.add(Move(startSquare: location, targetSquare: square))
@ -1506,7 +1507,7 @@ proc doMove(self: ChessBoard, move: Move) =
location = piece.color.queenSideRook()
target = longCastleRook()
let rook = self.grid[location.row, location.col]
let move = Move(startSquare: location, targetSquare: location + target, flag: move.flag)
let move = Move(startSquare: location, targetSquare: location + target, flags: move.flags)
self.movePiece(move, attack=false)
if move.isCapture():
@ -1809,7 +1810,7 @@ proc perft*(self: ChessBoard, ply: int, verbose: bool = false, divide: bool = fa
echo &"Move: {move.startSquare.locationToAlgebraic()}{move.targetSquare.locationToAlgebraic()}, from ({move.startSquare.row}, {move.startSquare.col}) to ({move.targetSquare.row}, {move.targetSquare.col})"
echo &"Turn: {self.getActiveColor()}"
echo &"Piece: {self.grid[move.startSquare.row, move.startSquare.col].kind}"
echo &"Flag: {move.flag}"
echo &"Flag: {move.flags}"
echo &"In check: {(if self.inCheck(): \"yes\" else: \"no\")}"
echo &"Can castle:\n - King side: {(if canCastle.king: \"yes\" else: \"no\")}\n - Queen side: {(if canCastle.queen: \"yes\" else: \"no\")}"
echo &"Position before move: {self.toFEN()}"
@ -1958,7 +1959,7 @@ proc handleMoveCommand(board: ChessBoard, command: seq[string]) =
var
startSquare: Location
targetSquare: Location
flag: uint16
flags: uint16
try:
startSquare = moveString[0..1].algebraicToLocation()
@ -1972,27 +1973,27 @@ proc handleMoveCommand(board: ChessBoard, command: seq[string]) =
return
if board.grid[targetSquare.row, targetSquare.col].kind != Empty:
flag = flag or Capture.uint16
flags = flags or Capture.uint16
if board.grid[startSquare.row, startSquare.col].kind == Pawn and abs(startSquare.row - targetSquare.row) == 2:
flag = flag or DoublePush.uint16
flags = flags or DoublePush.uint16
if len(moveString) == 5:
# Promotion
case moveString[4]:
of 'b':
flag = flag and PromoteToBishop.uint16
flags = flags or PromoteToBishop.uint16
of 'n':
flag = flag and PromoteToKnight.uint16
flags = flags or PromoteToKnight.uint16
of 'q':
flag = flag and PromoteToQueen.uint16
flags = flags or PromoteToQueen.uint16
of 'r':
flag = flag and PromoteToRook.uint16
flags = flags or PromoteToRook.uint16
else:
echo &"Error: move: invalid promotion type"
return
let move = Move(startSquare: startSquare, targetSquare: targetSquare, flag: flag)
let move = Move(startSquare: startSquare, targetSquare: targetSquare, flags: flags)
if board.makeMove(move) == emptyMove():
echo "Error: move: illegal move"