Exemplo n.º 1
0
def test_get_setup_and_moves(tc):
    g1 = sgf.Sgf_game.from_string(SAMPLE_SGF)
    board1, plays1 = sgf_moves.get_setup_and_moves(g1)
    tc.assertBoardEqual(board1, DIAGRAM1)
    tc.assertEqual(plays1, [('b', (2, 3)), ('w', (3, 4)), ('b', None),
                            ('w', None)])

    g2 = sgf.Sgf_game(size=9)
    root = g2.get_root()
    root.set("AB", [(1, 2), (3, 4)])
    node = g2.extend_main_sequence()
    node.set("B", (5, 6))
    node = g2.extend_main_sequence()
    node.set("W", (5, 7))
    board2, plays2 = sgf_moves.get_setup_and_moves(g2)
    tc.assertBoardEqual(board2, DIAGRAM2)
    tc.assertEqual(plays2, [('b', (5, 6)), ('w', (5, 7))])

    g3 = sgf.Sgf_game.from_string("(;AB[ab][ba]AW[aa])")
    tc.assertRaisesRegex(ValueError, "setup position not legal",
                         sgf_moves.get_setup_and_moves, g3)

    g4 = sgf.Sgf_game.from_string("(;SZ[9];B[ab];AW[bc])")
    tc.assertRaisesRegex(ValueError, "setup properties after the root node",
                         sgf_moves.get_setup_and_moves, g4)

    g5 = sgf.Sgf_game.from_string("(;SZ[26];B[ab];W[bc])")
    board5, plays5 = sgf_moves.get_setup_and_moves(g5)
    tc.assertEqual(plays5, [('b', (24, 0)), ('w', (23, 1))])
Exemplo n.º 2
0
    def find_patterns_in_game_str(self, sgf_src, game_id, fail_if_no_date=False):
        """
        Similar to find_patterns_in_game but takes the game record directly
        as a string.

        sgf_src: SGF as a sting
        """

        sgf_game = None
        try:
            sgf_game = sgf.Sgf_game.from_bytes(sgf_src)
            root = sgf_game.get_root()
            if root.has_property('SZ'):
                size = root.get_raw('SZ').decode(root.get_encoding())
                if size != '19':
                    logging.warning("Skipping game with size: %s", size)
                    return ([], None)

        except Exception as e:
            logging.warning("Warning: cannot open game", sgf_src, ", reason:", e)
            return ([], None)

        try:
            board, plays = sgf_moves.get_setup_and_moves(sgf_game)
        except Exception as e:
            logging.warning("Warning: cannot setup game", sgf_game, ", reason:", e)
            return ([], None)

        patterns_found = []
        num_moves = 0
        num_found = 0
        date = None
        try:
            date = get_game_date_from_sgf(sgf_game, game_id)
        except (Exception, e):
            logging.warning("Could not find date in game id: %s sgf: %s. Reason: %s",
                            game_id, sgf_game, e)
            pass
        if fail_if_no_date and date is None:
            return ([], None)
        for colour, move in plays:
            if self.max_moves_ is not None and num_moves > self.max_moves_:
                break
            if move is None:
                continue
            row, col = move
            num_moves += 1
            try:
                board.play(row, col, colour)
                for pattern in self.extract_board_patterns_after_move_(game_id,
                                                                       num_moves,
                                                                       board,
                                                                       row, col):
                    # TODO also add info about who played last move to create this pattern, B or W (colour)
                    patterns_found.append(pattern)
            except ValueError as e:
                logging.warning("Error processing game", game_id, "sgf:", sgf_src,
                      "at move:", num_moves, ":", e)
                break
        return (patterns_found, date)
Exemplo n.º 3
0
def show_sgf_file(pathname, move_number):
    f = open(pathname, "rb")
    sgf_src = f.read()
    f.close()
    try:
        sgf_game = sgf.Sgf_game.from_bytes(sgf_src)
    except ValueError:
        raise Exception("bad sgf file")

    try:
        board, plays = sgf_moves.get_setup_and_moves(sgf_game)
    except ValueError as e:
        raise Exception(str(e))
    if move_number is not None:
        move_number = max(0, move_number-1)
        plays = plays[:move_number]

    for colour, move in plays:
        if move is None:
            continue
        row, col = move
        try:
            board.play(row, col, colour)
        except ValueError:
            raise Exception("illegal move in sgf file")

    print(ascii_boards.render_board(board))
    print()
