Build a tree with each level corresponding to a fixed position on
        board. A path of tiles is stored for each board. If any two boards
        have the same path, then they are the same board. If there is any
        difference, a new branch will be created to store that path.

        Return: True if board already exists in the tree; False otherwise

def find_or_graft(self, board):
        """Build a tree with each level corresponding to a fixed position on
        board. A path of tiles is stored for each board. If any two boards
        have the same path, then they are the same board. If there is any
        difference, a new branch will be created to store that path.

        Return: True if board already exists in the tree; False otherwise

        """
        is_duplicate_board = True  # assume same until find a difference
        # compare each position
        node = self
        for p, new_tile in board.positions_with_tile():
            found_tile = False  # assume no tile in same position until found
            for child in node.children:
                if child.tile == new_tile:
                    # same tile found in this position --> continue this branch
                    node = child
                    found_tile = True
                    break
            if found_tile:
                pass  # go on to the next position
            else:
                # different tile --> start new branch and mark not exact match
                child = _DuplicateTree(new_tile)
                node.graft_child(child)
                node = child
                is_duplicate_board = False  # this will get set many times. ok
        return is_duplicate_board