From 57353c09942fda669374e12b262211a0a8ae2639 Mon Sep 17 00:00:00 2001 From: nocturn9x Date: Tue, 9 Apr 2024 17:46:30 +0200 Subject: [PATCH] Several bug fixes and minor improvements/additions --- src/Chess/board.nim | 57 ++++++++++++++++++---------------- src/Chess/compare_positions.py | 4 +-- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/Chess/board.nim b/src/Chess/board.nim index 2996b88..129b47c 100644 --- a/src/Chess/board.nim +++ b/src/Chess/board.nim @@ -723,46 +723,39 @@ proc canCastle*(self: ChessBoard, color: PieceColor = None): tuple[queen, king: var location = loc otherPiece: Piece - moveKing: bool = true while true: location = location + kingSide + 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 - if location == loc + shortCastleKing(): - moveKing = false + otherPiece = self.grid[location.row, location.col] if otherPiece.color != None: result.king = false break - if moveKing and self.isAttacked(location, color.opposite()): + if self.isAttacked(location, color.opposite()): result.king = false break + if result.queen: # Long castle var location = loc otherPiece: Piece - moveKing: bool = true while true: location = location + queenSide + if location == color.queenSideRook(): break - if location == loc + longCastleKing(): - moveKing = false + otherPiece = self.grid[location.row, location.col] if otherPiece.color != None: result.queen = false break - if moveKing and self.isAttacked(location, color.opposite()): + if self.isAttacked(location, color.opposite()): result.queen = false 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: targets.add(double) let enPassantPawn = self.getEnPassantTarget() + piece.color.opposite().topSide() - # They can also move on either diagonal one - # square, but only to capture or for en passant + # They can also move one square on either of their + # forward diagonals, but only for captures and 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(): + if diagonal == self.position.enPassantSquare and self.grid[enPassantPawn.row, enPassantPawn.col].color == piece.color.opposite(): # Ensure en passant doesn't create a check let king = self.getKing(piece.color) var ok = true @@ -971,7 +964,7 @@ proc generateKingMoves(self: ChessBoard, location: Location): seq[Move] = else: flag = Default let otherPiece = self.grid[square.row, square.col] - if otherPiece.color == self.getActiveColor.opposite(): + if otherPiece.color == piece.color.opposite(): flag = Capture # A friendly piece is in the way, move onto the next direction if otherPiece.color == piece.color: @@ -1326,9 +1319,9 @@ proc removePiece(self: ChessBoard, location: Location, attack: bool = true, empt of Pawn: self.position.pieces.white.pawns.delete(self.position.pieces.white.pawns.find(location)) 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: - 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: self.position.pieces.white.rooks.delete(self.position.pieces.white.rooks.find(location)) of Queen: @@ -1484,7 +1477,7 @@ proc doMove(self: ChessBoard, move: Move) = if move.isCapture(): let captured = self.grid[move.targetSquare.row, move.targetSquare.col] if captured.kind == Rook: - case piece.color: + case captured.color: of White: if move.targetSquare == captured.color.queenSideRook(): # Queen side @@ -1694,7 +1687,7 @@ proc `$`*(self: ChessBoard): string = proc toPretty*(piece: Piece): string = case piece.color: - of Black: + of White: case piece.kind: of King: return "\U2654" @@ -1710,7 +1703,7 @@ proc toPretty*(piece: Piece): string = return "\U2659" else: discard - of White: + of Black: case piece.kind: of King: return "\U265A" @@ -1723,7 +1716,7 @@ proc toPretty*(piece: Piece): string = of Knight: return "\U265E" of Pawn: - return "\U265F" + return "\240\159\168\133" else: discard else: @@ -1731,13 +1724,15 @@ proc toPretty*(piece: Piece): string = proc pretty*(self: ChessBoard): string = - ## Returns a colorized version of the + ## Returns a colored version of the ## board for easier visualization for i in 0..7: if i > 0: result &= "\n" 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" else: result &= "\x1b[39;40;1m" @@ -2116,6 +2111,7 @@ const HELP_TEXT = """Nimfish help menu: - ep: Print the current en passant target - pretty: Shorthand for "position pretty" - print: Shorthand for "position print" + - get : Get the piece on the given square """ @@ -2158,6 +2154,15 @@ proc main: int = echo &"En passant target: {target.locationToAlgebraic()}" else: 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": 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\")}" diff --git a/src/Chess/compare_positions.py b/src/Chess/compare_positions.py index 3e6c3f8..a8d41f4 100644 --- a/src/Chess/compare_positions.py +++ b/src/Chess/compare_positions.py @@ -86,7 +86,7 @@ def main(args: Namespace) -> int: continue if nodes[0] != nodes[1]: mistakes.add(move) - + mistakes = sorted(list(mistakes)) total_nodes = {"stockfish": sum(positions["stockfish"][move] for move in positions["stockfish"]), "nimfish": sum(positions["nimfish"][move] for move in positions["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'}") 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: total_difference = abs(total_difference) print(f"Nimfish searched {total_difference} more node{'' if total_difference == 1 else 's'} than Stockfish")