Java Crossword Puzzle
So I Am Making a Program That Is Supposed to Generate a Random Crossword Puzzle. I Have a Method Reads in a Txt File That Has a List of Around 3000 Words...
So I am making a program that is supposed to generate a random crossword puzzle. I have a method reads in a txt file that has a list of around 3000 words, stores it into an array list and returns the array list. I have a driver method which asks the user for the amount of rows and columns they want the crossword puzzle to be and from there it is supposed to generate a random puzzle. I'm using a 2d array to construct the entire puzzle but I can't figure out how to add words into the puzzle. This is what I have so far for the method that is supposed to fill in the crossword (the randomNumber method is just a method that returns a random index that is used to access a random word from the list)
public static void buildCrossword(ArrayList<String> words, int rows, int columns)
{
String[][] board = new String[rows][columns];
//Picks a random number from the arrayList using a random index from the randomNumber method
int randomNumber = randomNumber();
String randomWord = words.get(randomNumber);
//we remove it right after it is selected to ensure that it doesn't get used again in the puzzle
words.remove(randomNumber);
char[] temp = randomWord.toCharArray();
char[][] word = new char[temp.length][temp.length];
word[0] = temp;
System.out.println("*----".repeat(rows) + "*");
for(int i = 0; i < columns; i++)
{
System.out.println("| ".repeat(rows) + "|");
System.out.println(word[0][i]);
System.out.println("*----" .repeat(rows) + "*");
}
}
As you know own a crossword there are also filled in unused squares and I need to use an "*" to represent the unused squares. Any help at all would be appreciated.
1 Answer
You should separate your "showing the crossword" logic from your "filling in the crossword" logic. Typically, you would build a Crossword class that contains the 2d array of characters inside (you have a 2d array of Strings - but I believe characters are better), and would provide a toString() method to do the "showing the crossword". You could also have an addWord(String word) method to add a word into the crossword -- the currently-missing part of your code.
Building a crossword would require:
creating an empty,
new Crossword(rows, cols)in a loop, choosing words to add until it is full; and, for each word, adding it:
boolean full = false; while ( ! full) { // choose a word int randomNumber = randomNumber(); String randomWord = words.get(randomNumber); words.remove(randomNumber); // try to add it if ( ! crossword.addWord(randomWord)) { full = true; } }
Adding a word requires searching for an empty space where you can place it, but to save space and get a crossword, you actually want to share at least a single letter with an existing word on the crossword -- except for the 1st word placed, which cannot share anything. If your crossword looks like this, it is easier to know if it is empty:
public class Crossword {
private Char[][] letters;
private int rows, cols;
private int totalWords; // incremented by 1 after each successful addWord
public boolean addWord(String word) { /* your implementation here */}
public String toString() { /* your printing code here */ }
}
The hardest part is, without doubt, the "find where to fit a new word" logic from addWord. You can make it easier with some helper methods:
// inside Crossword class
// returns true if word fits vertically with 1st letter at letters[col][row]
private boolean fitsVertical(int row, int col, String word);
// returns true if word fits horizontally with 1st letter at letters[col][row]
private boolean fitsHorizontal(int row, int col, String word);