Exemplo n.º 4
0
    def doLoadSGFfile(self, pathname, move_number=None):
        stones = []
        # print('pathname ',pathname)
        f = open(pathname, "rb")
        sgf_src = f.read()
        f.close()
        # print('sgfsrc', sgf_src)

        try:
            sgf_game = sgf.Sgf_game.from_bytes(sgf_src)
            text = []
            if sgf_game.get_gamename() is None:
                text.append(
                    sgf_game.get_player_name('b') + ' VS ' +
                    sgf_game.get_player_name('w') + '\n')
            else:
                text.append((str(sgf_game.get_gamename())) + '\n')
            text.append('Winner:   ' + str(sgf_game.get_winner()) + '\n')
            text.append('size:     ' + str(sgf_game.get_size()) + '\n')
            text.append('komi:     ' + str(sgf_game.get_komi()) + '\n')
            text.append('handicap: ' + str(sgf_game.get_handicap()) + '\n')
            text.append('TotalTime:' + (
                str(sgf_game.get_times() /
                    3600) if sgf_game.get_times() is not None else '0') + '\n')
            text.append('overtime: ' + str(sgf_game.get_overtime()) + '\n')
            text.append(str(sgf_game.get_common()) + '\n')

            self.infopanel.mTextEditor.setText(''.join(text))
            self.infopanel.black.Name = sgf_game.get_player_name('b')
            self.infopanel.white.Name = sgf_game.get_player_name('w')

        except ValueError:
            raise Exception("bad sgf file")

        try:
            board, plays = sgf_moves.get_setup_and_moves(sgf_game)
        except ValueError as e:
            raise Exception(str(e))
        if move_number is not None:
            move_number = max(0, move_number - 1)
            plays = plays[:move_number]

        for colour, move in plays:
            if move is None:
                continue
            # print('move ', move)
            if colour is 'w':
                stones.append([move[0], move[1], 'white'])
            elif colour is 'b':
                stones.append([move[0], move[1], 'black'])
            else:
                print('color error')
            # row, col = move
            # print("stones:",row,' ',col, ' ', colour)

        return stones

        # print('board ', board)
        # print(ascii_boards.render_board(board))
        pass
Exemplo n.º 5
0
def extract_corners(game_path):
    '''
    returns a Counter("sequence", count) of all sequences/subsequences in all corners
    of a given game_path
    '''
    with open(game_path) as sgf_file:
        game_data = sgf_file.read().encode('utf-8')

    try:
        g = sgf.Sgf_game.from_bytes(game_data)
        _, moves = sgf_moves.get_setup_and_moves(g)
    except BaseException:
        print("bad file: ", game_path)
        return Counter()

    corner_trackers = [[], [], [], []]
    stop = []

    for m in moves:
        corners, m = move_to_corner(m)
        if not corners:
            continue
        for c in corners:
            if c in stop:
                continue
            corner_trackers[c].append(m)
            if len(corner_trackers[c]) > MAX_JOSEKI_LENGTH:
                stop.append(c)
        if len(stop) == 4:
            break

    # we now have the sequences of the four corners of the board extracted, but
    # not 'canonical', i.e., the reflections across y=x would be distinct.
    # so, canonicalize them

    sequence_counts = Counter()
    for c in corner_trackers:
        seq = ""
        canonical = None
        for idx, (color, m) in enumerate(c):
            y, x = m
            if y < x and canonical is None:
                canonical = True
            elif y > x and canonical is None:
                x, y = y, x
                canonical = False
            elif canonical is False:
                x, y = y, x
            seq += sgf_format((color, (18 - y, x)))

            if idx > MIN_JOSEKI_LENGTH:
                sequence_counts[seq] += 1

    return sequence_counts
Exemplo n.º 6
0
def sgf2list(sgf_file):
    """From the input sgf file named -sgf_file- sgf2list returns the moves as a Python list of strings, each containing a position in the format ["Color", "vertex"], e.g. ['["W","P5"]','["B","P6"]'] """
    SGFstring = ''
    with open(sgf_file, "r") as myfile:
        SGFstring = myfile.read().replace('\n', '')
    SGFobject = sgf.Sgf_game.from_string(SGFstring)
    moves = sgf_moves.get_setup_and_moves(SGFobject)[1]
    listmoves = []
    for move in moves:
        Color = move[0].upper()
        vertex = sgfmill.common.format_vertex(move[1])
        listmoves.append('["' + Color + '","' + vertex + '"]')
    return listmoves
Exemplo n.º 7
0
def test_get_setup_and_moves_board_provided(tc):
    b = boards.Board(9)
    g1 = sgf.Sgf_game.from_string(SAMPLE_SGF)
    board1, plays1 = sgf_moves.get_setup_and_moves(g1, b)
    tc.assertIs(board1, b)
    tc.assertBoardEqual(board1, DIAGRAM1)
    tc.assertEqual(plays1, [('b', (2, 3)), ('w', (3, 4)), ('b', None),
                            ('w', None)])
    tc.assertRaisesRegex(ValueError, "board not empty",
                         sgf_moves.get_setup_and_moves, g1, b)
    b2 = boards.Board(19)
    tc.assertRaisesRegex(ValueError, "wrong board size, must be 9$",
                         sgf_moves.get_setup_and_moves, g1, b2)
Exemplo n.º 8
0
def get_pro_tables():
    out = []

    all_filenames = get_file_names()
    
    count_prob = 0
    count_ok = 0

    for filename in all_filenames:

        f = open(filename, "rb")
        sgf_src = f.read()
        f.close()

        try:
            sgf_game = sgf.Sgf_game.from_bytes(sgf_src)
            board, plays = sgf_moves.get_setup_and_moves(sgf_game)
        except Exception:
            continue
        
        if len(plays) < 5:
            continue
        
        end_idx = random.randint(5, len(plays))

        new_game = {'list_of_moves': [], 'black_stones': [], 'white_stones': []}
        
        skip = False
        turn = 0
        for play in plays[:end_idx]:
            
            if play[1] == None:
                skip = True
                continue
            else:
                new_game['list_of_moves'].append(rev_coord_to_name(play[1]))
                
                if turn == 0:
                    new_game['black_stones'].append(rev_coord_to_name(play[1]))
                    turn = 1
                elif turn == 1:
                    new_game['white_stones'].append(rev_coord_to_name(play[1]))
                    turn = 0
                
        if not skip:
            assert len(new_game['black_stones']) + len(new_game['white_stones']) == len(new_game['list_of_moves'])
            new_game['depth'] = len(new_game['list_of_moves'])    
            out.append(new_game)
            
    return out
Exemplo n.º 9
0
def read_sgf(filename):
    """Parse sgf."""
    with open(filename, "rb") as f:
        sgf_src = f.read()

    try:
        sgf_game = sgf.Sgf_game.from_bytes(sgf_src)
    except ValueError:
        raise Exception("bad sgf file")

    try:
        sgf_board, plays = sgf_moves.get_setup_and_moves(sgf_game)
    except ValueError as e:
        raise Exception(str(e))

    return sgf_board, plays, sgf_game
Exemplo n.º 10
0
def extract_from_game(game_path):
    """
    In addition to the corner information returned, we also add the winner,
    returning a tuple of ((sequence_counts, nextmove_counts), winner)
    where `winner` == 1 for B win, 0 otherwise.
    """
    with open(game_path) as sgf_file:
        game_data = sgf_file.read().encode('utf-8')

    try:
        g = sgf.Sgf_game.from_bytes(game_data)
        _, moves = sgf_moves.get_setup_and_moves(g)
    except BaseException:
        print("bad file: ", game_path)
        return Counter(), {}

    return (extract_corners(moves), 1 if g.get_winner().lower() == 'b' else 0)
