Drieke
Drieke

Reputation: 301

Loops aren't processing everything

so I am programming a crossword puzzle solver and I have almost 98% of my code working except for 1 glitch. I have a loop that reads 1 word in from a file and then compares that string with an array of chars to find where in the array that string is. The loop so far reads in all the words and finds their location but my problem is that it skips 3 words on my list. I know the words are in the char array but for some reason they aren't being picked up. Any ideas?

Here is my code:

    import java.io.File;
    import java.util.Scanner;


    public class Test {

        public static void main(String[] args) throws Exception{
            File file = new File("puzzle.txt"); 
            Scanner sc = new Scanner(file);
            int row = sc.nextInt();
            int col = sc.nextInt();
            sc.nextLine();

            //Make an array to hold the puzzle
            char[][] puzzle = new char[row][col];   


             //Read in the strings from the file into the array.
            for (int i=0; i<row; i++){
                String getChar = (new String(sc.next()));
                for(int j = 0;j<col; j++){
                    puzzle[i][j] = getChar.charAt(j);
                    }
                }

            //Read the number of words and move to the next line    
            int numwords = sc.nextInt();
            sc.nextLine();  


            //look for each word
            for(int i=0; i<numwords; i++){
                String word = new String();
                word = sc.nextLine();
                System.out.printf("This is word: %s\n", word);

                //arrays to hold the direction.
                int [] movx ={-1, -1, -1, 0, 0, 1, 1, 1};
                int [] movy ={-1, 0, 1, -1, 1, -1, 0, 1};

                //this variable will hold if we found or not the string in the puzzle
                boolean found = false;

                //find the words in the puzzle
                for(int m = 0; m < puzzle.length; m++) {
                    for(int n = 0; n < puzzle[0].length; n++) {
                        if(puzzle[m][n] == word.charAt(0)){
                            for (int o = 0; o < 8; o++){
                                if(check(m, n, word, puzzle, movx[o], movy[o])){
                                    System.out.printf("%s found at position (%d, %d)\n\n", word, m, n);
                                    found = true;
                                    break;
                                    }
                            }

                        }
                    }
                }
                if (!found){
                    System.out.printf("%s was not found\n\n", word);
                }
            }

        //Close the scanner     
            sc.close();         
        }   
        //This is your generic-direction function
        public static boolean check(int row, int col, String word, char[][] puzzle, int offsetx, int offsety){

            //start with the current position
            int x = row;
            int y = col;

            for (int i = 0; i < word.length(); i++){
                char c = word.charAt(i);

                //Is not equal
                if (puzzle[x][y] != c) return false;

                x += offsetx;
                y += offsety;

                //check the boundaries, if we go out then we didn't find the word;
                if (x < 0 || x >= puzzle.length || y < 0 || y >= puzzle[x].length) return false;
            }

            return true;
        }

    }

(EDIT AREA)

From my diagnosis with print statements, when i is 3, 8 and 9, the wordsearch doesn't find the words. and I believe it's after this loop:

    //find the words in the puzzle
for(int m = 0; m < puzzle.length; m++)

since before this loop, my previous loop goes through every word. And word is getting passed into the loop inside this loop. So it is going all the way through all my checks through every spot in the array, and then just passing as false even though it's in the puzzle.

(/EDIT AREA)

Before this loop, I tested and

The file I'm reading in:

    10 10
    WVERTICALL
    ROOAFFLSAB
    ACRILIATOA
    NDODKONWDC
    DRKESOODDK
    OEEPZEGLIW
    MSIIHOAERA
    ALRKRRIRER
    KODIDEDRCD
    HELWSLEUTH
    10
    WEEK
    FIND
    RANDOM
    SLEUTH
    BACKWARD
    VERTICAL
    DIAGONAL
    WIKIPEDIA
    HORIZONTAL
    WORDSEARCH

This is what it prints (WEEK is not in the puzzle):

    This is word: WEEK and this is i 0
    WEEK was not found 

    This is word: FIND and this is i 1
    FIND found at position (1, 4)

    This is word: RANDOM and this is i 2
    RANDOM found at position (1, 0)

    This is word: SLEUTH and this is i 3
    SLEUTH was not found 

    This is word: BACKWARD and this is i 4
    BACKWARD found at position (1, 9)

    This is word: VERTICAL and this is i 5
    VERTICAL found at position (0, 1)

    This is word: DIAGONAL and this is i 6
    DIAGONAL found at position (8, 6)

    This is word: WIKIPEDIA and this is i 7
    WIKIPEDIA found at position (9, 3)

    This is word: HORIZONTAL and this is i 8
    HORIZONTAL was not found 

    This is word: WORDSEARCH and this is i 9
    WORDSEARCH was not found

These are the words that it cannot find:

    SLEUTH is at position (9,4) 
    HORIZONTAL is at position (9,0)
    WORDSEARCH is at position (0,0)

Any tips, tricks or ideas are very appreciated!

Upvotes: 1

Views: 118

Answers (2)

Omar Mainegra
Omar Mainegra

Reputation: 4194

What is missing is a condition in your check method. When the last character of the word is at some edge it fail because it is trying to find the next neighbor (bound checking). Add this condition if (i == word.length() - 1) return true; after if (puzzle[x][y] != c) return false;

Upvotes: 1

Darius Makaitis
Darius Makaitis

Reputation: 880

In your check method:

//check the boundaries, if we go out then we didn't find the word;
if (x < 0 || x >= puzzle.length || y < 0 || y >= puzzle[x].length) return false;

is checking to see if you've exceeded the puzzle boundaries after you've incremented your x,y values. The problem is for the three words it can't find, it finds the last letter, increments your counters, then decides you've gone off the edge of the puzzle and returns false, even though it's already found the last letter.

Try moving the condition to the start of your loop, like this:

for (int i = 0; i < word.length(); i++){
    //check the boundaries, if we go out then we didn't find the word;
    if (x < 0 || x >= puzzle.length || y < 0 || y >= puzzle[x].length) return false;

    char c = word.charAt(i);

    //Is not equal
    if (puzzle[x][y] != c) return false;

    x += offsetx;
    y += offsety;
} 

Upvotes: 4

Related Questions