Question

I'm trying to implement a boggle solver.

My basic idea was to create a method that would check a word to see if it was on the board. then trim my dictionary by getting rid of words that start with char's not on the board, then apply that method to every word on the dictionary set to get a solution set.

I'm not entirely sure how efficient this solution is.. I'm pretty sure it just runs on O(n) (proportional to the the size of the dictionary set) - which would be nice on bigger boards (5x5 - 7x7)

My current method (which should work if I can fix the way the visited works):

private Tile findFirstTile(String word) {
    word = word.toUpperCase();
    Tile first = null;
    boolean found = false;
    for (Tile tile : tiles) {
        if (tile.getChar() == word.charAt(0)) {
            first = tile;
            found = true;
        }
    }
    if (found) {
        System.out.println("Found the tile!!");
        return first;
    }
    else return null;
}


public boolean findWordOnBoard(String word, Tile tile, int depth, HashSet<Integer> visited) {
    System.out.println("depth is " + String.valueOf(depth) + " right meow.");
    if (depth == word.length()) return true; // base case - breaks recursion (on board)
    else {
        word = word.toUpperCase();
        if (tile == null) return false;
        HashSet<Integer> neighbors = map.get(tile.getPlace());
        for (int n : neighbors) {
            if ((tiles[n-1].getChar() == word.charAt(depth)) && (!visited.contains(n))) {
                visited.add(n);
                System.out.println("found " + tile.getChar() + " at " + n);
                if (depth == word.length()) return true; // it shouldn't but oh well it's just here
                findWordOnBoard(word, tiles[n-1], depth +1, visited);
            } 
        }

        System.out.println("only supposed to be here if it's ACTUALLY not on board");
        return false; //will only get here if it doesn't find a new word
    }
}

I'm not sure if I'm implementing the recursion correctly.. it's not finding any words right now but it seems to me like it should work..? i'm particularly worried if i'm handling the visited set correctly (if it's keeping track of which tiles it's visited at each depth), but I know that's not the only issue because I should still be able to find some short words otherwise...

R L O S
E E A P
M S T R
E A T S

Also, I just realized that my "findFirstTile" method will only start looking for words on the last tile that starts with that letter ... so if there's multiple occurrences of that letter on the board it might not look through all of them.

this is the constructor to my Tile object also:

  public Tile (char letter, int place){ // NOTE: the char MUST BE capital
    this.letter = letter;
    this.place = place;
    try {
        img = ImageIO.read(new File("tile"+letter+".png"));
    } catch (IOException e) {
    }

the Tile array (tiles) that I reference is also just an array of all the tiles in order so basically on my board:

tiles[0]  tiles[1]  tiles[2]  tiles[3]
tiles[4]  tiles[5]  tiles[6]  tiles[7]
tiles[8]  tiles[9]  tiles[10] tiles[11]
tiles[12] tiles[13] tiles[14] tiles[15]

while the "places" (from the Tile constructor) are just

1  2  3  4
5  6  7  8
9  10 11 12
13 14 15 16

I've checked my getNeighbors() and getChar() and getPlace() methods and they all work as intended.

Was it helpful?

Solution

In case anyone is wondering (probably not, lol)

here's the revised (and working) code:

public boolean findWordOnBoard(String word, Tile tile, int depth, HashSet<Integer> visited) {
    if (depth == word.length()) return true; // base case - breaks recursion (on board)
    else {
        word = word.toUpperCase();
        if (tile == null) return false;
        HashSet<Integer> neighbors = map.get(tile.getPlace());
        for (int n : neighbors) {
            if (depth >= word.length()) return true;
            if ((tiles[n-1].getChar() == word.charAt(depth)) && (!visited.contains(n))) {
                visited.add(n);
                System.out.println("found " + tile.getChar() + " at " + n);
                return findWordOnBoard(word, tiles[n-1], depth+1, visited);
            } 
        }

    }
    return false; //will only get here if it doesn't find a new word
}

the issue was just returning the recursive call as opposed to just make it, since when it went backwards through the recursion the base-case call to break (depth == word.length()) stopped being true as the depth went back to 1.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top