
// WordsGrid.java
// https://rosettacode.org/wiki/Word_search
// Modified by Andrew Davison, ad@coe.psu.ac.th, Dec. 2022

/*  A simplified version of the word search puzzle set at
    https://rosettacode.org/wiki/Word_search

    The words may be placed horizontally, vertically, or diagonally. 
    The words may also be spelled backwards.
    The words may overlap but are not allowed to zigzag, or wrap around. 

    Unlike the Rosetta code problem, there's no message hidden in
    the grid.

    The grid data is read from a text file.

    The search starts at every cell in the grid, and
    tries building words by extending in each of the permitted
    eight directions (encoded in DIRS[]). The words are stored 
    as GridWord objects in a list.

    A word must be longer then MIN_LEN characters.


  Usage:
    > compile WordsGrid.java
    > run WordsGrid <data-file>
  e.g.
    > run WordsGrid rosettaSq.txt
    > run WordsGrid wordSq1.txt

*/

import java.io.*;
import java.util.*;


public class WordsGrid
{
  private static final int MIN_LEN = 4;

  private static final int[][] DIRS = {
            {1, 0}, {0, 1}, {1, 1}, {1, -1}, {-1, 0},
            {0, -1}, {-1, -1}, {-1, 1} };
             // the eight directions possible from a cell

  private static HunspellChecker hsc;


  public static void main(String[] args)
  {
    if (args.length != 1) {
      System.out.println("Usage: run WordsGrid <data-file>");
      return;
    }
    char[][] grid = WordUtils.loadGrid(args[0]);
    // char[][] grid = WordUtils.randomGrid(10, 10);    // used for debugging
    WordUtils.printGrid(grid);

    hsc = new HunspellChecker();

    ArrayList<GridWord> gWords = new ArrayList<>();

    // Finds all words at (r,c), looking in all directions
    for (int r = 0; r < grid.length; r++)
      for (int c = 0; c < grid[0].length; c++)
        for(int[] dir : DIRS) 
          findWordsAt(r, c, dir, grid, gWords);

    // sort and print found words
    Collections.sort(gWords);
    WordUtils.printWords(gWords, 2);

    hsc.close();
  } /* main */



  private static void findWordsAt(int r, int c, int[] dir,
                      char[][] grid, ArrayList<GridWord> gWords)
  /* Find all dictionary words beginning at (r,c) in the
     grid extending in the vertical and horizontal directions in dir
  */
  {
    int startR = r;
    int startC = c;
    String word = "";
    while (WordUtils.onGrid(grid,r,c)) {
      word = word + grid[r][c];
      if ((word.length() >= MIN_LEN) && 
           hsc.isCorrect(word)) {
        GridWord gw = new GridWord(word, startR, startC, r, c);
        gWords.add(gw);
      }
      r += dir[0];   // x-axis direction
      c += dir[1];   // y-axis
    }
  } /* findWordsAt */


} // end of WordsGrid class
