code: def find_or_graft(self, board):
          
          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
docs: 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