def select_move(bot_name): content = request.json board_size = content['board_size'] game_state = goboard.GameState.new_game(board_size) # replay the game up to this point. for move in content['moves']: if move == 'pass': next_move = goboard.Move.pass_turn() elif move == 'resign': next_move = goboard.Move.resign() else: next_move = goboard.Move.play(point_from_coords(move)) game_state = game_state.apply_move(next_move) bot_agent = bot_map[bot_name] bot_move = bot_agent.select_move(game_state) if bot_move.is_pass: bot_move_str = 'pass' elif bot_move.is_resign: bot_move_str = 'resign' else: bot_move_str = coords_from_point(bot_move.point) return jsonify({ 'bot_move': bot_move_str, 'diagnostics': bot_agent.diagnostics() })
def analyze(self, position_json): data = Position.from_json(position_json) game = data.game command, orientation = data.command() if command.id not in self.query_to_positions: commands: List[Command] = [command] transformation = get_transformation(orientation) package = {} self.query_to_positions[command.id] = package for move in game.legal_moves(): if move.is_resign: continue c, _ = data.command(move) commands.append(c) # NOTE: The game is in the orientation in which the server received the position. All the analysis is # being done from the canonical representation's orientation. That means we need to transform the legal # move before storing it in the package if we are to be able to correctly restore the analysis later! if move.is_pass: move_label = 'pass' else: move_label = coords_from_point(transformation(move.point)) package[move_label] = c.id self._write_commands(commands) return f'{command.id}_{orientation}'
def fmt(x): if x is Player.black: return 'B' if x is Player.white: return 'W' if x.is_pass: return 'pass' if x.is_resign: return 'resign' return coords_from_point(x.point)
def select_move(bot_name): content = request.json board_size = content['board_size'] game_state = goboard.GameState.new_game(board_size) board_ext = goboard.Board_Ext(game_state.board) #Nail # Replay the game up to this point. for move in content['moves']: if move == 'pass': next_move = goboard.Move.pass_turn() elif move == 'resign': next_move = goboard.Move.resign() else: pm = point_from_coords(move) next_move = goboard.Move.play(pm) game_state = game_state.apply_move(next_move) p = next_move.point # Nail #board_ext.place_stone_ext(game_state.board, game_state.next_player.other.name[0], p) #Nail bot_agent = bot_map[bot_name] bot_move = bot_agent.select_move(game_state) #,board_ext) # Nail if bot_move.is_pass: bot_move_str = 'pass' elif bot_move.is_resign: bot_move_str = 'resign' else: bot_move_str = coords_from_point(bot_move.point) result_scoring, territory_black, territory_white = gr(game_state) # Nail winner = result_scoring.winner.name if winner == 'white': winner = 'Белые' else: winner = 'Черные' score = str(result_scoring.winning_margin) result_scoring = result_scoring.winner.name + ' : ' + str(result_scoring.winning_margin) print(' Current Result = ', result_scoring, ' Bot_move = ', bot_move_str) #Nail print('territory_black=', territory_black, ' territory_white=', territory_white) return jsonify({ 'score': score, 'winner': winner, 'territory_black': territory_black, 'territory_white': territory_white, 'bot_move': bot_move_str, 'diagnostics': bot_agent.diagnostics() })
def command(self, move: Move = None) -> Tuple[Command, int]: # Get the game that reflects the passed move having been played (if supplied). game = self.game if not move else self.game.apply_move(move) # Process the game board to get the necessary information to generate canonical encodings. point_plus_code: List[Tuple[Point, int]] = [] for i in intersections: color = game.board.get(i) if not color: code = 0 if game.is_valid_move(Move.play(i)) else 3 else: code = 1 if color == Player.black else 2 if code: point_plus_code.append((i, code)) # Select the transformation that leads to the lowest canonical position representation. selected_form = float('inf') selected_ordinal = -1 selected_transformation = None for ordinal, transformation in enumerate(transformations): encoding = self._encode_point_colorings(point_plus_code, transformation) if encoding < selected_form: selected_form = encoding selected_ordinal = ordinal selected_transformation = transformation # Encode the resulting board position as a string. position_representation = self._convert_code_to_dense_string( selected_form) # Transform the starting stone points using the selected transformation. initial_positions_plus_colors: List[Tuple[Point, int]] = [] initial_stones: List[Move] = [] if self.initial_black: transformed_black_points = [ selected_transformation(translate_label_to_point(x)) for x in self.initial_black ] initial_positions_plus_colors += [ (x, 1) for x in transformed_black_points ] initial_stones += [ MoveInfo(KataGoPlayer.b, coords_from_point(x)) for x in transformed_black_points ] if self.initial_white: transformed_white_points = [ selected_transformation(translate_label_to_point(x)) for x in self.initial_white ] initial_positions_plus_colors += [ (x, 2) for x in transformed_white_points ] initial_stones += [ MoveInfo(KataGoPlayer.w, coords_from_point(x)) for x in transformed_white_points ] initial_form = self._encode_point_colorings( initial_positions_plus_colors) initial_representation = self._convert_code_to_dense_string( initial_form) # Compose an ID to use when communicating with KataGo. Because it is possible to arrive at the same position # in multiple paths and/or transformations, this ID does NOT contain the information necessary to return to the # original representation. That exists for communicating between the UI and the server ONLY. next_player = "b" if game.next_player == Player.black else "w" id = f'{self.ruleset}_{self.komi}_{next_player}_{initial_representation}_{position_representation}' # Build the command! command = Command() command.id = id command.komi = self.komi command.initialPlayer = KataGoPlayer.b if self.initial_player == 'b' else KataGoPlayer.w command.rules = self.ruleset command.initialStones = initial_stones command.moves = [] player = command.initialPlayer for move in game.history: move_info = MoveInfo( player, 'pass' if not move or move.is_pass else coords_from_point( selected_transformation(move.point))) command.moves.append(move_info) player = player.opposite command.analyzeTurns = [len(command.moves)] return command, selected_ordinal
def point_to_label(point: Optional[Point]) -> str: return 'pass' if not point else coords_from_point(point)