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