def test_get_coalescer(self): component = object() coalescer = lambda: None uut = Node(component, coalescer) self.assertIs(coalescer, uut.get_coalescer())
def solve(self): start_time = time() root = Node(state=self._start_board) self._frontier.append(root) if root.state.string == self._goal: self._search_depth = root.depth self._running_time = time() - start_time return root while True: if len(self._frontier) == 0: self._running_time = time() - start_time raise ValueError('Goal not found.') node = self._frontier.pop() self._explored.add(node.state.string) if node.state.string == self._goal: self.update_fringe_size() self._search_depth = node.depth self._running_time = time() - start_time return node self._nodes_expanded += 1 actions = node.state.actions for action in list(reversed(actions)): state = node.state.act(action) child = Node(state=state, action=action, path_cost=1, parent=node) if child.depth > self._max_search_depth: self._max_search_depth = child.depth if child.state.string not in self._explored: self._frontier.append(child) self._explored.add(child.state.string) self.update_fringe_size()
def test_update(self): game = TestGame() node = Node(game) node.update(10) self.assertEqual(node.visits_count, 1) self.assertEqual(node.cumulative_score, 10)
def test_get_expected_success_rate(self): game = TestGame() node = Node(game) node.cumulative_score = 7 node.visits_count = 2 self.assertEqual(node.get_expected_success_rate(), 2)
def main(args): node = Node() if args.verbose is True: node.log() node.setup(args.host_port, host_IP=args.host_ip) # Continuous loop asking for user input or to quit program while True: print_menu() choice = input("Enter your choice [1-5]: ") if choice=='1': print("Getting Peers...") print(node.get_peers()) elif choice=='2': file_path = input('Enter the path to the file: ') set_file(file_path,node) print('File set!') elif choice=='3': file_name = input('Enter the file name: ') get_file(file_name,node) print('Got file!') elif choice=='4': # Gets the master_key from DHT to list all the files set to DHT print(node.get_file("master_key")) elif choice=='5': node.kill_thread() print("Thanks for joining us!") sys.exit() break else: print("Wrong option selection. Please try again...")
def test_node(): n1 = Node(3) assert n1.val == 3 assert n1.nxt is None n2 = Node(5, Node(7)) assert n2.val == 5 assert n2.nxt is not None
def load_from_json(self, file_name: str) -> bool: """ Loads a graph from a json file. @param file_name: The path to the json file @returns True if the loading was successful, False o.w. """ load_graph = DiGraph() try: with open(file_name, 'r') as f: dict_algo = json.load(f) nodes = dict_algo["Nodes"] if isinstance(nodes, list): for i in nodes: n = Node(**i) load_graph.add_node(n.id, n.pos) edges = dict_algo["Edges"] for i in edges: load_graph.add_edge(id1=i['src'], id2=i['dest'], weight=i['w']) elif isinstance(nodes, dict): for k, v in nodes.items(): n = Node(**v) load_graph.add_node(n.id, n.pos) edges = dict_algo["Edges"] for k, v in edges.items(): for i in v.keys(): load_graph.add_edge(int(k), int(i), float(v.get(i))) self.graph = load_graph except IOError as e: print(e) return False return True
def get_cpu_stats(self, cluster_id): available_nodes = [Node('localhost'), Node('10.30.0.20')] stats_dict = {} stats_lines = [] #GETTING DOCKER CPU STATS FROM ALL INSTANCES IN ALL NODES for node in available_nodes: if node.get_ip() != "localhost": url = 'http://' + node.get_ip( ) + ":5001/cpu_stats/" + cluster_id node_stats_table = urllib2.urlopen(url).read() node_stats_lines = node_stats_table.split('\n') stats_dict.update(stats_string_to_dict(node_stats_lines)) else: node_stats_table = docker.stats_cpu() node_stats_lines = node_stats_table.split('\n') #TURNING STATS STRING LINES INTO {INSTANCE_ID -> CPU_STAT} DICTIONARY all_stats_dict = stats_string_to_dict(node_stats_lines) ancestor_image_instances_ids = docker.get_instance_ids_by_id( cluster_id) cluster_instances_ids = [] for instance in ancestor_image_instances_ids: print docker.get_image(instance) + "vs" + cluster_id if docker.get_image(instance).strip('\n').strip( '"') == cluster_id: cluster_instances_ids.append(instance) print "cluster_instaces_ids found for id " + cluster_id + " were " + str( cluster_instances_ids) #REMOVING STATS FROM INSTANCES THAT ARE NOT FROM THE DESIRED CLUSTER for key in all_stats_dict: if key in cluster_instances_ids: stats_dict[key] = all_stats_dict[key] return stats_dict
def setUp(self): # States and Actions self.action_1 = Place(coord=(0,0), piece=Piece.BLACK_FLAT) self.action_2 = Place(coord=(1,0), piece=Piece.BLACK_FLAT) self.action_3 = Place(coord=(2,0), piece=Piece.BLACK_FLAT) # Create Tree self.root_node = Node(None, get_default_state(Color.BLACK), None) self.child_1 = self.root_node.add_child( self.action_1, get_next_state(get_default_state(Color.BLACK), self.action_1) ) self.child_2 = self.root_node.add_child( self.action_2, get_next_state(get_default_state(Color.BLACK), self.action_2) ) self.child_3 = self.root_node.add_child( self.action_3, get_next_state(get_default_state(Color.BLACK), self.action_3) ) # Set Wins and Visits self.root_node._wins = 5 self.root_node._visits = 10 self.child_1._wins = 0 self.child_1._visits = 3 self.child_2._wins = 2 self.child_2._visits = 3 self.child_3._wins = 3 self.child_3._visits = 4
def bfs(board, src, dest): """ Find shortest path to src to dest :param board: :param src: :param dest: :return: """ visited = np.full((board.rows, board.cols), False, dtype=bool) visited[src.row][src.col] = True queue = deque() queue.append(Node(row=src.row, col=src.col)) matrix = board.map while queue: node = queue.popleft() if node.row == dest.row and node.col == dest.col: return node.dist, node.get_path() for i in range(4): row = node.row + ROW_NUM[i] col = node.col + COL_NUM[i] if is_valid(row, col, board.rows, board.cols) and matrix[row][col] not in [ 1, 2 ] and not visited[row][col]: visited[row][col] = True queue.append( Node(row=row, col=col, dist=node.dist + 1, parent=node)) return -1, None
def test_calc_value(create_board, state, expected): node = Node(create_board(state), prev_piece='X', next_piece='O') if not node.is_terminal(): assert pytest.raises(AssertionError) else: node.calc_value(True, 0) assert node.value == expected
def run(self): # parameters Sim.scheduler.reset() Sim.set_debug(True) # setup network n1 = Node() n2 = Node() l = Link(address=1,startpoint=n1,endpoint=n2,queue_size=self.queue_size,bandwidth=10000000,propagation=0.01,loss=self.loss, printOut=True) n1.add_link(l) n1.add_forwarding_entry(address=2,link=l) l = Link(address=2,startpoint=n2,endpoint=n1,queue_size=self.queue_size,bandwidth=10000000,propagation=0.01,loss=self.loss) n2.add_link(l) n2.add_forwarding_entry(address=1,link=l) # setup transport t1 = Transport(n1) t2 = Transport(n2) # setup application a = AppHandler("2_1-" + self.filename) # setup connection c1 = My_RTP(t1,1,1,2,1,a) c2 = My_RTP(t2,2,1,1,1,a) # setup application a = AppHandler("2_2-" + self.filename) # setup connection c3 = My_RTP(t1,1,2,2,2,a) c4 = My_RTP(t2,2,2,1,2,a) # send a file with open(self.filename,'r') as f: while True: data = f.read(1000) if not data: break c1.load_buffer(data) c3.load_buffer(data) c1.set_file_prefix("2_1") c2.set_file_prefix("2_1") c3.set_file_prefix("2_2") c4.set_file_prefix("2_2") c1.open_window_file() c3.open_window_file() Sim.scheduler.add(delay=0, event="window_init", handler=c1.window_init) Sim.scheduler.add(delay=0, event="window_init", handler=c3.window_init) # run the simulation Sim.scheduler.run() n1.links[0].myfile.close() c1.close_window_file() c3.close_window_file() Sim.close_rate_file()
def push(self, value): if self.has_space(): item = Node(value) item.set_next_node(self.top_item) self.top_item = item self.size += 1 else: print("No more room!")
def test_create_child(self): game = TestGame() node = Node(game) node.remaining_moves = [None] child = node.create_child(game, None) self.assertEqual(node.children, [child]) self.assertEqual(len(node.remaining_moves), 0)
def test_has_children(self): game = TestGame() node = Node(game) self.assertFalse(node.has_children()) node.children = [None] self.assertTrue(node.has_children())
def prepend(self, val): self.size += 1 if self.is_empty(): node = Node(val) self.head = node self.tail = node else: node = Node(val, self.head) self.head = node
def generateBinaryTree(): root = Node(10) root.left = Node(6) root.right = Node(15) root.left.left = Node(5) root.left.right = Node(7) root.right.left = Node(12) root.right.right = Node(18) return root
def append(self, val): self.size += 1 if self.is_empty(): node = Node(val) self.head = node self.tail = node else: self.tail.nxt = Node(val) self.tail = self.tail.nxt
def test_find(self): # поиск в непересекающихся интервалах ints1 = [Interval(0, 2, 0), Interval(3, 4, 0), Interval(5, 6, 0)] node1 = Node(ints1) # покрываемая интервалами точка self.assertEqual(node1.find(3), [ Interval(3, 4, 0), ]) # не покрываемая интервалами точка self.assertEqual(node1.find(12), []) # поиск в пересекающихся интервалах ints2 = [ Interval(0, 21, 0), Interval(1, 3, 0), Interval(10, 15, 0), Interval(12, 17, 0) ] node2 = Node(ints2) # точка находится в нескольких интервалах self.assertEqual( node2.find(10), [Interval(0, 21, 0), Interval(10, 15, 0)]) # точка лежит ровно в одном интервале self.assertEqual(node2.find(18), [ Interval(0, 21, 0), ]) # точка не лежит ни в одном интервале self.assertEqual(node2.find(-6), [])
def test_update_uct_score(self): game = TestGame() parent = Node(game) parent.visits_count = 1 node = Node(game, parent=parent) node.cumulative_score = 1 node.visits_count = 1 node.update_uct_score() self.assertEqual(node.uct_score, 1)
def test_puct_root_node(self): np.random.seed(1) puct = PUCT(0.8, 0.2, 1) game = Game() parent_node = Node(game) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[0])), 0.14285715, 35)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[1])), 0.14285715, 36)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[2])), 0.14285715, 37)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[3])), 0.14285715, 38)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[4])), 0.14285715, 39)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[5])), 0.14285715, 40)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[6])), 0.14285715, 41)) simulation_edge = puct.puct(parent_node, is_root=True) self.assertEquals(simulation_edge.action, 35)
def test_puct_non_root_node(self): np.random.seed(1) puct = PUCT(0.8, 0.2, 1) game = Game() parent_node = Node(game) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[0])), 0.14805108, 29)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[1])), 0.14307857, 35)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[2])), 0.14475949, 37)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[3])), 0.1387326, 38)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[4])), 0.14208362, 39)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[5])), 0.14188258, 40)) parent_node.edges.append( Edge(parent_node, Node(game.move(game.get_possible_moves()[6])), 0.14141211, 41)) simulation_edge = puct.puct(parent_node, is_root=False) self.assertEquals(simulation_edge.action, 29)
def attack_defense_create(self, data, requirements): for device_name in data['resources']: if data['resources'][device_name]['type'] == 'node': service_file_created = False for team_name, team_data in self.get_teams( data ): # Is team_data needed? Maybe remove? dont need it node = Node(data['resources'], team_name, self.template, device_name, service_file_created, requirements) self.metadata['nodes'].append( str(team_name + '_' + device_name)) service_file_created = True requirements = node.get_requirements() self.write_output(requirements, 'requirements.yaml')
def build_mcts(self, state): self.root = Node(state) self.mcts = MCTS(self.root, self.model, self.state_encoder, self.action_encoder, config=self.config)
def compute_node_properties(self, network): """ Args: network (networkx.DiGraph()) -- A weighted, directed networkx DiGraph Returns: self.nodes (list) -- A list of Node objects where """ self.nodes = [] for node in network.nodes(): _node = Node(str(node)) _node.out_degree = network.out_degree(node, weight='weight') _node.in_degree = network.in_degree(node, weight='weight') self.nodes.append(_node)
def process_src(name_of_program, set_of_config, set_of_instructions): decompiler_data = DecompilerData() process_config(set_of_config, name_of_program) process_kernel_params(set_of_instructions) last_node = Node([""], decompiler_data.initial_state) curr_node = last_node last_node_state = decompiler_data.initial_state decompiler_data.cfg = last_node num = 0 while num < len(set_of_instructions): result_for_check = process_single_instruction(set_of_instructions, num, curr_node, last_node_state, last_node) if result_for_check is not None: num, curr_node, set_of_instructions, last_node, last_node_state = result_for_check else: return check_for_use_new_version() remove_unusable_versions() if decompiler_data.checked_variables != {} or decompiler_data.variables != {}: change_values() make_region_graph_from_cfg() process_region_graph() create_opencl_body()
def test_evaluate_leaf(self): game_root = Game() root = Node(game_root) model = MagicMock() prediction = [ np.array([[0.25]]), np.reshape(np.arange(0.001, 0.897, step=0.001), newshape=(1, 896)) ] model.predict.return_value = prediction action_encoder = ActionEncoder(DirectionResolver()) mcts = MCTS(root, config={ 'ALPHA': 0.8, 'CPUCT': 1, 'EPSILON': 0.2 }, model=model, state_encoder=StateEncoder(), action_encoder=action_encoder) _, probs, _ = mcts.predict_state_value(game_root) value = mcts.evaluate_leaf(root) self.assertEqual(value, 0.25) self.assertEqual(len(root.edges), 7) self.assertEqual(root.edges[0].action, 8) self.assertEqual(root.edges[0].stats['P'], probs[8]) self.assertEqual(root.edges[1].action, 104) self.assertEqual(root.edges[1].stats['P'], probs[104])
def test_predict(self): game_root = Game() root = Node(game_root) model = MagicMock() prediction = [ np.array([[0.25]]), np.reshape(np.arange(0.001, 0.897, step=0.001), newshape=(1, 896)) ] model.predict.return_value = prediction action_encoder = ActionEncoder(DirectionResolver()) mcts = MCTS(root, config={ 'ALPHA': 0.8, 'CPUCT': 1, 'EPSILON': 0.2 }, model=model, state_encoder=StateEncoder(), action_encoder=action_encoder) value, probs, allowed_actions = mcts.predict_state_value(game_root) self.assertEqual(value, 0.25) self.assertCountEqual( allowed_actions, action_encoder.convert_moves_to_action_ids( game_root.get_possible_moves_from_current_player_perspective()) ) for idx, prob in enumerate(probs): if idx in allowed_actions: self.assertTrue(prob > 0.01) else: self.assertTrue(prob < np.exp(-40))
def __init__(self, initial_board_state: list, heuristic: IHeuristics): self._current_node = None self._open_list = [] + [ Node(initial_board_state, initial_board_state.index(0), None, None) ] self._closed_list = {} self._heuristic = heuristic
def monte_carlo_tree_search(start_state, max_iterations_count=10000): root_node = Node(start_state) for _ in range(max_iterations_count): game = start_state.copy() node = root_node while node.has_children() and not node.has_remaining_moves(): node = node.select_child() game.apply_move(node.move) if not game.is_finished() and node.has_remaining_moves(): move = node.remaining_moves[randrange(len(node.remaining_moves))] game.apply_move(move) node = node.create_child(game, move) while not game.is_finished(): game.make_random_move() while node.parent: node.update(game.get_score(node.parent.player_to_move)) node = node.parent root_node.visits_count += 1 child = max(root_node.children, key=lambda child: child.get_expected_success_rate()) return child.move
def test_instance(self): component = object() coalescer = lambda: None uut = Node(component, coalescer) self.assertIsNotNone(uut)
def compute_node_properties(self, G): """ Parameters ---------- G: A networkx.DiGraph() object Returns ------- self.nodes: A list of Node objects where (list) """ self.nodes = [] for node in G.nodes(): _node = Node(str(node)) _node.out_degree = G.out_degree(node,weight='weight') _node.in_degree = G.in_degree(node,weight='weight') self.nodes.append(_node)
def run(self): # parameters Sim.scheduler.reset() Sim.set_debug(False) # setup network n1 = Node() n2 = Node() l = Link(address=1,startpoint=n1,endpoint=n2,loss=self.loss,bandwidth=100000000,propagation=0.01) if self.experiments: l = Link(address=1,startpoint=n1,endpoint=n2,loss=self.loss,bandwidth=100000000,propagation=0.01, queue_size=100) n1.add_link(l) n1.add_forwarding_entry(address=2,link=l) l = Link(address=2,startpoint=n2,endpoint=n1,loss=self.loss,bandwidth=100000000,propagation=0.01) if self.experiments: l = Link(address=2,startpoint=n2,endpoint=n1,loss=self.loss,bandwidth=100000000,propagation=0.01, queue_size=100) n2.add_link(l) n2.add_forwarding_entry(address=1,link=l) # setup transport t1 = Transport(n1) t2 = Transport(n2) # setup application a = AppHandler(self.filename) # setup connection c1 = ReliableTransport(t1,1,1,2,1,self.window_size,a) c2 = ReliableTransport(t2,2,1,1,1,self.window_size,a) # send a file with open(self.filename,'r') as f: c1.stats.set_size(os.path.getsize(self.filename)) while True: data = f.read(1000) if not data: break Sim.scheduler.add(delay=0, event=data, handler=c1.send) # run the simulation Sim.scheduler.run() print "Average queueing delay =", c1.stats.average() print "Throughput =", c1.stats.throughput(Sim.scheduler.current_time())
def run(self): # parameters Sim.scheduler.reset() Sim.set_debug(True) # setup network n1 = Node() n2 = Node() l = Link(address=1,startpoint=n1,endpoint=n2,loss=self.loss, bandwidth=10000000.0,propagation=0.01,queue_size=self.queue) n1.add_link(l) n1.add_forwarding_entry(address=2,link=l) l = Link(address=2,startpoint=n2,endpoint=n1,loss=self.loss, bandwidth=10000000.0,propagation=0.01,queue_size=self.queue) n2.add_link(l) n2.add_forwarding_entry(address=1,link=l) # setup transport t1 = Transport(n1) t2 = Transport(n2) # setup application a = AppHandler(self.filename) # setup connection c1 = TCP(t1,1,1,2,1,app=a,window=self.window) c2 = TCP(t2,2,1,1,1,app=a,window=self.window) # send a file with open(self.filename,'r') as f: while True: data = f.read(1000) if not data: break Sim.scheduler.add(delay=0, event=data, handler=c1.send) # run the simulation Sim.scheduler.run() print "Total queuing delay: ", a.total_queuing_delay print "Total packets sent: ", a.total_packets_sent
def decide_move(self, board): """ Determines the next move that the player should make. @return: a tuple with the coordinates of the next move. """ self.game_tree = Node(board) self.build_tree(self.game_tree, 0, []) moves = [move for move in self.game_tree.get_board().legal_moves(self.player_row)] values = [node.get_value() for node in self.game_tree.get_children()] return moves[values.index((max(values)))]
def run(self): # parameters Sim.scheduler.reset() Sim.set_debug(True) # setup network n1 = Node() n2 = Node() l = Link(address=1,startpoint=n1,endpoint=n2,queue_size=self.queue_size,bandwidth=10000000,propagation=0.01,loss=self.loss) n1.add_link(l) n1.add_forwarding_entry(address=2,link=l) l = Link(address=2,startpoint=n2,endpoint=n1,queue_size=self.queue_size,bandwidth=10000000,propagation=0.01,loss=self.loss) n2.add_link(l) n2.add_forwarding_entry(address=1,link=l) # setup transport t1 = Transport(n1) t2 = Transport(n2) # setup application a = AppHandler(self.filename) # setup connection c1 = My_RTP(t1,1,1,2,1,a) c2 = My_RTP(t2,2,1,1,1,a) # send a file with open(self.filename,'r') as f: while True: data = f.read(1000) if not data: break c1.load_buffer(data) c1.window_init(self.window_size) # run the simulation Sim.scheduler.run()
def run(self): # parameters Sim.scheduler.reset() Sim.set_debug(True) # setup network n1 = Node() n2 = Node() l = Link(address=1,startpoint=n1,endpoint=n2,loss=self.loss) n1.add_link(l) n1.add_forwarding_entry(address=2,link=l) l = Link(address=2,startpoint=n2,endpoint=n1,loss=self.loss) n2.add_link(l) n2.add_forwarding_entry(address=1,link=l) # setup transport t1 = Transport(n1) t2 = Transport(n2) # setup application a = AppHandler(self.filename) # setup connection c1 = StopAndWait(t1,1,1,2,1,a) c2 = StopAndWait(t2,2,1,1,1,a) # send a file with open(self.filename,'r') as f: while True: data = f.read(1000) if not data: break Sim.scheduler.add(delay=0, event=data, handler=c1.send) # run the simulation Sim.scheduler.run()
def __init__(self, heuristic_id, plies, rows=2, row_buckets=2, tile_pebbles=2): """ Constructor @param heuristic_id: An int representing the heuristic and player utilizing it. Constants for these are defined in the Menu class in main.py. 2 and 4 are weighted, 3 and 5 are weightless. @param: plies @param: rows @param: row_buckets @param: tile_pebbles """ super(AndOrGraphSearch, self).__init__(heuristic_id, plies, rows, row_buckets, tile_pebbles) self.board = Board(rows, row_buckets, tile_pebbles) self.game_tree = Node()
def start(): '''Start the Application''' log = configure_log() log.info('Starting Cloud Worker Node Agent') log.info('--------------------------') args = parse_args() settings = {'base_url': args.server, 'secret': args.secret, 'client_id': C.CLIENT_ID, 'client_secret': C.CLIENT_SECRET, 'username': C.USERNAME, 'password': C.PASSWORD} server = Server(settings) node = Node(server) #Send the hostname, ip etc to the server node.send_info() #Update the node status to ready node.update_node_status(C.STATUS_READY) #Get Config config = Config(server, node) actions = Action(server, node) processor = Processor() workers = Worker(server, node, processor) output = Output(server, node) finished = False #Loop forever (kind of) while not finished: log.info('Looping') log.info('--------------------------') #Update last seen date node.update_node_date() #Get config config.refresh() #Get actions num_pending = actions.get_pending() #Respond to actions if actions.has_pending(): message = 'Responding to %d Actions ...' % num_pending output.send(message) actions.respond_to_pending() #Get workers/commands workers.refresh() workers.process_workers() #TODO #Respond to/run commands #Send output to server log.info('Sleeping for %d seconds ...', config.get(C.CONFIG_POLL_PERIOD)) time.sleep(config.get(C.CONFIG_POLL_PERIOD))
class AndOrGraphSearch(Algorithm): """ This class handles the operations of the AND-OR graph search algorithm given a set of initial conditions for a board and which player (top or bottom). """ def __init__(self, heuristic_id, plies, rows=2, row_buckets=2, tile_pebbles=2): """ Constructor @param heuristic_id: An int representing the heuristic and player utilizing it. Constants for these are defined in the Menu class in main.py. 2 and 4 are weighted, 3 and 5 are weightless. @param: plies @param: rows @param: row_buckets @param: tile_pebbles """ super(AndOrGraphSearch, self).__init__(heuristic_id, plies, rows, row_buckets, tile_pebbles) self.board = Board(rows, row_buckets, tile_pebbles) self.game_tree = Node() def build_tree(self, node, depth, path): child_values = [] # Check for loops board = node.get_board() looping = str(board) in path if not looping and depth < self.plies and not board.is_game_over(): # Add the current node to the path path.append(str(board)) for child in board.get_possible_states(depth % 2): child_node = Node(child) node.add_child(child_node) child_values.append(self.build_tree(child_node, depth + 1, path)) node.set_value(math.ceil(sum([(1.0 / len(child_values)) * child for child in child_values]))) else: node.set_value(self.heuristic.evaluate_board_state(node.get_board().get_state())) return node.get_value() def decide_move(self, board): """ Determines the next move that the player should make. @return: a tuple with the coordinates of the next move. """ self.game_tree = Node(board) self.build_tree(self.game_tree, 0, []) moves = [move for move in self.game_tree.get_board().legal_moves(self.player_row)] values = [node.get_value() for node in self.game_tree.get_children()] return moves[values.index((max(values)))]