def _parse_game(game: Game) -> List[str]: positions: List[str] = [] board = game.board() for move in game.mainline_moves(): board.push(move) positions.append(board.fen()) return positions
def pgn_game_to_serializable_game(pgn_game: pgn.Game) -> SerializableGame: current_index = 1 all_positions: List[SerializablePosition] = [] def parse_position(pgn_position: pgn.ChildNode, is_mainline: bool) -> SerializablePosition: nonlocal current_index nonlocal all_positions index = current_index current_index += 1 next_pos_index = None if pgn_position.variations: next_pos_index = parse_position(pgn_position.variations[0], True).index variations_indexes = [] if len(pgn_position.variations) > 1: variations_indexes = [ parse_position(p, False).index for i, p in enumerate(pgn_position.variations) if i > 0 ] position = SerializablePosition( index=index, next_position_index=next_pos_index, variations_indexes=variations_indexes, nags=list(pgn_position.nags), fen=pgn_position.board().fen(), comment=pgn_position.comment, commentBefore=pgn_position.starting_comment, san=pgn_position.san(), is_mainline=is_mainline, move=Move(from_square=square_name(pgn_position.move.from_square), to=square_name(pgn_position.move.to_square), promotion=pgn_position.move.promotion)) all_positions.insert(0, position) return position first_pos = SerializablePosition(index=0, fen=pgn_game.board().fen(), is_mainline=True, nags=[], san="", variations_indexes=[], next_position_index=1) all_positions.append(first_pos) for i, position in enumerate(pgn_game.variations): if i != 0: first_pos.variations_indexes.append(current_index) parse_position(position, i == 0) headers: Dict[str, str] = {} for key in pgn_game.headers.keys(): headers[key] = pgn_game.headers[key] game = SerializableGame( headers=headers, comment=pgn_game.starting_comment, positions=all_positions, ) return game
def analyze_game(self, game: Game, tier: int) -> Optional[Puzzle]: logger.debug(f'Analyzing tier {tier} {game.headers.get("Site")}...') prev_score: Score = Cp(20) seen_epds: Set[str] = set() board = game.board() skip_until_irreversible = False for node in game.mainline(): if skip_until_irreversible: if board.is_irreversible(node.move): skip_until_irreversible = False seen_epds.clear() else: board.push(node.move) continue current_eval = node.eval() if not current_eval: logger.debug("Skipping game without eval on ply {}".format( node.ply())) return None board.push(node.move) epd = board.epd() if epd in seen_epds: skip_until_irreversible = True continue seen_epds.add(epd) if board.castling_rights != maximum_castling_rights(board): continue result = self.analyze_position(node, prev_score, current_eval, tier) if isinstance(result, Puzzle): return result prev_score = -result logger.debug("Found nothing from {}".format(game.headers.get("Site"))) return None