def not_puzzle(self, fen: str, prev_score: Score, move: str, current_score: Score) -> None: board = Board(fen) game = Game.from_board(board) node = game.add_main_variation(Move.from_uci(move)) current_eval = PovScore(current_score, not board.turn) result = self.gen.analyze_position( node, prev_score, current_eval, tier=10) self.assertIsInstance(result, Score)
def get_puzzle(self, fen: str, prev_score: Score, move: str, current_score: Score, moves: str) -> None: board = Board(fen) game = Game.from_board(board) node = game.add_main_variation(Move.from_uci(move)) current_eval = PovScore(current_score, not board.turn) result = self.gen.analyze_position(node, prev_score, current_eval, tier=10) self.assert_is_puzzle_with_moves(result, [Move.from_uci(x) for x in moves.split()])
def analyze_position(server: Server, engine: SimpleEngine, node: GameNode, prev_score: Score, current_eval: PovScore) -> Union[Puzzle, Score]: board = node.board() winner = board.turn score = current_eval.pov(winner) if board.legal_moves.count() < 2: return score game_url = node.game().headers.get("Site") logger.debug("{} {} to {}".format(node.ply(), node.move.uci() if node.move else None, score)) if prev_score > Cp(400): logger.debug("{} Too much of a winning position to start with {} -> {}".format(node.ply(), prev_score, score)) return score if is_up_in_material(board, winner): logger.debug("{} already up in material {} {} {}".format(node.ply(), winner, material_count(board, winner), material_count(board, not winner))) return score elif score >= Mate(1) and not allow_one_mover: logger.debug("{} mate in one".format(node.ply())) return score elif score > mate_soon: logger.info("Mate {}#{} Probing...".format(game_url, node.ply())) if server.is_seen_pos(node): logger.info("Skip duplicate position") return score mate_solution = cook_mate(engine, copy.deepcopy(node), winner) server.set_seen(node.game()) return Puzzle(node, mate_solution) if mate_solution is not None else score elif score >= Cp(0) and win_chances(score) > win_chances(prev_score) + 0.5: if score < Cp(400) and material_diff(board, winner) > -1: logger.info("Not clearly winning and not from being down in material, aborting") return score logger.info("Advantage {}#{} {} -> {}. Probing...".format(game_url, node.ply(), prev_score, score)) if server.is_seen_pos(node): logger.info("Skip duplicate position") return score puzzle_node = copy.deepcopy(node) solution : Optional[List[NextMovePair]] = cook_advantage(engine, puzzle_node, winner) server.set_seen(node.game()) if not solution: return score while len(solution) % 2 == 0 or not solution[-1].second: if not solution[-1].second: logger.info("Remove final only-move") solution = solution[:-1] if not solution or (len(solution) == 1 and not allow_one_mover): logger.info("Discard one-mover") return score last = list(puzzle_node.mainline())[len(solution)] gain = material_diff(last.board(), winner) - material_diff(board, winner) if gain > 1 or ( len(solution) == 1 and win_chances(solution[0].best.score) > win_chances(solution[0].second.score) + 0.5): return Puzzle(node, [p.best.move for p in solution]) return score else: return score
def get_info_obj(score): pov_score = PovScore(Cp(score), chess.WHITE) return dict(score=pov_score)
def analyze_position(self, node: ChildNode, prev_score: Score, current_eval: PovScore, tier: int) -> Union[Puzzle, Score]: board = node.board() winner = board.turn score = current_eval.pov(winner) if board.legal_moves.count() < 2: return score game_url = node.game().headers.get("Site") logger.debug("{} {} to {}".format( node.ply(), node.move.uci() if node.move else None, score)) if prev_score > Cp(300) and score < mate_soon: logger.debug( "{} Too much of a winning position to start with {} -> {}". format(node.ply(), prev_score, score)) return score if is_up_in_material(board, winner): logger.debug("{} already up in material {} {} {}".format( node.ply(), winner, material_count(board, winner), material_count(board, not winner))) return score elif score >= Mate(1) and tier < 3: logger.debug("{} mate in one".format(node.ply())) return score elif score > mate_soon: logger.debug("Mate {}#{} Probing...".format(game_url, node.ply())) if self.server.is_seen_pos(node): logger.debug("Skip duplicate position") return score mate_solution = self.cook_mate(copy.deepcopy(node), winner) if mate_solution is None or (tier == 1 and len(mate_solution) == 3): return score return Puzzle(node, mate_solution, 999999999) elif score >= Cp(200) and win_chances( score) > win_chances(prev_score) + 0.6: if score < Cp(400) and material_diff(board, winner) > -1: logger.debug( "Not clearly winning and not from being down in material, aborting" ) return score logger.debug("Advantage {}#{} {} -> {}. Probing...".format( game_url, node.ply(), prev_score, score)) if self.server.is_seen_pos(node): logger.debug("Skip duplicate position") return score puzzle_node = copy.deepcopy(node) solution: Optional[List[NextMovePair]] = self.cook_advantage( puzzle_node, winner) self.server.set_seen(node.game()) if not solution: return score while len(solution) % 2 == 0 or not solution[-1].second: if not solution[-1].second: logger.debug("Remove final only-move") solution = solution[:-1] if not solution or len(solution) == 1: logger.debug("Discard one-mover") return score if tier < 3 and len(solution) == 3: logger.debug("Discard two-mover") return score cp = solution[len(solution) - 1].best.score.score() return Puzzle(node, [p.best.move for p in solution], 999999998 if cp is None else cp) else: return score