def __iter__(self): """Supports a preorder traversal on a view of self.""" if not self.isEmpty(): stack = LinkedStack() stack.push(self._root) while not stack.isEmpty(): node = stack.pop() yield node.data if node.right != None: stack.push(node.right) if node.left != None: stack.push(node.left)
def preorder(self): """Supports a preorder traversal on a view of self.""" current = self._root traversal = [current.data] tracking = LinkedStack() tracking.push(current.right) tracking.push(current.left) while not tracking.isEmpty(): current = tracking.pop() traversal.append(current.data) for i in (current.right, current.left): if i: tracking.push(i) return iter(traversal)
def build_states(cur_state): """ Builds a tree of states starting from the current game state. Always chooses 2 random move options. (god knows why it's stupid) This method pre-fills the terminal states with scores of 1, -1, and 0. :param cur_state: Game :return: LinkedBST """ states = LinkedBST() st = LinkedStack() states.root = BSTNode([deepcopy(cur_state.board), None, None]) st.push(states.root) while not st.isEmpty(): curr = st.pop() curr_board = curr.data[0] p1w = curr_board.game_over(player=1) p2w = curr_board.game_over(player=2) if p1w: curr.data[1] = 1 continue elif p2w: curr.data[1] = -1 continue cells = curr.data[0].free_cells() if not cells: # No one won and no cells left - it's a tie. curr.data[1] = 0 continue available = random.sample(cells, k=min(len(cells), 2)) for cell in available: new_board = deepcopy(curr.data[0].move( cell, player=1 if curr.data[0].get_turn() % 2 == 1 else 2)) curr.data[0].undo(cell) if curr.left is None: curr.left = BSTNode([new_board, None, cell]) st.add(curr.left) elif curr.right is None: curr.right = BSTNode([new_board, None, cell]) st.add(curr.right) else: break return states