Java wordsearch Char arrays

16,394

Solution 1

Here is an example of searching a grid for words in different direction. I have implemented three of them, and left three of them for you to finish. In my personal preference, I would have used an array of strings instead of a jagged array for the wordList, but I went with the OP's choice for the implementation. I made a simple version using a 4 x 4 grid, and a list of 3 words. Note that I call fillWithSpaces() on the output board. This is critical for formatting.

I have a text file called "board.txt"

dcat
aoiq
eigk
snur

and a text file "words.txt"

dog
cat
runs

Here is output of the program:

DCAT
-O--
--G-
SNUR

My strategy is to search the board for the first letter of a word. Once I find it, I update the static fields foundRow and foundColumn. When I use a different word, I update the static field currentWord. When I find a letter that matches, I have six different methods, checkForwards() checkBackwards() and so on. (There are other ways to do this but I am trying to make the example as clear as possible.

Here is the check backwards method. Since I already know the first letter matches, I start with the second (index 1). For each new char, I check that it will be on the board before I compare the values. (There is a better way to do this as well). If anything fails, I return. If all the chars match, I copy each char one at a time.

static void checkBackwards()
{
    for(int i = 1; i < wordList[currentWord].length; i++)
    {
        if(foundColumn - i < 0) return;
        if(wordList[currentWord][i] != board[foundRow][foundColumn - i]) return;
    }
    //if we got to here, update the output
    for(int i = 0; i < wordList[currentWord].length; i++)
    {
        output[foundRow][foundColumn - i] = wordList[currentWord][i];
    }
    return;
}

And here is the source code:

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

public class Wordsearch 
{
    static Scanner input;
    static char[][] wordList;
    static char[][] board;
    static char[][] output;

    static int foundRow;
    static int foundColumn;
    static int currentWord;

    public static void main(String[] args) throws FileNotFoundException
    {
        File wordInput = new File("words.txt");
        File boardInput = new File("board.txt");
        if(!wordInput.exists() || !boardInput.exists())
        {
            System.out.println("Files do not exist.");
            System.exit(1);
        }

        wordList = new char[3][];   //word list matrix 
        board = new char[4][4]; //board or grid matrix
        output= new char[4][4]; //solved puzzle 

        fillWithSpaces(output);

        input = new Scanner(wordInput);
        for(int i = 0; i < wordList.length; i++)
        {
            wordList[i] = input.nextLine().toUpperCase().toCharArray();
        }

        input = new Scanner(boardInput);
        for(int i = 0; i < board[0].length; i++)
        {
            board[i] = input.nextLine().toUpperCase().toCharArray();
        }

        for(int i = 0; i < wordList.length; i++)
        {
            currentWord = i;
            if(findFirstLetter())
            {
                checkEachDirection();
            }
        }

        print(output);
    }

    static boolean findFirstLetter()
    {
        for(int r = 0; r < board.length; r++)
        {
            for(int c = 0; c < board.length; c++)
            {
                if(wordList[currentWord][0] == board[r][c])
                {
                    foundRow = r;
                    foundColumn = c;
                    return true;
                }
            }
        }
        return false;
    }

    static void checkEachDirection()
    {
        checkForwards();
        checkBackwards();
        //checkUp();
        //checkDown();
        checkDiagonalDown();
        //checkDiagonalUp();
    }

    static void checkForwards()
    {
        for(int i = 1; i < wordList[currentWord].length; i++)
        {
            if(foundColumn + i > board.length - 1) return;
            if(wordList[currentWord][i] != board[foundRow][foundColumn + i]) return;
        }
        //if we got to here, update the output
        for(int i = 0; i < wordList[currentWord].length; i++)
        {
            output[foundRow][foundColumn + i] = wordList[currentWord][i];
        }
        return;
    }

    static void checkBackwards()
    {
        for(int i = 1; i < wordList[currentWord].length; i++)
        {
            if(foundColumn - i < 0) return;
            if(wordList[currentWord][i] != board[foundRow][foundColumn - i]) return;
        }
        //if we got to here, update the output
        for(int i = 0; i < wordList[currentWord].length; i++)
        {
            output[foundRow][foundColumn - i] = wordList[currentWord][i];
        }
        return;
    }

    static void checkDiagonalDown()
    {
        for(int i = 1; i < wordList[currentWord].length; i++)
        {
            if(foundColumn + i > board.length - 1) return;
            if(foundRow + i > board.length - 1) return;
            if(wordList[currentWord][i] != board[foundRow + i][foundColumn + i]) return;
        }
        //if we got to here, update the output
        for(int i = 0; i < wordList[currentWord].length; i++)
        {
            output[foundRow + i][foundColumn + i] = wordList[currentWord][i];
        }
        return;
    }

    static void print(char[][] board)
    {
        for(int i = 0; i < board.length; i++)
        {
            for(int j = 0; j < board.length; j++)
            {
                System.out.print(board[i][j]);
            }
            System.out.println();
        }
        System.out.println();
    }

    static void fillWithSpaces(char[][] board)
    {
        for(int i = 0; i < board.length; i++)
        {
            for(int j = 0; j < board.length; j++)
            {
                board[i][j] = '-';
            }
        }
    }
}

Solution 2

Consider the following program:

import java.util.ArrayList;

public class WordSearch {

    static char[][] board;
    static int board_x, board_y;
    static ArrayList<String> search_words;

    public static void main(String args[])
    {
        board = new char[][]{
            { 's', 't', 'a', 'c', 'k' },
            { 'x', 'f', 'l', 'o', 'w' },
            { 'x', 'x', 'x', 'v', 'x' },
            { 'x', 'x', 'x', 'e', 'x' },
            { 'x', 'x', 'x', 'r', 'x' },
        };
        // You could also get these from board.size, etc
        board_x = 5;    
        board_y = 5;

        search_words = new ArrayList<String>();
        search_words.add("stack");
        search_words.add("over");
        search_words.add("flow");
        search_words.add("not");

        for(String word : search_words){
            find(word);
        }
    }

    public static void find(String word)
    {
        // Search for the word laid out horizontally
        for(int r=0; r<board_y; r++){
            for(int c=0; c<=(board_x - word.length()); c++){
                // The pair (r,c) will always be where we start checking from
                boolean match = true;
                for(int i=0; i<word.length(); i++){
                    if(board[r][c + i] != word.charAt(i)){
                        match = false;
                        System.out.format("    '%s' not found starting at (%d,%d) -- first failure at %d\n", word, r, c, i);
                        break;
                    }
                }

                if(match){
                    System.out.format("Found match (horizontal) for '%s' starting at (%d,%d)\n", word, r, c);
                }
            }
        }
    }
}

The board is a 2-dimensional char array and the list of words you're searching for is an ArrayList called search_words.

After some simple sample initialization of the board and the search_words list, it iterates through the words in the list, searching for each if it lies horizontally.

This idea could be extended to search vertically or diagonally as well with some tweaks.

The logic here is what you should take away from the sample program, not necessarily the structure. If I were doing this for anything serious, I'd probably have a Board class, probably with a .find(word) method.

Finally, the verbose output is:

Found match (horizontal) for 'stack' starting at (0,0)
    'stack' not found starting at (1,0) -- first failure at 0
    'stack' not found starting at (2,0) -- first failure at 0
    'stack' not found starting at (3,0) -- first failure at 0
    'stack' not found starting at (4,0) -- first failure at 0
    'over' not found starting at (0,0) -- first failure at 0
    'over' not found starting at (0,1) -- first failure at 0
    'over' not found starting at (1,0) -- first failure at 0
    'over' not found starting at (1,1) -- first failure at 0
    'over' not found starting at (2,0) -- first failure at 0
    'over' not found starting at (2,1) -- first failure at 0
    'over' not found starting at (3,0) -- first failure at 0
    'over' not found starting at (3,1) -- first failure at 0
    'over' not found starting at (4,0) -- first failure at 0
    'over' not found starting at (4,1) -- first failure at 0
    'flow' not found starting at (0,0) -- first failure at 0
    'flow' not found starting at (0,1) -- first failure at 0
    'flow' not found starting at (1,0) -- first failure at 0
Found match (horizontal) for 'flow' starting at (1,1)
    'flow' not found starting at (2,0) -- first failure at 0
    'flow' not found starting at (2,1) -- first failure at 0
    'flow' not found starting at (3,0) -- first failure at 0
    'flow' not found starting at (3,1) -- first failure at 0
    'flow' not found starting at (4,0) -- first failure at 0
    'flow' not found starting at (4,1) -- first failure at 0
    'not' not found starting at (0,0) -- first failure at 0
    'not' not found starting at (0,1) -- first failure at 0
    'not' not found starting at (0,2) -- first failure at 0
    'not' not found starting at (1,0) -- first failure at 0
    'not' not found starting at (1,1) -- first failure at 0
    'not' not found starting at (1,2) -- first failure at 0
    'not' not found starting at (2,0) -- first failure at 0
    'not' not found starting at (2,1) -- first failure at 0
    'not' not found starting at (2,2) -- first failure at 0
    'not' not found starting at (3,0) -- first failure at 0
    'not' not found starting at (3,1) -- first failure at 0
    'not' not found starting at (3,2) -- first failure at 0
    'not' not found starting at (4,0) -- first failure at 0
    'not' not found starting at (4,1) -- first failure at 0
    'not' not found starting at (4,2) -- first failure at 0

Solution 3

you can try this for horizontal search String word = ""; for (String keyWord : words) {

        // STEP1: Find *************IF ******************* The word is in
        // the Array
        // CODE HERE
        boolean found = false;
        for (int i = 0; i < puzzle.length; i++) {
            String rowString = "";
            for (int j = 0; j < puzzle[i].length; j++) {
                rowString += puzzle[i][j];
                if (rowString.contains(keyWord) && !found) {

                    System.out.println(keyWord);
                    int index = rowString.indexOf(keyWord);
                    rowString.indexOf(keyWord);
                    // int length = keyWord.length();
                    for (int ii = 0; ii < keyWord.length(); ii++) {
                        solutionArray[i][index + ii] = keyWord.charAt(ii);
                        rowString += puzzle[i][j];
                        System.out.println();
                        // length--;
                    }
                    found = true;
                }

            }
        }
Share:
16,394
Admin
Author by

Admin

Updated on June 14, 2022

Comments

  • Admin
    Admin almost 2 years

    I have been struggling with this wordsearch project for a couple of days now, just trying to get the horizontal search working. It's meant to work in all 8 possible directions (horizontal, vertical, diagonal). Here is my current code.

    For now I'm only worrying about the horizontal, as I suspect if I get the comparison down right then the rest will be simpler.

    I am meant to write code which finds the words contained in the boards array, and output those characters to another array which is the same size as the board array (Hence, the output array is the solution to the board array).

    So far, all my code does is iterate through the entire board, then check if it matches with the first character of the wordlist, if it does then this character is assigned on the output array, which is finally printed in the end out to the console for the user to see.

    My question is, how can I forward my search to iterate the wordlist as well? Is my approach wrong? For example, if the board char matches with the char in the wordlist, then continue in that specified direction (in my case I'm worrying about the horizontal direction) and find the word.

    Also, method 'filter' is meant to handle exceptionOutofBounds in case the search goes off the board.

    Any ideas or approaches are welcome.

  • Admin
    Admin over 10 years
    I was trying to implement this exact method, just didn't know where to even begin. Thank you so much.