Пример #1
0
def format_delta_info(delta, this_move, board_size):
    comment = ""
    LB_values = []
    if delta <= -0.2:
        comment += "=================================\n"
        comment += "Leela thinks %s is a big mistake!\n" % convert_position(
            board_size, this_move)
        comment += "Winning percentage drops by %.2f%%!\n" % (-delta * 100)
        comment += "=================================\n"
        if not is_pass(board_size, this_move):
            LB_values.append("%s:%s" % (this_move, "?"))
    elif delta <= -0.1:
        comment += "=================================\n"
        comment += "Leela thinks %s is a mistake!\n" % convert_position(
            board_size, this_move)
        comment += "Winning percentage drops by %.2f%%\n" % (-delta * 100)
        comment += "=================================\n"
        if not is_pass(board_size, this_move):
            LB_values.append("%s:%s" % (this_move, "?"))
    elif delta <= -0.05:
        comment += "=================================\n"
        comment += "Leela thinks %s is not the best choice.\n" % convert_position(
            board_size, this_move)
        comment += "Winning percentage drops by %.2f%%\n" % (-delta * 100)
        comment += "=================================\n"
        if not is_pass(board_size, this_move):
            LB_values.append("%s:%s" % (this_move, "?"))
    elif delta <= -0.025:
        comment += "=================================\n"
        comment += "Leela slightly dislikes %s.\n" % convert_position(
            board_size, this_move)
        comment += "=================================\n"

    comment += "\n"
    return comment, LB_values
Пример #2
0
    def analyze(self):
        """Analyze current position with given seconds per search."""
        stdout, stderr = self.genmove()

        # Drain and parse Leela stdout & stderr
        stats, move_list = self.parse_analysis(stdout, stderr)

        if stats.get('winrate') and move_list:
            best_move = convert_position(self.board_size, move_list[0]['pos'])
            winrate = (stats['winrate'] * 100)
            visits = stats['visits']
            pv = " ".join([convert_position(self.board_size, m) for m in move_list[0]['pv']])
            logger.debug(f"Suggested: %s (winrate %.2f%%, %d visits). Perfect sequence: %s",
                         best_move, winrate, visits, pv)
        else:
            chosen_move = convert_position(self.board_size, stats['chosen'])
            logger.debug(f"Chosen move: %s", chosen_move)

        return stats, move_list
Пример #3
0
def format_winrate(stats, move_list, board_size, next_game_move):
    comment = ""
    if 'winrate' in stats:
        comment += "Overall black win%%: %.2f%%\n" % (stats['winrate'] * 100)
    else:
        comment += "Overall black win%: not computed (Leela still in opening book)\n"

    if len(move_list) > 0 and move_list[0]['pos'] != next_game_move:
        comment += "Leela's preferred next move: %s\n" % convert_position(board_size, move_list[0]['pos'])
    else:
        comment += "\n"

    return comment
