简体   繁体   中英

Java - Boggle / Word Matrix Solver Path Issues

I am making an application that will find all words that can be made with adjacent tiles on a 4x4 grid (Boggle). I have gotten to where I can input a string of letters and the algorithm will find all available words in an optimal amount of time. However, I need to know not just the words that are valid, but their square's location on the board.

Here is the main Game class. The algorithm recursively starts with one letter, then checks to see if any words exist that start with that letter plus its neighbor. If no words exist, the path is blocked off and the algorithm moves on to the next letter. If a word exists with that prefix, do the same thing with that neighbor.

import java.io.IOException;
import java.util.ArrayList;

public class Game {
private final int boardSize = 4;
private BoardSquare[][] squares;
private ArrayList<String> validWords;
private static WordTree trie;
private static int counter = 0;
private DevRunner runner;

public Game(String letters) throws IOException{
    validWords = new ArrayList<String>();
    runner = new DevRunner();
    trie = new WordTree();
    squares = new BoardSquare[boardSize][boardSize];
    for (int y=0; y<boardSize; y++){
        for (int x=0; x<boardSize; x++){
            squares[x][y] = new BoardSquare(letters.charAt(y*boardSize + x), y*boardSize + x);
        }
    }
    for (int y=0; y<boardSize; y++){
        for (int x=0; x<boardSize; x++){
            for (int a=-1; a<2; a++){
                for (int b=-1; b<2; b++){
                    if (a == 0 && b == 0) continue;
                    if (x+b < 0 || y+a < 0) continue;
                    if (x+b > boardSize-1 || y+a > boardSize-1) continue;
                    squares[x][y].addNeighbor(squares[x+b][y+a]);
                }
            }
        }
    }
    getPossibleCombinations();
    System.out.println(counter + " words found.");
}

public void getPossibleCombinations(){
    for (int y=0; y<boardSize; y++){
        for (int x=0; x<boardSize; x++){
            doNeigh(squares[x][y], "", new ArrayList<Integer>());
        }
    }
}

public void doNeigh(BoardSquare square, String path, ArrayList<Integer> locations) {
    square.setIsActive(true);
    path += square.getData();
    locations.add(square.getPosition());
    if (trie.has(path) != 0){
        for (BoardSquare neighbor : square.getNeighbors()){
            if (!neighbor.getIsActive()){
                doNeigh(neighbor, path, locations);
                };
            }
        }
    if (trie.has(path) == 1 && !validWords.contains(path)){
        System.out.print(path + " is a word! (");
        validWords.add(path);
        for (int i : locations){
            System.out.print(i + " -> ");
        }
        System.out.print("\n");
        sendWord(path);
        counter++;
    }
    square.setIsActive(false);
}

public void sendWord(String s){

}

public static void main(String[] args){
    try {
        long t1 = System.currentTimeMillis();
        Game g = new Game("SIOZTRTEBAINERLA");
        long t2 = System.currentTimeMillis();
        System.out.println("The algorithm took " + Long.toString(t2-t1) + " milliseconds to complete.");
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

Actual output:

SITAR is a word! (0 -> 1 -> 2 -> 4 -> 5 -> 8 -> 9 -> 5 -> 2 -> 6 -> 8 -> 10 -> 6 -> 7 -> 11 -> 13 -> 14 -> 15 -> 
SIT is a word! (0 -> 1 -> 2 -> 4 -> 5 -> 8 -> 9 -> 5 -> 2 -> 6 -> 8 -> 10 -> 6 -> 7 -> 11 -> 13 -> 14 -> 15 -> 6 -> 8 -> 10 -> 12 -> 13 -> 8 -> 10 -> 5 -> 6 -> 7 -> 11 -> 14 -> 15 -> 12 -> 14 -> 14 -> 
SIR is a word! (0 -> 1 -> 2 -> 4 -> 5 -> 8 -> 9 -> 5 -> 2 -> 6 -> 8 -> 10 -> 6 -> 7 -> 11 -> 13 -> 14 -> 15 -> 6 -> 8 -> 10 -> 12 -> 13 -> 8 -> 10 -> 5 -> 6 -> 7 -> 11 -> 14 -> 15 -> 12 -> 14 -> 14 -> 5 -> 2 -> 3 -> 6 -> 7 -> 4 -> 6 -> 8 -> 9 -> 10 -> 6 -> 7 -> 9 -> 11 -> 6 -> 7 -> 14 -> 15 -> 13 -> 14 -> 15 -> 

Expected output:

SITAR is a word! (0 -> 1 -> 4 -> 9 -> 5 ->
SIT is a word! (0 -> 1 -> 4 ->
SIR is a word! (0 -> 1 -> 5 ->
...

I don't get why I can use the doNeigh() method and have it build String path via recursion, but when I try to build an arraylist of the square's positions in the same way, it includes a bunch of squares that don't make up the word.

Any help is appreciated, thank you.

You have to remove the last element from locations at the end of doNeigh() . Otherwise this path will grow indefinitely.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM