Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
    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