Beispiel #1
0
 def _zugzwang(board: SearchBoard) -> bool:
     """
     Detects so called zugzwang positions, wherein not moving is actually more benificial than moving (often happens
     in the end game when trying to mate the king). Note that this method is only a heuristic and technically
     doesn't cover every case.
     :param board: Board to check
     :return: True if zugzwang, False otherwise
     """
     # TODO improve zugzwang detection (see brucemo.com)
     return board.pieces_mask(chess.KNIGHT, board.turn) == 0 and \
            board.pieces_mask(chess.BISHOP, board.turn) == 0 and \
            board.pieces_mask(chess.ROOK, board.turn) == 0 and \
            board.pieces_mask(chess.QUEEN, board.turn) == 0
Beispiel #2
0
 def _count_piece_type(board: SearchBoard,
                       piece_type: chess.PieceType) -> Tuple[int, int]:
     """
     Counts how many occurrences of the given piece type are on the board.
     :param board: Board to consider
     :param piece_type: Piece type to count
     :return: The piece count for white, black
     """
     return (count_bin_ones(board.pieces_mask(piece_type, chess.WHITE)),
             count_bin_ones(board.pieces_mask(piece_type, chess.BLACK)))
Beispiel #3
0
 def apply_heatmap_dynamic(self, board: SearchBoard,
                           color: chess.Color) -> int:
     """
     Applies a heatmap to a given board. This implementation dynamically locates pieces and thus it is slower than
     `apply_heatmap`, which should be used if possible.
     :param board: The board to apply the heatmap to
     :param color: The color to apply the heatmap to
     :return: The sum of the heatmap times 1 if a piece of the given color and `self.piece_type`
     """
     piece_mask = board.pieces_mask(self.piece_type, color)
     heatmap = self._white_heatmap if color == chess.WHITE else self._black_heatmap
     return sum(v * (1 if piece_mask & (1 << i) else 0)
                for i, v in enumerate(heatmap))