/* * Created on Jun 23, 2004 */ package wordFinderPuzzle; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import textfile.FileOrURLInputStream; /** Read a text file which contains a representation of a word finder puzzle. * The format of the file is as follows: *
Line 1 contains two integers, separated by a space. These * are number of rows (r) and number of columns (c) of the puzzle. *
The next r lines each contain a string of exactly c characters. * These lines represent the rows of characters of the puzzle. *
The next line contains a single number, which is the number (w) of * words * which are to be looked for in the puzzle. *
The next w lines each contain one word to be searched for. *
Any lines beyond this are ignored. *
For example, the following represents a 3x3 puzzle with * two words to be searched for:
3 3
cat
ack
rtx
2
cat
act
There is a minimum number of rows and columns that a puzzle must be. The number of rows and columns does not have to be the same. * * @author dickey */ public class WFPuzzleReader { /** Minimum number of rows a puzzle may have. */ public static final int MIN_ROWS = 2; /** Minimum number of columns a puzzle may have. */ public static final int MIN_COLS = 2; /** The 2-D array of puzzle letters. */ private char[][] matrix; /** The words to look for in the puzzle. */ private String[] words; /** Read in a file from a file. * * @param fileID Identifies a file, which may be local, or may * be a URL of a remote file. If local, the file should be on * the classpath, in the user directory, or someplace else likely. *
The original case of all letters and words is preserved. There * is no check for legality of characters or words. * @throws IOException if there is any error reading the file. * @throws IllegalArgumentException if the file format is illegal. */ public WFPuzzleReader(String fileID) throws IOException { BufferedReader puzzfile = // FileOrURLBufferedReader.createReader(fileID); new BufferedReader(new InputStreamReader( new FileOrURLInputStream(fileID))); int lineNum = 0; //how many lines of file have been read try { //The first line should have two numbers: 2-D array dimensions String firstLine = puzzfile.readLine(); lineNum++; String[] nums = firstLine.split("\\s", -1); //split on whitespace int rowCount = Integer.parseInt(nums[0]); if (rowCount <= MIN_ROWS) { throw new IllegalArgumentException( "line #" + lineNum + ": row count " + rowCount + " must be > " + MIN_ROWS); } int colCount = Integer.parseInt(nums[1]); if (colCount <= MIN_COLS) { throw new IllegalArgumentException( "line #" + lineNum + ": column count " + colCount + " must be > " + MIN_COLS); } //Now we know how big to expect the puzzle to be this.matrix = new char[rowCount][colCount]; for (int row = 0; row < rowCount; row++) { String rowLine = puzzfile.readLine(); lineNum++; if (rowLine.length() != colCount) { throw new IllegalArgumentException( "line #" + lineNum + " has " + rowLine.length() + ", expected " + colCount); } this.matrix[row] = rowLine.toCharArray(); } //all rows of the matrix have been read in //next line tells how many words to expect String wCountString = puzzfile.readLine(); lineNum++; int wCount = Integer.parseInt(wCountString); if (wCount < 0) { throw new IllegalArgumentException("Line " + lineNum + ": " + "Number of words to search for " + " must be positive: " + wCount); } this.words = new String[wCount]; for (int w = 0; w < wCount; w++) { String wLine = puzzfile.readLine(); if (wLine == null) { throw new IllegalArgumentException("Premature end of file " + "after line " + lineNum); } lineNum++; this.words[w] = wLine.trim(); } //all expected data has been read String extraData = puzzfile.readLine(); while (extraData != null) { lineNum++; System.out.println("Line " + lineNum + ": " + " unexpected data ignored: " + extraData); extraData = puzzfile.readLine(); } System.out.println("Puzzle file " + fileID + " processed completely. " + lineNum + " lines read"); System.out.println(this); //all done, successfully } catch (IOException e) { System.out.println("Error reading puzzle file, line " + lineNum + ":\n\t" + e); throw e; } } /** Get the character matrix of the puzzle that was read in. * * @return the character matrix. */ public char[][] getMatrix() { return this.matrix; } /** Get the list of words which are to be looked for in the puzzle. * * @return an array of strings, each of which represents a word * to be looked for. */ public String[] getWords() { return this.words; } /** Give a short summary of the puzzle that was read in. * */ public String toString() { String retVal = this.getClass().getName() + " " + this.matrix.length + "x" + this.matrix[0].length + " matrix, " + this.words.length + " words to find."; return retVal; } }