def test_new_game(self): start = GameState.new_game(19) next_state = start.apply_move(Move.play(Point(16, 16))) self.assertEqual(start, next_state.prev) self.assertEqual(Player.white, next_state.nplayer) self.assertEqual(Player.black, next_state.board.get(Point(16, 16)))
def test_encode(self): encoder = get_encoder_by_name('oneplane', 9) gs = GameState.new_game(9) gs = gs.apply_move(Move.play(Point(5, 5))) gs = gs.apply_move(Move.play(Point(4, 5))) code = encoder.encode(gs) self.assertEqual(1, code[0][4][4]) self.assertEqual(-1, code[0][3][4])
def test_capture(self): board = Board(19) board.place_stone(Player.black, Point(2, 2)) board.place_stone(Player.white, Point(1, 2)) self.assertEqual(Player.black, board.get(Point(2, 2))) board.place_stone(Player.white, Point(2, 1)) self.assertEqual(Player.black, board.get(Point(2, 2))) board.place_stone(Player.white, Point(2, 3)) self.assertEqual(Player.black, board.get(Point(2, 2))) board.place_stone(Player.white, Point(3, 2)) self.assertIsNone(board.get(Point(2, 2)))
def empty_positions_(self): ret = list() for ri in range(1, self.board.sz + 1): for ci in range(1, self.board.sz + 1): pt = Point(ri, ci) if self.board.get(pt) is None: ret.append(pt) return ret
def print_board(board): for row in range(board.sz, 0, -1): bump = " " if row <= 9 else "" line = [] for col in range(1, board.sz + 1): stone = board.get(Point(row, col)) line.append(STONE_TO_CHAR[stone]) print('%s%d %s' % (bump, row, ''.join(line))) print(' ' + ' '.join(COLS[:board.sz]))
def test_empty_triangle(self): board = Board(5) board.place_stone(Player.black, Point(1, 1)) board.place_stone(Player.black, Point(1, 2)) board.place_stone(Player.black, Point(2, 2)) board.place_stone(Player.white, Point(2, 1)) black_string = board.get_go_string_(Point(1, 1)) six.assertCountEqual( self, [Point(3, 2), Point(2, 3), Point(1, 3)], black_string.liberties)
def legal_moves(self): if self.is_over(): return list() ret = [Move.pass_turn(), Move.resign()] for ri in range(1, self.board.sz + 1): for ci in range(1, self.board.sz + 1): m = Move.play(Point(ri, ci)) if self.is_valid_move(m): ret.append(m) return ret
def is_connected_(self): assert self.pmove.is_play pt = self.pmove.pt player = self.nplayer.other if (sum([ self.board.get(Point(ri, pt.c)) == player for ri in range(1, self.board.sz + 1) ]) == self.board.sz or sum([ self.board.get(Point(pt.r, ci)) == player for ci in range(1, self.board.sz + 1) ]) == self.board.sz or sum([ self.board.get(Point(i, i)) == player for i in range(1, self.board.sz + 1) ]) == self.board.sz or sum([ self.board.get(Point(i, self.board.sz + 1 - i)) == player for i in range(1, self.board.sz + 1) ]) == self.board.sz): return True return False
def get_handicap(sgf): go_board = Board(19) first_move_done = False move = None game_state = GameState.new_game(19) if sgf.get_handicap() is not None and sgf.get_handicap() != 0: for setup in sgf.get_root().get_setup_stones(): for move in setup: row, col = move go_board.place_stone(Player.black, Point(row + 1, col + 1)) first_move_done = True game_state = GameState(go_board, Player.white, None, move) return game_state, first_move_done
def test_encode(self): encoder = get_encoder_by_name('sevenplane', 9) gs = GameState.new_game(9) gs = gs.apply_move(Move.play(Point(2, 7))) gs = gs.apply_move(Move.play(Point(7, 2))) gs = gs.apply_move(Move.play(Point(3, 6))) gs = gs.apply_move(Move.play(Point(6, 3))) gs = gs.apply_move(Move.play(Point(3, 7))) gs = gs.apply_move(Move.play(Point(2, 6))) gs = gs.apply_move(Move.play(Point(2, 5))) code = encoder.encode(gs) self.assertEqual(1., code[0][1][5])
def encode(self, game_state): board_mtx = np.zeros(self.shape()) nplayer = game_state.nplayer for r in range(self.sz): for c in range(self.sz): p = Point(r + 1, c + 1) gstring = game_state.board.get_go_string_(p) if gstring is None: continue if gstring.color == nplayer: board_mtx[0, r, c] = 1 else: board_mtx[0, r, c] = -1 return board_mtx
def new_game_from_handicap(sgf): board = Board(19) first_move_done = False move = None gs = GameState.new_game(19) if sgf.get_handicap() is not None and sgf.get_handicap() != 0: print('Handicap detected') for setup in sgf.get_root().get_setup_stones(): for move in setup: row, col = move board.place_stone(Player.black, Point(row + 1, col + 1)) first_move_done = True gs = GameState(board, Player.white, None, move) return gs, first_move_done
def process_zip(self, zip_file_name, data_file_name, game_list): tar_file = self.unzip_data(zip_file_name) zip_file = tarfile.open(self.data_dir + '/' + tar_file) name_list = zip_file.getnames() total_examples = self.num_total_examples(zip_file, game_list, name_list) shape = self.encoder.shape() feature_shape = np.insert(shape, 0, np.asarray([total_examples])) features = np.zeros(feature_shape) labels = np.zeros((total_examples, )) counter = 0 for index in game_list: name = name_list[index + 1] if not name.endswith('.sgf'): raise ValueError(name + ' is not a valid sgf') print('Game Index {}, name {}'.format(index + 1, name)) sgf_content = zip_file.extractfile(name).read() sgf = sgf_game.from_string(sgf_content) game_state, first_move_done = self.get_handicap(sgf) for item in sgf.main_sequence_iter(): color, move_tuple = item.get_move() point = None if color is not None: if move_tuple is not None: row, col = move_tuple point = Point(row + 1, col + 1) move = Move.play(point) else: move = Move.pass_turn() if first_move_done and point is not None: features[counter] = self.encoder.encode(game_state) labels[counter] = self.encoder.encode_point(point) counter += 1 game_state = game_state.apply_move(move) first_move_done = True feature_file_base = self.data_dir + '/' + data_file_name + '_features_%d' label_file_base = self.data_dir + '/' + data_file_name + '_labels_%d' chunk = 0 chunksize = 1024 # it losses the last incomplete chunk, and that could be a bug while features.shape[0] >= chunksize: feature_file = feature_file_base % chunk label_file = label_file_base % chunk chunk += 1 current_features, features = features[:chunksize], features[ chunksize:] current_labels, labels = labels[:chunksize], labels[chunksize:] np.save(feature_file, current_features) np.save(label_file, current_labels)
def create_territory_labels_(self): self.labels.clear() for ri in range(1, self.board.sz + 1): for ci in range(1, self.board.sz + 1): pt = Point(ri, ci) if self.board.get(pt) is None and pt not in self.labels: (tpoints, boundary) = self.recursive_territory_labeling_( pt, {pt}, set()) if len(boundary) == 1: color = boundary.pop() for pti in tpoints: self.labels[pti] = color elif len(boundary) == 2: for pti in tpoints: self.labels[pti] = 'dame'
def encode(self, game_state): board_tensor = np.zeros(self.shape()) base_plane = {game_state.nplayer: 0, game_state.nplayer.other: 3} for row in range(self.sz): for col in range(self.sz): p = Point(r=row + 1, c=col + 1) gostring = game_state.board.get_go_string_(p) if gostring is None: if game_state.does_move_violate_ko_( game_state.nplayer, Move.play(p)): board_tensor[6][row][col] = 1 else: liberty_plane = min(3, gostring.num_liberties) - 1 liberty_plane += base_plane[gostring.color] board_tensor[liberty_plane][row][col] = 1 return board_tensor
def main(): args = parse_args() with open(args.file) as fd: data = fd.read() sgf = sgf_game.from_string(data) gs, first_move_done = new_game_from_handicap(sgf) print_board(gs.board) for item in sgf.main_sequence_iter(): color, move_tuple = item.get_move() point = None if color is not None: if move_tuple is not None: row, col = move_tuple point = Point(row + 1, col + 1) move = Move.play(point) print('Move ({},{})'.format(row + 1, col + 1)) else: move = Move.pass_turn() gs = gs.apply_move(move) print_board(gs.board)
def encode(self, game_state): board_tensor = np.zeros(self.shape()) base_plane = {game_state.nplayer: 0, game_state.nplayer.other: 3} next_player = game_state.nplayer if next_player == Player.white: board_tensor[8] = 1 else: board_tensor[9] = 1 for r in range(self.sz): for c in range(self.sz): p = Point(r + 1, c + 1) string = game_state.board.get_go_string_(p) if string is None: if game_state.does_move_violate_ko_( next_player, Move.play(p)): board_tensor[10][r][c] = 1 else: liberty_plane = min(4, string.num_liberties) - 1 liberty_plane += base_plane[string.color] board_tensor[liberty_plane][r][c] = 1 return board_tensor
def score_(self): wp = 0 wt = 0 bp = 0 bt = 0 dm = 0 for ri in range(1, self.board.sz + 1): for ci in range(1, self.board.sz + 1): pt = Point(ri, ci) color = self.board.get(pt) if color is None: tcolor = self.labels.get(pt) if tcolor == Player.black: bt += 1 elif tcolor == Player.white: wt += 1 else: dm += 1 elif color == Player.black: bp += 1 else: wp += 1 return (bp, bt, wp, wt, dm)
def test_decode_index(self): encoder = get_encoder_by_name('elevenplane', 9) pt = encoder.decode_point_index(16) self.assertEqual(Point(2, 8), pt)
def test_encode_point(self): encoder = get_encoder_by_name('elevenplane', 9) pt = Point(2, 2) idx = encoder.encode_point(pt) self.assertEqual(10, idx)
from rlgames.common_types import Player, Point __all__ = ['HASH_CODE', 'EMPTY_BOARD'] HASH_CODE = { (Point(r=1, c=1), Player.black): 5938969218873697146, (Point(r=1, c=1), Player.white): 6537908640901172238, (Point(r=1, c=2), Player.black): 4575650336626632829, (Point(r=1, c=2), Player.white): 6714225117977053155, (Point(r=1, c=3), Player.black): 5975505691681295160, (Point(r=1, c=3), Player.white): 7705714122181807010, (Point(r=1, c=4), Player.black): 1144767793739480361, (Point(r=1, c=4), Player.white): 2446078014333976630, (Point(r=1, c=5), Player.black): 1376395755508585321, (Point(r=1, c=5), Player.white): 886483694641699916, (Point(r=1, c=6), Player.black): 145504254062808924, (Point(r=1, c=6), Player.white): 7112209688809435977, (Point(r=1, c=7), Player.black): 7606349446666030018, (Point(r=1, c=7), Player.white): 9075376108734945888, (Point(r=1, c=8), Player.black): 2345945021219746370, (Point(r=1, c=8), Player.white): 2058555680059971594, (Point(r=1, c=9), Player.black): 4584944256790851944, (Point(r=1, c=9), Player.white): 5865600984395041337, (Point(r=1, c=10), Player.black): 1524123014086142396, (Point(r=1, c=10), Player.white): 2771175685712231736, (Point(r=1, c=11), Player.black): 8585213004220674452, (Point(r=1, c=11), Player.white): 1453612300888370159, (Point(r=1, c=12), Player.black): 3243755781169320981, (Point(r=1, c=12), Player.white): 5500764483198535569, (Point(r=1, c=13), Player.black): 7893969331835742556, (Point(r=1, c=13), Player.white): 7965774864463763873,
def point_from_coord(coords): col = COLS.index(coords[0].upper()) + 1 row = int(coords[1:]) return Point(row, col)
def test_scoring(self): # .w.ww # wwww. # bbbww # .bbbb # .b.b. board = Board(5) board.place_stone(Player.black, Point(1, 2)) board.place_stone(Player.black, Point(1, 4)) board.place_stone(Player.black, Point(2, 2)) board.place_stone(Player.black, Point(2, 3)) board.place_stone(Player.black, Point(2, 4)) board.place_stone(Player.black, Point(2, 5)) board.place_stone(Player.black, Point(3, 1)) board.place_stone(Player.black, Point(3, 2)) board.place_stone(Player.black, Point(3, 3)) board.place_stone(Player.white, Point(3, 4)) board.place_stone(Player.white, Point(3, 5)) board.place_stone(Player.white, Point(4, 1)) board.place_stone(Player.white, Point(4, 2)) board.place_stone(Player.white, Point(4, 3)) board.place_stone(Player.white, Point(4, 4)) board.place_stone(Player.white, Point(5, 2)) board.place_stone(Player.white, Point(5, 4)) board.place_stone(Player.white, Point(5, 5)) scorer = AreaScore(board) self.assertEqual(Player.white, scorer.winner()) self.assertEqual(9, scorer.bp) self.assertEqual(4, scorer.bt) self.assertEqual(9, scorer.wp) self.assertEqual(3, scorer.wt) self.assertEqual(0, scorer.dames)
def decode_point_index(self, index): row = index // self.sz col = index % self.sz return Point(r=row + 1, c=col + 1)
def decode_move_index(self, index): if index == self.sz * self.sz: return Move.pass_turn() row = index // self.sz col = index % self.sz return Move.play(Point(row + 1, col + 1))
def init_cache_(self, sz): return [ Point(ri, ci) for ri in range(1, sz + 1) for ci in range(1, sz + 1) ]
#Create perfect hash value for each go board state def to_python(player_state): if player_state is None: return 'None' if player_state == Player.black: return Player.black else: return Player.white MAX63 = 0x7fffffffffffffff table = dict() empty_board = 0 for row in range(1, 20): for col in range(1, 20): for state in (Player.black, Player.white): code = random.randint(0, MAX63) table[Point(row, col), state] = code print('from common_types import Player, Point') print('') print("__all__ = ['HASH_CODE', 'EMPTY_BOARD']") print('') print('HASH_CODE = {') for (pt, state), hash_code in table.items(): print(' (%r, %s): %r,' % (pt, to_python(state), hash_code)) print('}') print('') print('EMPTY_BOARD = %d' % (empty_board,))
def gtp_position_to_coord(gtp_position): col_str, row_str = gtp_position[0], gtp_position[1:] point = Point(int(row_str), COLS.find(col_str.upper()) + 1) return Move.play(point)
def test_remove_liberties(self): board = Board(5) board.place_stone(Player.black, Point(3, 3)) board.place_stone(Player.white, Point(2, 2)) white_string = board.get_go_string_(Point(2, 2)) six.assertCountEqual( self, [Point(2, 3), Point(2, 1), Point(1, 2), Point(3, 2)], white_string.liberties) board.place_stone(Player.black, Point(3, 2)) white_string = board.get_go_string_(Point(2, 2)) six.assertCountEqual( self, [Point(2, 3), Point(2, 1), Point(1, 2)], white_string.liberties)