def setUp(self): self.node = Node(id='node1', x=0, y=0, production=3, connections={ 'node2': Connection('node1', 'node2', throughput=1, travel_time=10), 'node3': Connection('node1', 'node3', throughput=1, travel_time=10), 'node4': Connection('node1', 'node4', throughput=1, travel_time=10), }) self.game = Game( {'node1': self.node}, decay_rate=0.1, starting_units=1, offensive_force=1, )
def uct(board, time_limit): # record start time start_time = time.time() root = Node(board, None, None) c = 5 while (time.time() - start_time) < time_limit: tree_terminal = tree_policy(root, c) reward_vector = default_policy(tree_terminal.get_board()) backup(tree_terminal, reward_vector) return best_child(root, 0).get_action()
def setUp(self): self.connection = Connection('node1', 'node0', throughput=1, travel_time=10) self.game = Game( nodes={ 'node0': Node('node0', x=0, y=0, production=3, connections={}), }, decay_rate=0.1, starting_units=1, offensive_force=1, )
def generate(self): return { self.stringify_node_id(node_id): Node(id=self.stringify_node_id(node_id), **self.node_position(node_id), production=self.node_production(node_id), connections={ self.stringify_node_id(to_id): Connection(**self.connection_properties(node_id, to_id), ) for to_id in self.node_connections(node_id) if to_id in self.node_ids }) for node_id in self.node_ids }
def expand(node): # get the current board board = node.get_board() visited_actions = set( [child.get_action() for child in node.get_children()]) all_actions = board.get_legal_actions() # get first unvisited for all_action in all_actions: not_visited = True for visited_action in visited_actions: if hash(visited_action) == hash(all_action): not_visited = False if not_visited: action = all_action break new_board = action.apply(board) child = Node(new_board, action, node) node.add_child(child) return child
def initialize_nodes(self): nodes_li = [] cards = [i for i in range(1, self.nb_cards + 1)] # Step 1: creating all nodes and information sets for nb_rounds in range(self.nb_cards): for all_cards in permutations(cards): for previous_p0 in permutations(cards, nb_rounds): for previous_p1 in permutations(cards, nb_rounds): all_cards = list(all_cards) previous_p0 = list(previous_p0) previous_p1 = list(previous_p1) p1 = goof.Player('P1', nb_cards=self.nb_cards, previous=previous_p0) p2 = goof.Player('P2', nb_cards=self.nb_cards, previous=previous_p1) prizes = goof.Prize(nb_cards=self.nb_cards, all_cards=all_cards, current_round=nb_rounds) engine = goof.Engine(p1=p1, p2=p2, prize=prizes) info_chance = engine.get_infoset(is_chance=True) info_p0 = engine.get_infoset(active_player=0) info_p1 = engine.get_infoset(active_player=1) # OLIVIER: CETTE LIGNE NE FONCTIONNE PAS CAR # LES ACTIONS POSSIBLES ASSOCIEES AUX NOEUDS CHANCE NE SONT PAS BONS # chance_actions = [card for card in cards # if card not in prizes.showing] # OLIVIER: j'ai RAJOUTER UN SORT ICI chance_actions = np.sort(prizes.all_cards[nb_rounds:]) act_p0 = [ card for card in cards if card not in previous_p0 ] act_p1 = [ card for card in cards if card not in previous_p1 ] dec_chance = Node(actions=chance_actions, available_information=info_chance, is_chance=True, is_initial=(nb_rounds == 0), line=nb_rounds * 3) dec_p0 = Node(actions=act_p0, available_information=info_p0, is_decision=True, player=0, line=nb_rounds * 3 + 1) dec_p1 = Node(actions=act_p1, available_information=info_p1, is_decision=True, player=1, line=nb_rounds * 3 + 2) nodes_li.append(dec_chance) nodes_li.append(dec_p0) nodes_li.append(dec_p1) # Step 2: removing duplicates (appearing for chance nodes) nodes_li = list(set(nodes_li)) # Step 3: sort by line nodes_li = sorted(nodes_li, key=lambda node: node.line) # Step 4: create terminal nodes max_reward = int(self.nb_cards * (self.nb_cards + 1) / 2) reward_to_node = {} for reward in range(-max_reward, max_reward + 1): term_node = Node(is_terminal=True, utility=reward, player=0) nodes_li.append(term_node) reward_to_node[reward] = term_node # Step 5: initialize topological index for index_node, node in enumerate(nodes_li): node.topological_idx = index_node # Step 6: creating hash --> node dictionnary self.hash_to_node = {} for node in nodes_li: node_hash = hash_dict(node.available_information) self.hash_to_node[node_hash] = node self.info_sets = nodes_li self.reward_to_node = reward_to_node self.nodes = nodes_li
def compute_info_sets(): """ Proceeding depth wise WE CONSIDER AT FIRST ONLY NON TERMINAL NODES AND CONSIDER ONLY THE FOUR POSSIBLE TERMINAL NODES AND SUPPOSE THEY APPEAR AT DEPTH (AKA LINE) 5 :return: """ idx = 0 info_sets = [ Node(actions=[0, 1, 2], available_information={}, is_chance=True, is_initial=True, line=0, topological_idx=idx) ] idx += 1 info_sets += [ Node(actions=a, available_information={}, is_chance=True, line=1, topological_idx=new_id) for (a, new_id) in zip([[1, 2], [0, 2], [0, 1]], range(idx, idx + 3)) ] idx = 4 # First Player First Call line2 = [] for j in range(3): line2.append( Node(actions=[0, 1], available_information={ 'active_player': 0, 'list_act': [], 'card': j }, is_decision=True, player=0, line=2, topological_idx=idx)) idx += 1 # Second Player information set line3 = [] for card_2 in range(3): for last_call in range(2): line3.append( Node(actions=[0, 1], available_information={ 'active_player': 1, 'list_act': [last_call], 'card': card_2 }, is_decision=True, player=1, line=3, topological_idx=idx)) idx += 1 # First player last action (if any) line4 = [] for card_1 in range(3): line4.append( Node(actions=[0, 1], available_information={ 'active_player': 0, 'list_act': [0, 1], 'card': card_1 }, is_decision=True, player=0, line=4, topological_idx=idx)) idx += 1 # Terminal Nodes: 4 in total terminal_nodes = [ Node(actions=[], available_information={ 'active_player': 0, 'list_act': None, 'card': None }, is_terminal=True, player=0, line=5, topological_idx=idx, utility=-1), Node(actions=[], available_information={ 'active_player': 0, 'list_act': None, 'card': None }, is_terminal=True, player=0, line=5, topological_idx=idx + 1, utility=1), Node(actions=[], available_information={ 'active_player': 0, 'list_act': None, 'card': None }, is_terminal=True, player=0, line=5, topological_idx=idx + 2, utility=-2), Node(actions=[], available_information={ 'active_player': 0, 'list_act': None, 'card': None }, is_terminal=True, player=0, line=5, topological_idx=idx + 3, utility=2) ] info_sets = info_sets + line2 + line3 + line4 + terminal_nodes return info_sets
class NodeTestCase(TestCase): def setUp(self): self.node = Node(id='node1', x=0, y=0, production=3, connections={ 'node2': Connection('node1', 'node2', throughput=1, travel_time=10), 'node3': Connection('node1', 'node3', throughput=1, travel_time=10), 'node4': Connection('node1', 'node4', throughput=1, travel_time=10), }) self.game = Game( {'node1': self.node}, decay_rate=0.1, starting_units=1, offensive_force=1, ) def test_set_incoming_change(self): changed = self.node.set_incoming('some_id', {'player1': 5}) self.assertEqual(changed, {self.node}) def test_set_incoming_no_change(self): changed = self.node.set_incoming('some_id', {}) self.assertEqual(changed, set()) def test_do_frame_nobodys_land(self): changed = self.node.do_frame(self.game, 1) self.assertEqual(changed, set()) def test_do_frame_single_owner(self): self.node.units = {'player1': 6} changed = self.node.do_frame(self.game, 0.5) self.assertEqual(changed, {self.node}) self.assertEqual(self.node.units, {'player1': 6 + 3 * 0.5 - 6 * 0.5 * 0.1}) def test_do_frame_sending_split(self): self.node.units = {'player1': 6} self.node.dispositions = { 'player1': Disposition(6.1, { 'node2': 0.2, 'node3': 0.8 }) } self.node.do_frame(self.game, 1) self.assertEqual(self.node.units, {'player1': 6.1}) to_distribute = (6 + 3 - 6 * 0.1) - 6.1 self.assertTrue(to_distribute > 0) self.assertEqual(self.node.connections['node2'].movements, {'player1': to_distribute * 0.2}) self.assertEqual(self.node.connections['node3'].movements, {'player1': to_distribute * 0.8}) def test_do_frame_sending_changed_throughput(self): self.node.units = {'player1': 6} self.node.dispositions = {'player1': Disposition(6, {'node2': 1})} changed = self.node.do_frame(self.game, 1) self.assertEqual(changed, {self.node, self.node.connections['node2']}) self.assertEqual(self.node.units, {'player1': 6}) def test_do_frame_sending_unchanged(self): self.node.units = {'player1': 6} self.node.dispositions = {'player1': Disposition(6, {'node2': 1})} self.node.connections['node2'].set_movements( {'player1': 6 + 3 - 6 * 0.1 - 6}) changed = self.node.do_frame(self.game, 1) self.assertEqual(changed, set()) self.assertEqual(self.node.units, {'player1': 6})