Exemplo n.º 11
0
def open_sgf(filename):

    f = open(filename, "rb")
    sgf_src = f.read()
    f.close()
    #print("Just read this sgf:", sgf_src)
    sgf_game = sgf.Sgf_game.from_bytes(sgf_src)
    board, plays = sgf_moves.get_setup_and_moves(sgf_game)

    sz = sgf_game.get_size()

    # makes new game
    new_game = Game(sz)
    my_array = new_game.board
    print(plays)
    for color, move in plays:
        if move is None:
            continue
        row, col = move
        row = (new_game.board_sz - 1) - row
        if color == 'b':
            color = 'black'
        if color == 'w':
            color = 'white'

        try:
            my_array[row, col] = moves.GridSquare(row, col, color, sz)
            #board.play(row, col, colour)
        except ValueError:
            raise Exception("illegal move in sgf file")

    game_nodes = sgf_game.get_main_sequence()

    for node in game_nodes:
        if node.has_property("LB"):
            node_vals = node.get("LB")[0]
            row = (new_game.board_sz - 1) - node_vals[0][0]
            col = node_vals[0][1]
            sym = node_vals[1]
            # print("Printing label symbols in open_sgf")
            # print(sym, row, col)

            my_array[row, col] = moves.GridSquare(row, col, sym, sz)

    return new_game
Exemplo n.º 12
0
def test_get_setup_and_moves_move_in_root(tc):
    # A move in the root node is allowed (though deprecated) if there are no
    # setup stones.
    g1 = sgf.Sgf_game(size=9)
    root = g1.get_root()
    root.set("B", (1, 2))
    node = g1.extend_main_sequence()
    node.set("W", (3, 4))
    board1, plays1 = sgf_moves.get_setup_and_moves(g1)
    tc.assertTrue(board1.is_empty())
    tc.assertEqual(plays1, [('b', (1, 2)), ('w', (3, 4))])

    g2 = sgf.Sgf_game(size=9)
    root = g2.get_root()
    root.set("B", (1, 2))
    root.set("AW", [(3, 3)])
    node = g2.extend_main_sequence()
    node.set("W", (3, 4))
    tc.assertRaisesRegex(ValueError, "mixed setup and moves in root node",
                         sgf_moves.get_setup_and_moves, g2)
Exemplo n.º 13
0
def sgf_to_mat(pathname, move_number=None):
    """Converts game position from sgf file to in-memory matrix representation.

    Only follows left branch of game tree.
    Move number one is the empty board, default is the last node.
    Returns numpy matrix with '1's for black stones and '2' for white
    ones.
    """
    with open(pathname, "rb") as f:
        sgf_src = f.read()
    try:
        sgf_game = sgf.Sgf_game.from_bytes(sgf_src)
    except ValueError:
        raise Exception("bad sgf file")
    try:
        board, plays = sgf_moves.get_setup_and_moves(sgf_game)
    except ValueError as e:
        raise Exception(str(e))
    if move_number is not None:
        move_number = max(0, move_number-1)
        plays = plays[:move_number]
    for colour, move in plays:
        if move is None:
            continue
        row, col = move
        try:
            board.play(row, col, colour)
        except ValueError:
            raise Exception("illegal move in sgf file")
    mat = np.full((19, 19), 0)
    for colour, pos in board.list_occupied_points():
        if (colour == 'b'):
            mat[pos] = 1
        if (colour == 'w'):
            mat[pos] = 2
    # internal representation starts coordinates in upper left:
    mat = np.flipud(mat)
    return mat
Exemplo n.º 14
0
    def __init__(self, pathname):
        self.pathname = pathname

        num_of_threads = 100

        with open(self.pathname, "rb") as f:
            sgf_src = f.read()

        try:
            self.sgf_game = sgf.Sgf_game.from_bytes(sgf_src)
        except:
            raise Exception("SGF file format error")
        try:
            _, self.play_seq = sgf_moves.get_setup_and_moves(self.sgf_game)
        except:
            raise Exception("")

        self.initial_board = []

        for i in range(19):
            self.initial_board.append([0, i])
            self.initial_board.append([18, i])
            self.initial_board.append([i, 0])
            self.initial_board.append([i, 18])
