def handle_play(self, color, move): if move.lower() == 'pass': self.game_state = self.game_state.apply_move(Move.pass_turn()) elif move.lower() == 'resign': self.game_state = self.game_state.apply_move(Move.resign()) else: self.game_state = self.game_state.apply_move(gtp_position_to_coords(move)) return response.success()
def decode_move_index(self, index): if index == self.board_size * self.board_size: return Move.pass_turn() row = index // self.board_size col = index % self.board_size return Move.play(Point(row=row + 1, col=col + 1))
def __init__(self, game_state, parent=None, move=None): self.game_state = game_state self.parent = parent self.move = move self.children = [] self.win_count = {Player.black: 0, Player.white: 0} self.num_rollouts = 0 self.unvisited_moves = legal_moves(game_state) + [Move.pass_turn()]
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') 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 # Due to files with large content, split up after chunksize chunksize = 1024 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 play_their_move(self): their_name = self.their_color.name their_letter = their_name[0].upper() pos = self.command_and_response("genmove {}\n".format(their_name)) if pos.lower() == 'resign': self.game_state = self.game_state.apply_move(Move.resign()) self._stopped = True elif pos.lower() == 'pass': self.game_state = self.game_state.apply_move(Move.pass_turn()) self.sgf.append(";{}[]\n".format(their_letter)) if self.game_state.last_move.is_pass: self._stopped = True else: move = gtp_position_to_coords(pos) self.game_state = self.game_state.apply_move(move) self.sgf.append(";{}[{}]\n".format(their_letter, self.sgf.coordinates(move)))
def select_move(self, game_state): best_moves = [] best_so_far = -MAX_SCORE for move in legal_moves(game_state): next_state = game_state.apply_move(move) opponent_best = alpha_beta_best(next_state, best_so_far, self.max_depth, self.eval_fn) # opponent_best = best_result(next_state, self.max_depth, self.eval_fn) our_result = -opponent_best if our_result > best_so_far: best_moves = [move] best_so_far = our_result elif our_result == best_so_far: best_moves.append(move) if not best_moves: return Move.pass_turn() return random.choice(best_moves)
def select_move(self, game_state): """Choose a random valid move that preserves our own eyes.""" candidates = [] for r in range(1, game_state.board.num_rows + 1): for c in range(1, game_state.board.num_cols + 1): candidate = Point(row=r, col=c) print("kkk", candidate.row, candidate.col) if game_state.is_valid_move(Move.play(candidate)) and \ not is_point_an_eye(game_state.board, candidate, game_state.next_player): candidates.append(candidate) if not candidates: return Move.pass_turn() return Move.play(random.choice(candidates)) # end::random_bot[]
def game(self) -> GameState: if not self._game: black = batch_translate_labels_to_coordinates(self.initial_black) white = batch_translate_labels_to_coordinates(self.initial_white) move_points = batch_translate_labels_to_coordinates(self.moves) player = Player.black if self.initial_player == 'b' else Player.white board = Board(19, 19) for b in black: board.place_stone(Player.black, b) for w in white: board.place_stone(Player.white, w) self._game = GameState(board, player, None, None) for move_point in move_points: move = Move.pass_turn() if not move_point else Move.play( move_point) self._game = self._game.apply_move(move) return self._game
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) # <1> shape = self.encoder.shape() # <2> 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') sgf_content = zip_file.extractfile(name).read() sgf = Sgf_game.from_string(sgf_content) # <3> game_state, first_move_done = self.get_handicap(sgf) # <4> for item in sgf.main_sequence_iter(): # <5> color, move_tuple = item.get_move() point = None if color is not None: if move_tuple is not None: # <6> row, col = move_tuple point = Point(row + 1, col + 1) move = Move.play(point) else: move = Move.pass_turn() # <7> if first_move_done and point is not None: features[counter] = self.encoder.encode( game_state) # <8> labels[counter] = self.encoder.encode_point( point) # <9> counter += 1 game_state = game_state.apply_move(move) # <10> first_move_done = True # <1> Determine the total number of moves in all games in this zip file. # <2> Infer the shape of features and labels from the encoder we use. # <3> Read the SGF content as string, after extracting the zip file. # <4> Infer the initial game state by applying all handicap stones. # <5> Iterate over all moves in the SGF file. # <6> Read the coordinates of the stone to be played... # <7> ... or pass, if there is none. # <8> We encode the current game state as features... # <9> ... and the next move as label for the features. # <10> Afterwards the move is applied to the board and we proceed with the next one. # end::read_sgf_files[] # tag::store_features_and_labels[] feature_file_base = self.data_dir + '/' + data_file_name + '_features_%d' label_file_base = self.data_dir + '/' + data_file_name + '_labels_%d' chunk = 0 # Due to files with large content, split up after chunksize chunksize = 1024 while features.shape[0] >= chunksize: # <1> 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:] # <2> np.save(feature_file, current_features) np.save(label_file, current_labels) # <3>
def process_zip(self, zip_file_name, data_file_name, game_list): """ .tar.gzファイルを解凍し, 必要なゲームだけ特徴量とラベルに変換して任意の名前で保存 1024の着手データごとに一つのファイルに保存する これにより,動的ロードによるメモリの節約ができる Parameters ---------- zip_file_name : str 解凍対象となるファイルパス data_file_name : str 特徴量とラベルの保存先パス game_list : 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, total_examples) features = np.zeros(feature_shape) labels = np.zeros((total_examples, )) # 必要な全てのゲームインデックスのゲームを再生しながら記録していく counter = 0 # 着手数 for index in game_list: # 対象となるsgfファイルの棋譜データを読み込み name = name_list[index + 1] if not name.endswith('.sgf'): raise ValueError(name + ' is not a valid sgf') # メンバーをファイルオブジェクトとして抽出 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() # 着手 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: # 現在の盤面を特徴量として, 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_sizeで区切って保存 chunk = 0 chunk_size = 1024 while features.shape[0] >= chunk_size: feature_file = feature_file_base % chunk label_file = label_file_base % chunk chunk += 1 # chunk_sizeでfeaturesとlabelsを区切っていく current_features, features = features[:chunk_size], features[ chunk_size:] current_labels, labels = labels[:chunk_size], labels[chunk_size:] # 区切ったfeaturesとlabelsを保存 np.save(feature_file, current_features) np.save(label_file, current_labels)
def process_zip(self, zip_file_name, data_file_name, game_list): feature_file_base = self.data_dir + '/' + data_file_name + '_features_%d' label_file_base = self.data_dir + '/' + data_file_name + '_labels_%d' print("processing {}...".format(data_file_name)) 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') sgf_content = zip_file.extractfile(name).read() sgf = SgfGame.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 chunk = 0 chunksize = 1024 # Does not do what author thinks it does -- truncates data # 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) # fixed code: while features.shape[0] > 0: 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) print('wrote {}'.format(feature_file)) np.save(label_file, current_labels) print('wrote {}'.format(label_file)) # allow garbage collection features = None labels = None current_features = None current_labels = None
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() # このzipファイル内の全てのゲームの合計着手回数を決定する total_examples = self.num_total_examples(zip_file, game_list, name_list) # <1> # 使用するエンコーダからのフィーちゃとラベルの形状を推測する shape = self.encoder.shape() # <2> 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') sgf_content = zip_file.extractfile(name).read() # zipファイルを解凍した後、SGFの内容を文字列として読み込む sgf = Sgf_game.from_string(sgf_content) # <3> # すべての置石を適用して、初期のゲーム状態を推測する game_state, first_move_done = self.get_handicap(sgf) # <4> # SGFファイル内のすべての着手を繰り返す for item in sgf.main_sequence_iter(): # <5> color, move_tuple = item.get_move() point = None if color is not None: # 着手する石の座標を読み込み if move_tuple is not None: # <6> row, col = move_tuple point = Point(row + 1, col + 1) move = Move.play(point) else: # ない場合はパス move = Move.pass_turn() # <7> if first_move_done and point is not None: # 現在のゲームの状態を特徴量としてエンコード features[counter] = self.encoder.encode( game_state) # <8> # 次の着手を特徴量に対するラベルとしてエンコードする labels[counter] = self.encoder.encode_point( point) # <9> counter += 1 # その後、着手を盤に適用し、次に進む game_state = game_state.apply_move(move) # <10> first_move_done = True # <1> Determine the total number of moves in all games in this zip file. # <2> Infer the shape of features and labels from the encoder we use. # <3> Read the SGF content as string, after extracting the zip file. # <4> Infer the initial game state by applying all handicap stones. # <5> Iterate over all moves in the SGF file. # <6> Read the coordinates of the stone to be played... # <7> ... or pass, if there is none. # <8> We encode the current game state as features... # <9> ... and the next move as label for the features. # <10> Afterwards the move is applied to the board and we proceed with the next one. # end::read_sgf_files[] # tag::store_features_and_labels[] # 特徴量とラベルを小さなチャンクとしてローカルに保持する # 小さなチャンクを格納する理由は、データの配列が非常に高速になり、後でより柔軟な小さなファイルにデータを格納できるため。 feature_file_base = self.data_dir + '/' + data_file_name + '_features_%d' label_file_base = self.data_dir + '/' + data_file_name + '_labels_%d' chunk = 0 # Due to files with large content, split up after chunksize chunksize = 1024 # 特徴量とラベルを1024のサイズのチャンクで処理する while features.shape[0] >= chunksize: # <1> 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:] # <2> np.save(feature_file, current_features) # 別々のファイルに保存される np.save(label_file, current_labels) # <3>
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 board = Board(19, 19) #Nail board_ext = Board_Ext(board) # Nail for index in game_list: name = name_list[index + 1] if not name.endswith('.sgf'): raise ValueError(name + ' is not a valid sgf') sgf_content = zip_file.extractfile(name).read() sgf = Sgf_game.from_string(sgf_content) game_state, first_move_done, board_ext = self.get_handicap(sgf) # if first_move_done : # Nail ignore handicap # continue # Ignore games with handicap if self.encoder.name( )[:2] == 'my' and first_move_done == False: # Not handicap board_ext = Board_Ext(game_state.board) #inserted Nail 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: encode = True # # Data only for debute Nail # if self.count_stones_debute is not None and \ # self.count_stones_middle is None and \ # self.count_stones_end is None and \ # board_ext.count_stones() > self.count_stones_debute: # encode = False # # Data for middle game Nail # if self.count_stones_debute is not None and \ # self.count_stones_middle is not None and \ # self.count_stones_end is None and \ # self.board_ext.count_stones() <= self.count_stones_debute and board_ext.count_stones() > self.count_stones_middle: # encode = False # # # Data for end # if self.count_stones_middle is not None and \ # self.count_stones_end is not None and \ # self.board_ext.count_stones() <= self.count_stones_middle and board_ext.count_stones() > self.count_stones_end: # encode = False if encode == True: #Nail if self.encoder.name()[:2] == 'my': features[counter] = self.encoder.encode( game_state, board_ext) #Nail else: features[counter] = self.encoder.encode( game_state) labels[counter] = self.encoder.encode_point(point) counter += 1 game_state = game_state.apply_move(move) if self.encoder.name()[:2] == 'my': board_ext.place_stone_ext(game_state.board, color, point) # Inserted Nail # Nail 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 # Due to files with large content, split up after chunksize chunksize = 1024 start_time_all = time.time() while features.shape[0] >= chunksize: start_time = time.time() 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) # Inserted Nail print("Chunk = ", chunk, " File for training Current_features: ", feature_file) print("Time per one file = ", (time.time() - start_time_all) / 1000, ' seconds') print('Files preparation with proccess_zip is over\n') print('Full Time = ', (time.time() - start_time_all) / 1000, ' seconds') print("End chunk = ", chunk)
def select_move(self, game_state): candidates = legal_moves(game_state) if not candidates: return Move.pass_turn() return random.choice(candidates)
def process_zip(self, zip_file_name, data_file_name, game_list): # total number of moves in all games in zip file 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) # infers shape of features and labels from the encoder shape = self.encoder.shape() # <2> 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: # reads the SGF contents as a string name = name_list[index + 1] if not name.endswith('.sgf'): raise ValueError(name + ' is not a valid sgf') sgf_content = zip_file.extractfile(name).read() sgf = SgfGame.from_string(sgf_content) # apply handicap stones game_state, first_move_done = self.get_handicap(sgf) # iterates through all moves for item in sgf.main_sequence_iter(): color, move_tuple = item.get_move() point = None if color is not None: # read the coordinate of the stone to be played if move_tuple is not None: row, col = move_tuple point = Point(row + 1, col + 1) move = Move.play(point) else: # or do nothing move = Move.pass_turn() if first_move_done and point is not None: # Encode the current games state as features features[counter] = self.encoder.encode(game_state) # Encode the next move as label labels[counter] = self.encoder.encode_point(point) counter += 1 # Apply the move and move on to the next one. game_state = game_state.apply_move(move) first_move_done = True # Finish implementation of process_zip feature_file_base = self.data_dir + '/' + data_file_name + '_features_%d' label_file_base = self.data_dir + '/' + data_file_name + '_labels_%d' chunk = 0 # Due to files with large content, split up after chunksize chunksize = 1024 # author's code which doesn't do what he thinks it does # # Process features and labels in chunks of 1024 # while features.shape[0] >= chunksize: # feature_file = feature_file_base % chunk # label_file = label_file_base % chunk # chunk += 1 # # break up chunk into another piece # current_features, features = features[:chunksize], features[chunksize:] # current_labels, labels = labels[:chunksize], labels[chunksize:] # # store into a separate file # np.save(feature_file, current_features) # np.save(label_file, current_labels) # fixed code: while features.shape[0] > 0: 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 process_zip(self, zip_file_name, data_file_name, game_list): # total number of moves in all games in zip file 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) new_game_list = game_list.copy() shape = self.encoder.shape() # Changed code to prevent too big features in memory # Finish implementation of process_zip feature_file_base = self.data_dir + '/' + data_file_name + '_features_%d' label_file_base = self.data_dir + '/' + data_file_name + '_labels_%d' chunk = 0 examples_used = 1024 iters = math.ceil(total_examples / examples_used) for z in range(iters): # <2> #feature_shape = np.insert(shape, 0, np.asarray([examples_used])) # features = np.zeros(feature_shape) # labels = np.zeros((examples_used,)) # counter = 0 for index in new_game_list[:examples_used]: features = [] labels = [] # reads the SGF contents as a string name = name_list[index + 1] if not name.endswith('.sgf'): raise ValueError(name + ' is not a valid sgf') sgf_content = zip_file.extractfile(name).read() sgf = SgfGame.from_string(sgf_content) # apply handicap stones game_state, first_move_done = self.get_handicap(sgf) # iterates through all moves for item in sgf.main_sequence_iter(): z = np.zeros(shape) color, move_tuple = item.get_move() point = None if color is not None: # read the coordinate of the stone to be played if move_tuple is not None: row, col = move_tuple point = Point(row + 1, col + 1) move = Move.play(point) else: # or do nothing move = Move.pass_turn() if first_move_done and point is not None: # Encode the current games state as features # features[counter] = self.encoder.encode(game_state) z = self.encoder.encode(game_state) features.append(z) # Encode the next move as label # labels[counter] = self.encoder.encode_point(point) labels.append(self.encoder.encode_point(point)) # counter += 1 # Apply the move and move on to the next one. game_state = game_state.apply_move(move) first_move_done = True new_game_list = new_game_list[examples_used:] feature_file = feature_file_base % chunk label_file = label_file_base % chunk chunk += 1 # current_features, features = features[:examples_used], features[examples_used:] # current_labels, labels = labels[:examples_used], labels[examples_used:] # np.save(feature_file, current_features) # np.save(label_file, current_labels) features = np.array(features) labels = np.array(labels) np.save(feature_file, features) np.save(label_file, labels) # """