def search(node):
        for mv in node["history"]:
            leela.add_move(leela.whoseturn(), mv)
        stats, move_list = do_analyze(leela, base_dir, verbosity)
        expand(node, stats, move_list)

        for mv in node["history"]:
            leela.pop_move()
    try:
        move_num = -1
        C = sgf.cursor()
        prev_stats = {}
        prev_move_list = []
        has_prev = False

        leela.start()
        add_moves_to_leela(C, leela)

        # analyze main line, without variations
        while not C.atEnd:
            C.next()
            move_num += 1
            this_move = add_moves_to_leela(C, leela)
            current_player = leela.whoseturn()
            prev_player = "white" if current_player == "black" else "black"

            if ((args.analyze_start <= move_num <= args.analyze_end)
                    or (move_num in comment_requests_analyze)
                    or ((move_num - 1) in comment_requests_analyze)
                    or (move_num in comment_requests_variations)
                    or ((move_num - 1) in comment_requests_variations)):
                stats, move_list = do_analyze(leela, base_dir, args.verbosity)

                if 'winrate' in stats and stats['visits'] > 100:
                    collected_winrates[move_num] = (current_player,
                                                    stats['winrate'])

                if len(move_list) > 0 and 'winrate' in move_list[0]:
                    collected_best_moves[move_num] = move_list[0]['pos']
def do_variations(C, leela, stats, move_list, board_size, game_move, base_dir,
                  args):

    nodes_per_variation = args.nodes_per_variation
    verbosity = args.verbosity

    if 'bookmoves' in stats or len(move_list) <= 0:
        return None

    rootcolor = leela.whoseturn()
    leaves = []
    tree = {
        "children": [],
        "is_root": True,
        "history": [],
        "explored": False,
        "prob": 1.0,
        "stats": stats,
        "move_list": move_list,
        "color": rootcolor
    }

    def expand(node, stats, move_list):
        assert node["color"] in ['white', 'black']

        def child_prob_raw(i, move):
            # possible for book moves
            if "is_book" in move:
                return 1.0
            elif node["color"] == rootcolor:
                return move["visits"]**1.0
            else:
                return (move["policy_prob"] + move["visits"]) / 2.0

        def child_prob(i, move):
            return child_prob_raw(i, move) / probsum

        probsum = 0.0
        for (i, move) in enumerate(move_list):
            probsum += child_prob_raw(i, move)

        for (i, move) in enumerate(move_list):
            # Don't expand on the actual game line as a variation!
            if node["is_root"] and move["pos"] == game_move:
                node["children"].append(None)
                continue

            subhistory = node["history"][:]
            subhistory.append(move["pos"])
            prob = node["prob"] * child_prob(i, move)
            clr = "white" if node["color"] == "black" else "black"
            child = {
                "children": [],
                "is_root": False,
                "history": subhistory,
                "explored": False,
                "prob": prob,
                "stats": {},
                "move_list": [],
                "color": clr
            }
            node["children"].append(child)
            leaves.append(child)

        node["stats"] = stats
        node["move_list"] = move_list
        node["explored"] = True

        for i in range(len(leaves)):
            if leaves[i] is node:
                del leaves[i]
                break

    def search(node):
        for mv in node["history"]:
            leela.add_move(leela.whoseturn(), mv)
        stats, move_list = do_analyze(leela, base_dir, verbosity)
        expand(node, stats, move_list)

        for mv in node["history"]:
            leela.pop_move()

    expand(tree, stats, move_list)
    for i in range(nodes_per_variation):
        if len(leaves) > 0:
            node = max(leaves, key=(lambda n: n["prob"]))
            search(node)

    def advance(C, color, mv):
        found_child_idx = None
        clr = 'W' if color == 'white' else 'B'

        for j in range(len(C.children)):
            if clr in C.children[j].keys(
            ) and C.children[j][clr].data[0] == mv:
                found_child_idx = j

        if found_child_idx is not None:
            C.next(found_child_idx)
        else:
            nnode = sgflib.Node()
            nnode.add_property(sgflib.Property(clr, [mv]))
            C.append_node(nnode)
            C.next(len(C.children) - 1)

    def record(node):
        if not node["is_root"]:
            annotations.annotate_sgf(
                C,
                annotations.format_winrate(node["stats"], node["move_list"],
                                           board_size, None), [], [])
            move_list_to_display = []

            # Only display info for the principal variation or for lines that have been explored.
            for i in range(len(node["children"])):
                child = node["children"][i]

                if child is not None and (i == 0 or child["explored"]):
                    move_list_to_display.append(node["move_list"][i])

            (analysis_comment, lb_values,
             tr_values) = annotations.format_analysis(node["stats"],
                                                      move_list_to_display,
                                                      None)
            annotations.annotate_sgf(C, analysis_comment, lb_values, tr_values)

        for i in range(len(node["children"])):
            child = node["children"][i]

            if child is not None:
                if child["explored"]:
                    advance(C, node["color"], child["history"][-1])
                    record(child)
                    C.previous()
                # Only show variations for the principal line, to prevent info overload
                elif i == 0:
                    pv = node["move_list"][i]["pv"]
                    c = node["color"]
                    num_to_show = min(len(pv), max(1, len(pv) * 2 / 3 - 1))

                    if args.num_to_show is not None:
                        num_to_show = args.num_to_show

                    for k in range(int(num_to_show)):
                        advance(C, c, pv[k])
                        c = 'black' if c == 'white' else 'white'

                    for k in range(int(num_to_show)):
                        C.previous()

    record(tree)
예제 #4
0
    needs_variations = {}

    try:
        move_num = -1
        C = sgf.cursor()
        prev_stats = {}
        prev_move_list = []
        has_prev = False

        leela.start()
        add_moves_to_leela(C,leela)
        while not C.atEnd:
            C.next()
            move_num += 1
            this_move = add_moves_to_leela(C,leela)
            current_player = leela.whoseturn()
            prev_player = "white" if current_player == "black" else "black"
            if ((move_num >= args.analyze_start and move_num <= args.analyze_end) or
                (move_num in comment_requests_analyze) or
                ((move_num-1) in comment_requests_analyze) or
                (move_num in comment_requests_variations) or
                ((move_num-1) in comment_requests_variations)):
                stats, move_list = do_analyze(leela,base_dir,args.verbosity)

                if 'winrate' in stats and stats['visits'] > 100:
                    collected_winrates[move_num] = (current_player, stats['winrate'])
                if len(move_list) > 0 and 'winrate' in move_list[0]:
                    collected_best_moves[move_num] = move_list[0]['pos']
                    collected_best_move_winrates[move_num] = move_list[0]['winrate']

                delta = 0.0