Exemplo n.º 15
0
    def find_patterns_in_game_str(self,
                                  sgf_src,
                                  game_id,
                                  fail_if_no_date=False):
        """
        Similar to find_patterns_in_game but takes the game record directly
        as a string.

        sgf_src: SGF as a sting
        """

        sgf_game = None
        try:
            sgf_game = sgf.Sgf_game.from_bytes(sgf_src)
            root = sgf_game.get_root()
            if root.has_property('SZ'):
                size = root.get_raw('SZ').decode(root.get_encoding())
                if size != '19':
                    logging.warning("Skipping game with size: %s", size)
                    return ([], None)

        except Exception as e:
            logging.warning("Warning: cannot open game", sgf_src, ", reason:",
                            e)
            return ([], None)

        try:
            board, plays = sgf_moves.get_setup_and_moves(sgf_game)
        except Exception as e:
            logging.warning("Warning: cannot setup game", sgf_game,
                            ", reason:", e)
            return ([], None)

        patterns_found = []
        num_moves = 0
        num_found = 0
        date = None
        try:
            date = get_game_date_from_sgf(sgf_game, game_id)
        except (Exception, e):
            logging.warning(
                "Could not find date in game id: %s sgf: %s. Reason: %s",
                game_id, sgf_game, e)
            pass
        if fail_if_no_date and date is None:
            return ([], None)
        for colour, move in plays:
            if self.max_moves_ is not None and num_moves > self.max_moves_:
                break
            if move is None:
                continue
            row, col = move
            num_moves += 1
            try:
                board.play(row, col, colour)
                for pattern in self.extract_board_patterns_after_move_(
                        game_id, num_moves, board, row, col):
                    # TODO also add info about who played last move to create this pattern, B or W (colour)
                    patterns_found.append(pattern)
            except ValueError as e:
                logging.warning("Error processing game", game_id, "sgf:",
                                sgf_src, "at move:", num_moves, ":", e)
                break
        return (patterns_found, date)
Exemplo n.º 16
0
def extract_board_table(sgf_file, move_number):
    sgf_src = sgf_file.read()
    sgf_file.close()
    try:
        sgf_game = sgf.Sgf_game.from_bytes(sgf_src)
    except ValueError:
        raise Exception("bad sgf file")

    board_size = sgf_game.get_size()

    # extract annotations/markings eg. A, B, square
    try:
        node = sgf_game.get_main_sequence()[move_number - 1]
    except ValueError as e:
        raise Exception(str(e))

    try:
        board, plays = sgf_moves.get_setup_and_moves(sgf_game)
    except ValueError as e:
        raise Exception(str(e))
    if move_number is not None:
        move_number = max(0, move_number - 1)
        plays = plays[:move_number]

    for colour, move in plays:
        if move is None:
            continue
        row, col = move
        try:
            board.play(row, col, colour)
        except ValueError:
            raise Exception("illegal move in sgf file")

    board_list = [[col + 1, row + 1, board.get(row, col)] for col in range(board_size) for row in range(board_size)]
    board_table = pd.DataFrame(board_list, columns=['x', 'y', 'stone'])

    # properties_with_a_value = ['LB']
    p = 'LB'
    text_list = list()
    if p in node.properties():
        text_list = [[i[0][1] + 1, i[0][0] + 1, 'text', i[1]] for i in node.get(p)]
    text_table = pd.DataFrame(text_list, columns=['x', 'y', 'annotation_type', 'value'])

    properties_without_a_value = ['SQ', 'MA']
    symbol_list = list()
    for p in properties_without_a_value:
        if p in node.properties():
            for i in node.get(p):
                row = i[0]
                col = i[1]
                symbol_list = symbol_list + [[col + 1, row + 1, 'symbol', p]]
    symbol_table = pd.DataFrame(symbol_list, columns=['x', 'y', 'annotation_type', 'value'])
    symbol_table

    # combine stones and annotations into a single table
    annotation_table = pd.concat([text_table, symbol_table])
    board_table = board_table.merge(annotation_table, on=['x', 'y'], how='outer')

    # set the color of the annotations
    board_table['annotation_color'] = np.where(
        (board_table['stone'].isnull()) | (board_table['stone'] == 'w'),
        'b',
        'w')

    return board_table, board_size