Ejemplo n.º 1
0
def find_puzzle_candidates(game: Game, scan_depth=SCAN_DEPTH) -> List[Puzzle]:
    """ finds puzzle candidates from a chess game 
    """
    log(Color.DIM, "Scanning game for puzzles (depth: %d)..." % scan_depth)
    prev_score = Cp(0)
    puzzles = []
    i = 0
    node = game
    while not node.is_end():
        next_node = node.variation(0)
        next_board = next_node.board()
        cur_score = AnalysisEngine.best_move(next_board, scan_depth).score
        board = node.board()
        highlight_move = False
        if should_investigate(prev_score, cur_score, board):
            highlight_move = True
            puzzle = Puzzle(
                board,
                next_node.move,
            )
            puzzles.append(puzzle)
        log_move(board, next_node.move, cur_score, highlight=highlight_move)
        prev_score = cur_score
        node = next_node
        i += 1
    return puzzles
Ejemplo n.º 2
0
 def _analyze(board, depth, **kwargs) -> Union[List[InfoDict], InfoDict]:
     try:
         info = AnalysisEngine.instance().analyse(board, Limit(depth=depth), **kwargs)
     except EngineTerminatedError:
         log(Color.RED, "Analysis engine crashed... restarting")
         AnalysisEngine.quit()
         info = AnalysisEngine._analyze(board, depth, **kwargs)
     return info
Ejemplo n.º 3
0
 def _calculate_candidate_moves(self, depth):
     """ Find the best move from board position using multipv 3
     """
     multipv = NUM_CANDIDATE_MOVES
     log(Color.BLACK, "Evaluating best %d moves (depth %d)..." % (multipv, depth))
     self.candidate_moves = AnalysisEngine.best_moves(self.board, depth, multipv)
     for analyzed_move in self.candidate_moves:
         self._log_move(analyzed_move.move, analyzed_move.score)
Ejemplo n.º 4
0
 def _calculate_best_move(self, depth):
     """ Find the best move from board position using multipv 1
     """
     log(Color.BLACK, "Evaluating best move (depth %d)..." % depth)
     best_move = AnalysisEngine.best_move(self.board, depth)
     self.best_move = best_move.move
     self.score = best_move.score
     if self._num_legal_moves() == 1:
         self.candidate_moves = [best_move]
     self._log_move(self.best_move, self.score)
Ejemplo n.º 5
0
 def _analyze_best_initial_move(self, depth) -> Move:
     log(Color.BLACK, "Evaluating best initial move (depth %d)..." % depth)
     best_move = AnalysisEngine.best_move(self.initial_board, depth)
     if best_move.move:
         self.analyzed_moves.append(best_move)
         log_move(self.initial_board,
                  best_move.move,
                  best_move.score,
                  show_uci=True)
     self.initial_score = best_move.score
     return best_move.move
Ejemplo n.º 6
0
 def _analyze_initial_moves(self, depth):
     """ get the score of the position before the initial move
         also get the score of the position after the initial move
     """
     best_move = self._analyze_best_initial_move(depth)
     if not self.initial_move:
         return
     elif self.initial_move == best_move:
         log(Color.BLACK, "The move played was the best move")
     else:
         log(Color.BLACK,
             "Evaluating played initial move (depth %d)..." % depth)
         analyzed_move = AnalysisEngine.evaluate_move(
             self.initial_board, self.initial_move, depth)
         self.analyzed_moves.append(analyzed_move)
         log_move(self.initial_board,
                  self.initial_move,
                  analyzed_move.score,
                  show_uci=True)
Ejemplo n.º 7
0
 def _log_position(self):
     if self.initial_move:
         move_san = self.initial_board.san(self.initial_move)
         log(
             Color.VIOLET, "\nAfter %s %s" %
             (fullmove_string(self.initial_board).strip(), move_san))
     log_board(self.board)
     log(Color.DARK_BLUE,
         "Material difference:  %d" % material_difference(self.board))
     log(Color.DARK_BLUE,
         "# legal moves:        %d" % self._num_legal_moves())
Ejemplo n.º 8
0
 def generate(self, depth):
     """ Generate new positions for the puzzle until a final position is reached
     """
     log_board(self.initial_board)
     self._analyze_initial_moves(depth)
     self._set_initial_position()
     position = self.initial_position
     position.evaluate(depth)
     self.player_moves_first = self._player_moves_first()
     is_player_move = not self.player_moves_first
     while True:
         self.positions.append(position)
         if position.is_final(is_player_move):
             log_str = "Not going deeper: "
             if position.is_ambiguous():
                 log_str += "ambiguous"
             elif position.board.is_game_over():
                 log_str += "game over"
             log(Color.YELLOW, log_str)
             break
         else:
             log_str = "Going deeper..."
             if is_player_move is not None:
                 if is_player_move:
                     if len(position.candidate_moves) == 1:
                         log_str += " only one move"
                     else:
                         log_str += " one clear best move"
                 else:
                     log_str += " not player move"
             log(Color.DIM, log_str)
         position = PuzzlePosition(position.board, position.best_move)
         position.evaluate(depth)
         is_player_move = not is_player_move
     self._calculate_final_score(depth)
     if self.is_complete():
         log(Color.GREEN, "Puzzle is complete")
     else:
         log(Color.RED, "Puzzle incomplete")
Ejemplo n.º 9
0
def print_puzzle_pgn(puzzle, pgn_headers=None):
    puzzle_pgn = puzzle.to_pgn(pgn_headers=pgn_headers)
    log(Color.MAGENTA, "NEW PUZZLE GENERATED\n")
    print(Color.CYAN + puzzle_pgn + "\n\n" + Color.ENDC)
Ejemplo n.º 10
0
if settings.quiet:
    configure_logging(level=logging.INFO)
else:
    configure_logging(level=logging.DEBUG)


def print_puzzle_pgn(puzzle, pgn_headers=None):
    puzzle_pgn = puzzle.to_pgn(pgn_headers=pgn_headers)
    log(Color.MAGENTA, "NEW PUZZLE GENERATED\n")
    print(Color.CYAN + puzzle_pgn + "\n\n" + Color.ENDC)


# load a FEN and try to create a puzzle from it

if settings.fen:
    log(Color.DIM, AnalysisEngine.name())
    puzzle = Puzzle(Board(settings.fen))
    puzzle.generate(depth=settings.search_depth)
    if puzzle.is_complete():
        print_puzzle_pgn(puzzle)
    engine.quit()
    exit(0)

# load games from a PGN and scan them for puzzles

n_positions = 0  # number of positions considered
n_puzzles = 0  # number of puzzles generated
game_id = 0
pgn = open(settings.pgn, "r")

while game_id < settings.start_index: