Several bug fixes and minor improvements/additions
This commit is contained in:
parent
77129855df
commit
57353c0994
|
@ -723,46 +723,39 @@ proc canCastle*(self: ChessBoard, color: PieceColor = None): tuple[queen, king:
|
||||||
var
|
var
|
||||||
location = loc
|
location = loc
|
||||||
otherPiece: Piece
|
otherPiece: Piece
|
||||||
moveKing: bool = true
|
|
||||||
while true:
|
while true:
|
||||||
location = location + kingSide
|
location = location + kingSide
|
||||||
|
|
||||||
if location == color.kingSideRook():
|
if location == color.kingSideRook():
|
||||||
# No need to do any extra checks: if the piece
|
|
||||||
# on this square were not a rook of the same color
|
|
||||||
# as the castling king, then we wouldn't have gotten
|
|
||||||
# here in the first place (it would've had to be either
|
|
||||||
# moved or captured, and both of those actions are detected
|
|
||||||
# and accounted for way before this point)
|
|
||||||
break
|
break
|
||||||
if location == loc + shortCastleKing():
|
|
||||||
moveKing = false
|
|
||||||
otherPiece = self.grid[location.row, location.col]
|
otherPiece = self.grid[location.row, location.col]
|
||||||
|
|
||||||
if otherPiece.color != None:
|
if otherPiece.color != None:
|
||||||
result.king = false
|
result.king = false
|
||||||
break
|
break
|
||||||
if moveKing and self.isAttacked(location, color.opposite()):
|
if self.isAttacked(location, color.opposite()):
|
||||||
result.king = false
|
result.king = false
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
if result.queen:
|
if result.queen:
|
||||||
# Long castle
|
# Long castle
|
||||||
var
|
var
|
||||||
location = loc
|
location = loc
|
||||||
otherPiece: Piece
|
otherPiece: Piece
|
||||||
moveKing: bool = true
|
|
||||||
while true:
|
while true:
|
||||||
location = location + queenSide
|
location = location + queenSide
|
||||||
|
|
||||||
if location == color.queenSideRook():
|
if location == color.queenSideRook():
|
||||||
break
|
break
|
||||||
if location == loc + longCastleKing():
|
|
||||||
moveKing = false
|
|
||||||
otherPiece = self.grid[location.row, location.col]
|
otherPiece = self.grid[location.row, location.col]
|
||||||
|
|
||||||
if otherPiece.color != None:
|
if otherPiece.color != None:
|
||||||
result.queen = false
|
result.queen = false
|
||||||
break
|
break
|
||||||
if moveKing and self.isAttacked(location, color.opposite()):
|
if self.isAttacked(location, color.opposite()):
|
||||||
result.queen = false
|
result.queen = false
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -824,12 +817,12 @@ proc generatePawnMoves(self: ChessBoard, location: Location): seq[Move] =
|
||||||
if double.isValid() and self.grid[forward.row, forward.col].color == None and self.grid[double.row, double.col].color == None:
|
if double.isValid() and self.grid[forward.row, forward.col].color == None and self.grid[double.row, double.col].color == None:
|
||||||
targets.add(double)
|
targets.add(double)
|
||||||
let enPassantPawn = self.getEnPassantTarget() + piece.color.opposite().topSide()
|
let enPassantPawn = self.getEnPassantTarget() + piece.color.opposite().topSide()
|
||||||
# They can also move on either diagonal one
|
# They can also move one square on either of their
|
||||||
# square, but only to capture or for en passant
|
# forward diagonals, but only for captures and 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]
|
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 == piece.color.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)
|
||||||
var ok = true
|
var ok = true
|
||||||
|
@ -971,7 +964,7 @@ proc generateKingMoves(self: ChessBoard, location: Location): seq[Move] =
|
||||||
else:
|
else:
|
||||||
flag = Default
|
flag = Default
|
||||||
let otherPiece = self.grid[square.row, square.col]
|
let otherPiece = self.grid[square.row, square.col]
|
||||||
if otherPiece.color == self.getActiveColor.opposite():
|
if otherPiece.color == piece.color.opposite():
|
||||||
flag = Capture
|
flag = Capture
|
||||||
# A friendly piece is in the way, move onto the next direction
|
# A friendly piece is in the way, move onto the next direction
|
||||||
if otherPiece.color == piece.color:
|
if otherPiece.color == piece.color:
|
||||||
|
@ -1326,9 +1319,9 @@ proc removePiece(self: ChessBoard, location: Location, attack: bool = true, empt
|
||||||
of Pawn:
|
of Pawn:
|
||||||
self.position.pieces.white.pawns.delete(self.position.pieces.white.pawns.find(location))
|
self.position.pieces.white.pawns.delete(self.position.pieces.white.pawns.find(location))
|
||||||
of Bishop:
|
of Bishop:
|
||||||
self.position.pieces.white.pawns.delete(self.position.pieces.white.bishops.find(location))
|
self.position.pieces.white.bishops.delete(self.position.pieces.white.bishops.find(location))
|
||||||
of Knight:
|
of Knight:
|
||||||
self.position.pieces.white.pawns.delete(self.position.pieces.white.knights.find(location))
|
self.position.pieces.white.knights.delete(self.position.pieces.white.knights.find(location))
|
||||||
of Rook:
|
of Rook:
|
||||||
self.position.pieces.white.rooks.delete(self.position.pieces.white.rooks.find(location))
|
self.position.pieces.white.rooks.delete(self.position.pieces.white.rooks.find(location))
|
||||||
of Queen:
|
of Queen:
|
||||||
|
@ -1484,7 +1477,7 @@ proc doMove(self: ChessBoard, move: Move) =
|
||||||
if move.isCapture():
|
if move.isCapture():
|
||||||
let captured = self.grid[move.targetSquare.row, move.targetSquare.col]
|
let captured = self.grid[move.targetSquare.row, move.targetSquare.col]
|
||||||
if captured.kind == Rook:
|
if captured.kind == Rook:
|
||||||
case piece.color:
|
case captured.color:
|
||||||
of White:
|
of White:
|
||||||
if move.targetSquare == captured.color.queenSideRook():
|
if move.targetSquare == captured.color.queenSideRook():
|
||||||
# Queen side
|
# Queen side
|
||||||
|
@ -1694,7 +1687,7 @@ proc `$`*(self: ChessBoard): string =
|
||||||
|
|
||||||
proc toPretty*(piece: Piece): string =
|
proc toPretty*(piece: Piece): string =
|
||||||
case piece.color:
|
case piece.color:
|
||||||
of Black:
|
of White:
|
||||||
case piece.kind:
|
case piece.kind:
|
||||||
of King:
|
of King:
|
||||||
return "\U2654"
|
return "\U2654"
|
||||||
|
@ -1710,7 +1703,7 @@ proc toPretty*(piece: Piece): string =
|
||||||
return "\U2659"
|
return "\U2659"
|
||||||
else:
|
else:
|
||||||
discard
|
discard
|
||||||
of White:
|
of Black:
|
||||||
case piece.kind:
|
case piece.kind:
|
||||||
of King:
|
of King:
|
||||||
return "\U265A"
|
return "\U265A"
|
||||||
|
@ -1723,7 +1716,7 @@ proc toPretty*(piece: Piece): string =
|
||||||
of Knight:
|
of Knight:
|
||||||
return "\U265E"
|
return "\U265E"
|
||||||
of Pawn:
|
of Pawn:
|
||||||
return "\U265F"
|
return "\240\159\168\133"
|
||||||
else:
|
else:
|
||||||
discard
|
discard
|
||||||
else:
|
else:
|
||||||
|
@ -1731,13 +1724,15 @@ proc toPretty*(piece: Piece): string =
|
||||||
|
|
||||||
|
|
||||||
proc pretty*(self: ChessBoard): string =
|
proc pretty*(self: ChessBoard): string =
|
||||||
## Returns a colorized version of the
|
## Returns a colored version of the
|
||||||
## board for easier visualization
|
## board for easier visualization
|
||||||
for i in 0..7:
|
for i in 0..7:
|
||||||
if i > 0:
|
if i > 0:
|
||||||
result &= "\n"
|
result &= "\n"
|
||||||
for j in 0..7:
|
for j in 0..7:
|
||||||
if ((i + j) mod 2) == 0:
|
# Equivalent to (i + j) mod 2
|
||||||
|
# (I'm just evil)
|
||||||
|
if ((i + j) and 1) == 0:
|
||||||
result &= "\x1b[39;44;1m"
|
result &= "\x1b[39;44;1m"
|
||||||
else:
|
else:
|
||||||
result &= "\x1b[39;40;1m"
|
result &= "\x1b[39;40;1m"
|
||||||
|
@ -2116,6 +2111,7 @@ const HELP_TEXT = """Nimfish help menu:
|
||||||
- ep: Print the current en passant target
|
- ep: Print the current en passant target
|
||||||
- pretty: Shorthand for "position pretty"
|
- pretty: Shorthand for "position pretty"
|
||||||
- print: Shorthand for "position print"
|
- print: Shorthand for "position print"
|
||||||
|
- get <square>: Get the piece on the given square
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -2158,6 +2154,15 @@ proc main: int =
|
||||||
echo &"En passant target: {target.locationToAlgebraic()}"
|
echo &"En passant target: {target.locationToAlgebraic()}"
|
||||||
else:
|
else:
|
||||||
echo "En passant target: None"
|
echo "En passant target: None"
|
||||||
|
of "get":
|
||||||
|
if len(cmd) != 2:
|
||||||
|
echo "get: invalid syntax"
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
echo board.getPiece(cmd[1])
|
||||||
|
except ValueError:
|
||||||
|
echo "get: invalid square"
|
||||||
|
continue
|
||||||
of "castle":
|
of "castle":
|
||||||
let canCastle = board.canCastle()
|
let canCastle = board.canCastle()
|
||||||
echo &"Castling rights for {($board.getActiveColor()).toLowerAscii()}:\n - King side: {(if canCastle.king: \"yes\" else: \"no\")}\n - Queen side: {(if canCastle.queen: \"yes\" else: \"no\")}"
|
echo &"Castling rights for {($board.getActiveColor()).toLowerAscii()}:\n - King side: {(if canCastle.king: \"yes\" else: \"no\")}\n - Queen side: {(if canCastle.queen: \"yes\" else: \"no\")}"
|
||||||
|
|
|
@ -86,7 +86,7 @@ def main(args: Namespace) -> int:
|
||||||
continue
|
continue
|
||||||
if nodes[0] != nodes[1]:
|
if nodes[0] != nodes[1]:
|
||||||
mistakes.add(move)
|
mistakes.add(move)
|
||||||
|
mistakes = sorted(list(mistakes))
|
||||||
total_nodes = {"stockfish": sum(positions["stockfish"][move] for move in positions["stockfish"]),
|
total_nodes = {"stockfish": sum(positions["stockfish"][move] for move in positions["stockfish"]),
|
||||||
"nimfish": sum(positions["nimfish"][move] for move in positions["nimfish"])}
|
"nimfish": sum(positions["nimfish"][move] for move in positions["nimfish"])}
|
||||||
total_difference = total_nodes["stockfish"] - total_nodes["nimfish"]
|
total_difference = total_nodes["stockfish"] - total_nodes["nimfish"]
|
||||||
|
@ -94,7 +94,7 @@ def main(args: Namespace) -> int:
|
||||||
print(f"Nimfish searched {total_nodes['nimfish']} node{'' if total_nodes['nimfish'] == 1 else 's'}")
|
print(f"Nimfish searched {total_nodes['nimfish']} node{'' if total_nodes['nimfish'] == 1 else 's'}")
|
||||||
|
|
||||||
if total_difference > 0:
|
if total_difference > 0:
|
||||||
print(f"Nimfish searched {total_difference} less node{'' if total_difference == 1 else 's'} than Stockfish")
|
print(f"Nimfish searched {total_difference} fewer node{'' if total_difference == 1 else 's'} than Stockfish")
|
||||||
elif total_difference < 0:
|
elif total_difference < 0:
|
||||||
total_difference = abs(total_difference)
|
total_difference = abs(total_difference)
|
||||||
print(f"Nimfish searched {total_difference} more node{'' if total_difference == 1 else 's'} than Stockfish")
|
print(f"Nimfish searched {total_difference} more node{'' if total_difference == 1 else 's'} than Stockfish")
|
||||||
|
|
Loading…
Reference in New Issue