def _generate_node(self, game_state: GameState) -> GameNode: """Generate the node with game_state and also its entire subtree. The node is also inserted into the corresponding layer. Assumption: a node with game_state does not yet exist in the tree (to avoid empty recursive calls) :param game_state: a valid game state, that is a descendant of the root game state :return: the generated node """ # init assert self.find(game_state) is None node = GameNode(game_state) # generate all child nodes, look for a winning == -1 flag minus1_found = False for s_game_state in game_state.normalized_successors(): s_node = self.find(s_game_state) if s_node is None: # recursive guard s_node = self._generate_node(s_game_state) # recursive call node.children.append(s_node) assert s_node.winning != 0 if s_node.winning == -1: minus1_found = True # set the winning flag if minus1_found: node.winning = 1 else: node.winning = -1 # insert this node n = game_state.get_total_count() self.layers[n].insert(node) # count nodes self.node_count += 1 # result return node
def __init__(self, game_state: GameState): """Create the tree whose root-node contains game_state. """ # for tests and logs only self.node_count: int = 0 # generate layers self.layers: List[GameLayer] = [] self.total_count: int = game_state.get_total_count() for n in range(self.total_count + 1): self.layers.append(GameLayer(n)) # generate root node -- and recursively all nodes self.root_node: GameNode = self._generate_node(game_state) # checks assert self.node_count == sum( [len(layer.nodes) for layer in self.layers]) assert all([layer.is_sorted_lt() for layer in self.layers])
def find(self, game_state: GameState) -> GameNode or None: """Return the the tree-node containing game_state, None if not found.""" n = game_state.get_total_count() assert n <= self.total_count node = self.layers[n].find(game_state) return node