1

I am programming a boggle game board solver. It uses a Stack, a 2D Array Grid of letters for the game board that are read in from a .dat/.txt file, and Search "States" to store where its been, specifically (point coordinates, word so far). It is designed to search every possible letter combination on the board to form strings of length 3 or more, and then checks a dictionary file to see if that word is a valid boggle word solution. After, it stores the word and returns a list of solutions to the game board that was given in the arguments.

My Problem: For some reason this program has eluded me like no other thing I've ever written before. I am very new to the concept of "states" so that could be an underlying issue. I believe that what I have is fairly close to working, I am just at a loss for what could be wrong with it. The current issue is that it is not ever storing the current letter and building strings as it checks neighboring letters. It does check neighbors properly, but no strings are built. Here is the code:

BoggleSearch: contains the main method, acts as the driver class.

import java.io.*;
import java.util.*;

public class BoggleSearch {

protected static int GRID_SIZE = 4;
public static String[][] grid = new String[GRID_SIZE][GRID_SIZE];

public static void main(String[] args) throws FileNotFoundException {

    if (args.length != 1) {
        System.err.println("Usage: java BoggleSearch gridFile");
        System.exit(1);

    }

    Scanner scan = new Scanner(new File(args[0]));

    String bigString = scan.next();
    bigString = bigString+scan.next();
    bigString = bigString+scan.next();
    bigString = bigString+scan.next();

    scan.close();

    int count = 0;

    for (int i = 0; i < GRID_SIZE; i++) {

        for (int j = 0; j < GRID_SIZE; j++) {


            grid[i][j] = bigString.substring(count, count);

            count++;
        }

    }

    WordSearch ws = new WordSearch(grid);

    ArrayList<BoggleSearchState> foundWords = ws.startSearch();

    System.out.println(foundWords);


   }

}

WordSearch: contains all of the algorithms that find that string every possible combination of letters possible on the given game board and cross-check them with the dictionary class.

import java.awt.Point;
import java.util.*;

public class WordSearch {

public static Stack<BoggleSearchState> stack;

public static ArrayList<BoggleSearchState> foundWords;

private String[][] grid;

private static final int GRID_SIZE = 4;

public BoggleDictionary dictionary;

public WordSearch(String[][] inputGrid) {

    grid = new String[GRID_SIZE][GRID_SIZE];
    stack = new Stack<BoggleSearchState>();
    foundWords = new ArrayList<BoggleSearchState>();
    inputGrid = new String[GRID_SIZE][GRID_SIZE];



    try {
        dictionary = new BoggleDictionary();
    } catch (Exception e) {
        System.err.println("blew up while making dict object");
        e.printStackTrace();
    }
}

public ArrayList<BoggleSearchState> startSearch() {

    for (int i = 0; i < grid.length; i++) {

        for (int j = 0; j < grid.length; j++) {

            BoggleSearchState b = new BoggleSearchState(
                    new ArrayList<Point>(), grid[i][j]);

            Point p = new Point(i, j);

            b.path.add(p);
            stack.push(b);


            while (!stack.isEmpty()) {

                BoggleSearchState s = stack.pop();

                if (s.getWord().length() >=1  && dictionary.contains(s.getWord())) {

                    foundWords.add(s);

                }

                Point loc = s.path.get(s.path.size() - 1);

                p = new Point(loc.x,loc.y);

                // Bottom Neighbor
                if (loc.x + 1 >= 0 && loc.x + 1 < grid.length && loc.y >= 0
                        && loc.y < grid.length) {
                    if (s.getVisited(new Point(p.x+1,p.y)) != true) {

                        BoggleSearchState neo = new BoggleSearchState(new ArrayList<Point>(),s.getWord() + grid[loc.x + 1][loc.y]);
                        neo.path.add(new Point(p.x+1,p.y));
                        stack.push(neo);

                    }
                }

                // Top Neighbor
                if (loc.x - 1 >= 0 && loc.x - 1 < grid.length && loc.y >= 0
                        && loc.y < grid.length) {
                    if (s.getVisited(new Point(p.x-1,p.y)) != true) {

                        BoggleSearchState neo = new BoggleSearchState(
                                new ArrayList<Point>(),s.getWord() + 
                                grid[loc.x - 1][loc.y]);
                        neo.path.add(new Point(p.x-1,p.y));
                        stack.push(neo);

                    }
                }
                // Right Neighbor
                if (loc.x >= 0 && loc.x < grid.length && loc.y + 1 >= 0
                        && loc.y + 1 < grid.length) {
                    if (s.getVisited(new Point(p.x,p.y+1)) != true) {

                        BoggleSearchState neo = new BoggleSearchState(
                                new ArrayList<Point>(),s.getWord() + 
                                grid[loc.x][loc.y + 1]);
                        neo.path.add(new Point(p.x,p.y+1));
                        stack.push(neo);


                    }
                }
                // Left Neighbor
                if (loc.x >= 0 && loc.x < grid.length && loc.y - 1 >= 0
                        && loc.y - 1 < grid.length) {
                    if (s.getVisited(new Point(p.x,p.y-1)) != true) {

                        BoggleSearchState neo = new BoggleSearchState(
                                new ArrayList<Point>(),s.getWord() + 
                                grid[loc.x][loc.y - 1]);
                        neo.path.add(new Point(p.x,p.y-1));
                        stack.push(neo);

                    }
                }
                // Bottom-Right Neighbor
                if (loc.x + 1 >= 0 && loc.x + 1 < grid.length
                        && loc.y + 1 >= 0 && loc.y + 1 < grid.length) {
                    if (s.getVisited(new Point(p.x+1,p.y+1)) != true) {

                        BoggleSearchState neo = new BoggleSearchState(
                                new ArrayList<Point>(),s.getWord() + 
                                grid[loc.x + 1][loc.y + 1]);
                        neo.path.add(new Point(p.x+1,p.y+1));
                        stack.push(neo);

                    }
                }

                // Bottom-Left Neighbor
                if (loc.x + 1 >= 0 && loc.x + 1 < grid.length
                        && loc.y - 1 >= 0 && loc.y - 1 < grid.length) {
                    if (s.getVisited(new Point(p.x+1,p.y-1)) != true) {

                        BoggleSearchState neo = new BoggleSearchState(
                                new ArrayList<Point>(),s.getWord() +
                                grid[loc.x + 1][loc.y - 1]);
                        neo.path.add(new Point(p.x+1,p.y-1));
                        stack.push(neo);

                    }
                }

                // Top-Right Neighbor
                if (loc.x - 1 >= 0 && loc.x - 1 < grid.length
                        && loc.y + 1 >= 0 && loc.y + 1 < grid.length) {
                    if (s.getVisited(new Point(p.x-1,p.y+1)) != true) {

                        BoggleSearchState neo = new BoggleSearchState(
                                new ArrayList<Point>(),s.getWord() +
                                grid[loc.x - 1][loc.y + 1]);
                        neo.path.add(new Point(p.x-1,p.y+1));
                        stack.push(neo);

                    }
                }

                // Top-Left Neighbor
                if (loc.x - 1 >= 0 && loc.x - 1 < grid.length
                        && loc.y - 1 >= 0 && -1 < grid.length) {
                    if (s.getVisited(new Point(p.x-1,p.y-1)) != true) {

                        BoggleSearchState neo = new BoggleSearchState(
                                new ArrayList<Point>(),s.getWord() +
                                grid[loc.x - 1][loc.y - 1]);
                        neo.path.add(new Point(p.x-1,p.y-1));
                        stack.push(neo);

                    }
                }
            }
        }
    }
    return foundWords;
}
}

BoggleSearchState: Creates a state object that is used to store necessary data for each instance of a string forming path on the game board. contains methods necessary for its purpose.

import java.awt.Point;
import java.util.ArrayList;

public class BoggleSearchState {

private String word="";

public ArrayList<Point> path = new ArrayList<Point>();

public BoggleSearchState(ArrayList<Point>path, String word) {

    this.path = path;
    this.word = word;


}

  public String getWord() {


    return word;
}

public ArrayList<Point> getLocation() {


    return path;
}

public boolean getVisited (Point p) {

    ArrayList<Point> newPath = new ArrayList<Point>();
    for (Point s: path) {
        newPath.add(s);

        if (p.equals(s)) {
            return true;


        }

    }

    return false;
}

public String toString() {



    return this.word;
}

}

