class DotsAndBoxesAgent: """ A DotsAndBoxesAgent object should implement the following methods: - __init__ - add_player - register_action - next_action - end_game This class does not necessarily use the best data structures for the approach you want to use. """ def __init__(self, player, nb_rows, nb_cols, timelimit): """Create Dots and Boxes agent. :param player: Player number, 1 or 2 :param nb_rows: Rows in grid :param nb_cols: Columns in grid :param timelimit: Maximum time allowed to send a next action. """ self.player = {player} self.timelimit = timelimit self.ended = False self.board = Board(nb_rows, nb_cols) self.times_for_move = [] def add_player(self, player): """Use the same agent for multiple players.""" self.player.add(player) def register_action(self, row, column, orientation, player): """ Register action played in game. :param row: :param columns: :param orientation: "v" or "h" :param player: 1 or 2 """ self.board.fill_line(row, column, orientation, player) def next_action(self): """Return the next action this agent wants to perform. :return: (row, column, orientation) """ logger.info("Computing next move (grid={}x{}, player={})"\ .format(self.board.nb_rows, self.board.nb_cols, self.player)) start_time = time.time() free_lines = self.board.free_lines() if len(free_lines) == 0: # Board full return None # Random move movei = random.randint(0, len(free_lines) - 1) r, c, o = free_lines[movei] elapsed_time = time.time() - start_time self.times_for_move.append(elapsed_time) return r, c, o def end_game(self): time = 0 for t in self.times_for_move: time += t print("avg time v1 =", int(time) / len(self.times_for_move)) self.ended = True
class DotsAndBoxesAgent: """ A DotsAndBoxesAgent object should implement the following methods: - __init__ - add_player - register_action - next_action - end_game This class does not necessarily use the best data structures for the approach you want to use. """ def __init__(self, player, nb_rows, nb_cols, timelimit): """Create Dots and Boxes agent. :param player: Player number, 1 or 2 :param nb_rows: Rows in grid :param nb_cols: Columns in grid :param timelimit: Maximum time allowed to send a next action. """ self.player = {player} self.timelimit = timelimit self.ended = False self.tree = MonteCarloSearchTree(nb_rows, nb_cols) self.nodes = self.tree.tree['nodes'] self.board = Board(nb_rows, nb_cols) def add_player(self, player): """Use the same agent for multiple players.""" self.player.add(player) def register_action(self, row, column, orientation, player): """ Register action played in game. :param row: :param columns: :param orientation: "v" or "h" :param player: 1 or 2 """ node = self.tree.fill_line( self.nodes, str(row) + "," + str(column) + "," + str(orientation)) if node != False: self.nodes = node['children'] self.board.fill_line(row, column, orientation, player) visited_lines = [] count_chains = self.board.count_chains_v2() def next_action(self): """Return the next action this agent wants to perform. :return: (row, column, orientation) """ logger.info("Computing next move (grid={}x{}, player={})"\ .format(self.board.nb_rows, self.board.nb_cols, self.player)) free_lines = self.board.free_lines() used_lines = self.board.used_lines() if len(free_lines) == 0: # Board full return None s = self.tree.get_best_move(self.nodes) if not isinstance(s, str): # Random move movei = random.randint(0, len(free_lines) - 1) r, c, o = free_lines[movei] print("RANDOM MOVE MCTS") return r, c, o else: print("MCTS tree.data MOVE") print(type(s)) r, c, o = s.split(",") print(r, c, o) return r, c, o def end_game(self): self.ended = True