/**
   * The main function of sorts. Takes in an input, forms the table, solves the puzzle and prints
   * the results in ascending order of length.
   *
   * @param inputString
   */
  public static void startSolving(String inputString, int wordLimit) {
    getTableFromString(inputString);
    solvePuzzle();

    System.out.println("Number of words : " + validWords.size());
    ArrayList<Position> tiles = null;

    CustomStringComparator myComparator = new CustomStringComparator("");
    Collections.sort(validWords, myComparator);

    RuzzleSwiper ruzzleSwiper = new RuzzleSwiper(60);
    int numOfWords = 0;
    for (String word : validWords) {
      System.out.println(word);
      tiles = wordTilesMapping.get(word);
      ruzzleSwiper.clickPositions(tiles);
      for (Position position : tiles) {
        System.out.print("(" + position.getX() + "," + position.getY() + ")->");
      }
      System.out.println("END\n");

      numOfWords++;
      if (numOfWords >= wordLimit) {
        break;
      }
    }
  }
  /**
   * A recursive function that performs DFS and checks to see if a word is valid or not. Stops when
   * you're out of tiles.
   *
   * <p>TODO Performance Enhancement : Build a suffix tree and check if the node with the suffix arg
   * has any children. That will help skip loads of paths.
   *
   * @param suffix
   * @param coveredPositions
   * @param currentPosition
   */
  private static void solve(
      String suffix, ArrayList<Position> coveredPositions, Position currentPosition) {
    ArrayList<Position> newCoveredPositions = UtilityFunctions.getNewList(coveredPositions);
    newCoveredPositions.add(currentPosition);

    ArrayList<Position> adjacentPositions = currentPosition.getAdjacentPositions();
    for (Position adjacentPosition : adjacentPositions) {
      Boolean isCovered = false;
      for (Position position : newCoveredPositions) {
        if ((position.getX() == adjacentPosition.getX())
            && (position.getY() == adjacentPosition.getY())) {
          isCovered = true;
          break;
        }
      }

      if (isCovered) continue;

      String word = suffix + table[adjacentPosition.getX()][adjacentPosition.getY()];

      if (dictionary.isWordValid(word)) {
        if (!validWords.contains(word)) {
          validWords.add(word);

          ArrayList<Position> tilePositions = UtilityFunctions.getNewList(newCoveredPositions);
          tilePositions.add(adjacentPosition);

          wordTilesMapping.put(word, tilePositions);
        }
      }
      solve(word, newCoveredPositions, adjacentPosition);
    }
  }