Пример #4
0
    def analyze_main_line(self):
        logger.info("Started analyzing main line.")

        move_num = -1
        prev_stats = {}
        prev_move_list = []
        has_prev = False
        previous_player = None

        logger.info(f"Executing analysis for %d moves", len(self.moves_to_analyze))
        moves_count = 0
        self.cursor.reset()
        self.bot = self.factory()
        self.bot.time_per_move = CONFIG['analyze_time']
        self.bot.start()
        # analyze main line, without variations
        while not self.cursor.atEnd:
            self.cursor.next()
            move_num += 1
            this_move = self.add_moves_to_bot()

            current_player = 'black' if 'W' in self.cursor.node else 'white'

            if previous_player == current_player:
                raise BotException('Two consecutive moves.')

            if move_num in self.moves_to_analyze:
                stats, move_list = self.do_analyze()

                # Here we store ALL statistics
                self.all_stats[move_num] = stats
                self.all_move_lists[move_num] = move_list

                if move_list and 'winrate' in move_list[0]:
                    self.best_moves[move_num] = move_list[0]

                delta = 0.0

                if 'winrate' in stats and (move_num - 1) in self.best_moves:
                    if this_move != self.best_moves[move_num - 1]['pos']:
                        delta = stats['winrate'] - self.best_moves[move_num - 1]['winrate']
                        delta = min(0.0, (-delta if self.bot.whose_turn() == "black" else delta))

                    if -delta > CONFIG['analyze_threshold']:
                        (delta_comment, delta_lb_values) = annotations.format_delta_info(delta, this_move,
                                                                                         self.board_size)
                        annotations.annotate_sgf(self.cursor, delta_comment, delta_lb_values, [])

                if has_prev and delta <= -CONFIG['variations_threshold']:
                    self.moves_to_variations[move_num - 1] = True

                if -delta > CONFIG['analyze_threshold']:
                    logger.warning("Move %d: %s %s is a mistake (winrate dropped by %.2f%%)", move_num + 1,
                                   previous_player, convert_position(self.board_size, this_move), -delta * 100)

                next_game_move = self.next_move_pos()

                annotations.annotate_sgf(self.cursor,
                                         annotations.format_winrate(stats, move_list, self.board_size, next_game_move),
                                         [], [])

                if has_prev and ((move_num - 1) in self.moves_to_analyze and -delta > CONFIG['analyze_threshold'] or (
                        move_num - 1) in self.moves_to_variations):
                    (analysis_comment, lb_values, tr_values) = annotations.format_analysis(
                        prev_stats, filter_move_list(prev_move_list), this_move, self.board_size)
                    self.cursor.previous()
                    # adding comment to sgf with suggested alternative variations
                    annotations.annotate_sgf(self.cursor, analysis_comment, lb_values, tr_values)
                    self.cursor.next()

                prev_stats = stats
                prev_move_list = move_list
                has_prev = True

                self.save_to_file()
                self.graph_winrates()

                if 'winrate' in stats \
                        and (1 - CONFIG['stop_on_winrate'] > stats['winrate']
                             or stats['winrate'] > CONFIG['stop_on_winrate']):
                    break

                moves_count += 1
                logger.info("Analysis done for %d/%d move.", moves_count, len(self.moves_to_analyze))
            else:
                prev_stats = {}
                prev_move_list = []
                has_prev = False

            previous_player = current_player

        logger.info("Finished analyzing main line.")
Пример #5
0
 def current_position(self, frame="/odom_combined"):
     return utils.convert_position(self.listener, (0, 0, 0), (0, 0, 0),
                                   "/base_link", frame)
Пример #6
0
    while not game.cursor.atEnd:
        game.cursor.next()
        move_num += 1
        this_move = game.add_moves_to_bot()
    game.bot.go_to_position()
    # c_node = game.cursor.node
    # nnode = Node()
    # game.cursor.append_node(nnode)
    for i in range(1):
        stdout, stderr = game.bot.genmove()

        # Drain and parse Leela stdout & stderr
        stats, move_list = game.bot.parse_analysis(stdout, stderr)

        if stats.get('winrate') and move_list:
            best_move = convert_position(19, move_list[0]['pos'])

        print("result={}".format(best_move))
        color = game.bot.whose_turn()
        best_move = parse_position(19, best_move)
        command = f"play {color} {best_move}"
        print("index is {},play is {}".format(i, command))
        # game.bot.send_command(command)
        # this_move = game.add_moves_to_bot()
        game.bot.add_move_to_history(color, best_move)
        clr = 'W' if color == 'white' else 'B'
        nnode = Node()
        nnode.add_property(Property(clr, [best_move]))
        game.cursor.append_node(nnode)
        game.cursor.next(len(game.cursor.children) - 1)
Пример #7
0
def test_convert_position_valid():
    assert convert_position(19, 'aa') == 'A19'
    assert convert_position(19, 'as') == 'A1'
    assert convert_position(19, 'sa') == 'T19'
    assert convert_position(19, 'ss') == 'T1'
    assert convert_position(19, 'jj') == 'K10'
    assert convert_position(19, '') == 'pass'

    assert convert_position(13, 'aa') == 'A13'
    assert convert_position(13, 'am') == 'A1'
    assert convert_position(13, 'ma') == 'N13'
    assert convert_position(13, 'mm') == 'N1'
    assert convert_position(13, 'gg') == 'G7'
    assert convert_position(13, '') == 'pass'

    assert convert_position(9, 'aa') == 'A9'
    assert convert_position(9, 'ai') == 'A1'
    assert convert_position(9, 'ia') == 'J9'
    assert convert_position(9, 'ii') == 'J1'
    assert convert_position(9, 'ee') == 'E5'
    assert convert_position(9, '') == 'pass'
 def current_position(self, frame="/odom_combined"):
     return utils.convert_position(self.listener, 
                                   (0,0,0), 
                                   (0,0,0), 
                                   "/base_link", 
                                   frame)
Пример #9
0
 def add_move_to_history(self, color: str, pos: str):
     """ Convert given SGF coordinates to GTP console command"""
     move = convert_position(self.board_size, pos)
     command = f"play {color} {move}"
     self._history.append(command)