BoggleDictionary: The terribly written dictionary class that was given for the assignment. It is tested and fully functional however.

//  BoggleDictionary.java

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.util.Scanner;
import java.util.HashSet;
import java.util.Iterator;

/** 
A class that stores a dictionary containing words that can be used in a
Boggle game.

@author Teresa Cole
@version CS221 Fall 2013
 */
    public class BoggleDictionary
    {
private HashSet<String> dictionary;

/** Create the BoggleDictionary from the file dictionary.dat
 */
@SuppressWarnings("unchecked")
public BoggleDictionary() throws Exception {
    ObjectInputStream dictFile = new ObjectInputStream(
            new FileInputStream( new File( "dictionary.dat")));
    dictionary = (HashSet<String>)dictFile.readObject();
    dictFile.close();
}

/** Check to see if a string is in the dictionary to determine whether it
 * is a valid word.
 * @param word the string to check for
 * @return true if word is in the dictionary, false otherwise.
 */
public boolean contains( String word)
{
    return dictionary.contains( word);
}

/** Get an iterator that returns all the words in the dictionary, one at a
 * time.
 * @return an iterator that can be used to get all the words in the
 * dictionary.
 */
public Iterator<String> iterator() 
{
    return dictionary.iterator();
}

/** 
 Main entry point
 */
static public void main(String[] args)  
{
    System.out.println( "BoggleDictionary Program ");

    Scanner kbd = new Scanner( System.in);
    BoggleDictionary theDictionary=null;
    try 
    {
        theDictionary = new BoggleDictionary();
    }
    catch (Exception ioe) 
    {
        System.err.println( "error reading dictionary");
        System.exit(1);
    }
    String word;

    /*
while (kbd.hasNext())
    {
    word = kbd.next();
    if (theDictionary.contains( word))
    System.out.println( word + " is in the dictionary");
    else
    System.out.println( word + " is not in the dictionary");
    }
     */

    Iterator<String> iter = theDictionary.iterator();
    while (iter.hasNext())
        System.out.println( iter.next()); 
}

}

I would appreciate any help on this as I am really struggling with it at this point. I understand that there are numerous ways to implement other data structures or organization methods to accomplish this task in a much more efficient run-time. However the concern of the assignment is not catered towards efficiency, rather the underlying principles of using these data structures (stacks etc.) and understanding how you are able to go a wrong direction and then safely back track and go a new direction without the program crashing. Thank you in advance, any questions I'll try to answer as fast as I can.

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
  • 1
    TLDR; You need to do a bit more work to narrow down the problem - either run in a debugger or use good old prints to find out what is going on as you run. – John3136 Nov 08 '13 at 00:35
  • What it isn't doing: 1.) Building Strings What it is doing: 1.) I've put prints inside every neighbor call as follows: System.out.println(neo + "1"); 1-8 for each neighbor. sample output after that: 1 2 3 4 5 6 7 8 However there are gaps in between where ever I call to print neo, as if its trying to display a word but they are all null strings. – user2967070 Nov 08 '13 at 00:42
  • 1
    I apologize, I'm new here and I thought I was supposed to be detailed about the issue. – user2967070 Nov 08 '13 at 00:46

1 Answers1

2

As near as I can tell, you have two grids in WordSearch, but you set both of them to initialized arrays. You never use the grid you look like you might have built in the main method.

But it is hard to tell.

You have given us much data but little information. We don't need details about the entirety of a program, even one this size; we need to know what your specific question is. No one is liable to debug this for you, and in fact few enough are going to read as much of it as I have.

After you've fixed your initialization problem, debug your program however you can and figure out where it does something that (1) it isn't supposed to, and (2) you don't understand. You need to spend enough time attempting to figure out #1 yourself for your own education on debugging, and it makes it much more likely that you can explain what you don't understand and get a good answer to a specific question. "It isn't Building Strings" doesn't go quite far enough; WHERE isn't it building, what do you mean by building strings, etc. I expect it's because it has no input, but I didn't analyze that far.

arcy
  • 12,845
  • 12
  • 58
  • 103
  • Okay I will do that and perhaps reformulate a better structured question. Thank you for the insight, its much appreciated! – user2967070 Nov 08 '13 at 03:28