Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.*;
- import java.io.*;
- import java.math.*;
- /**
- * This program takes a given rack of letters (in an array)
- * and finds words in a dictionary file that can be
- * made from that given rack. Then, it computes the scores for
- * each matching word and returns them to the user based on
- * the desired word length (3-6 characters). Also, it has to
- * randomly select a 6 letter word from a generated text file.
- * Lastly, it needs to computer the top word score and the highest
- * word score per tile value.
- *
- *
- * @author Zach VanDuyn
- *
- * CS1122, Spring 2011
- * Bryan Franklin
- */
- public class ScrabbleSolver
- {
- private String dictFile;
- /**
- * Constructor for the ScrabbleSolver Object
- * This should create the files containing the lists of
- * 3-6 letter words and only 6 letter words, as well as initialize
- * any other class variables you need for the other methods
- *
- * @param dictFilename - filename of the dictionary text file
- * @param scoreFilename - filename of the letter score text file
- */
- public ScrabbleSolver(String dictFilename, String scoreFilename)
- {
- dictFile = dictFilename;
- Scanner in = null;
- try{
- in = new Scanner(new File(dictFilename));
- }
- catch(Exception e)
- {
- System.out.println("Unable to access file: [" + dictFilename + "]");
- }
- try
- {
- in = new Scanner(new File(scoreFilename));
- }
- catch(Exception e)
- {
- System.out.println("Unable to access file: [" + scoreFilename + "]");
- }
- PrintWriter dict36 = null;
- try {
- dict36 = new PrintWriter("words3-6.txt");
- } catch (FileNotFoundException e) {
- System.out.println("Unable to access file: words3-6.txt");
- e.printStackTrace();
- } //allows us to write to "words3-6.txt"
- PrintWriter dict6 = null;
- try {
- dict6 = new PrintWriter("words6.txt");
- } catch (FileNotFoundException e) {
- System.out.println("Unable to access file: words6.txt");
- e.printStackTrace();
- } //allows us to write to "words6.txt"
- while(in != null && in.hasNext())
- {
- String word = in.nextLine();
- if(word.length() > 2 && word.length() < 7) //makes sure the words length is between three and six
- {
- if(dict36 != null)
- dict36.println(word);
- if(dict6 != null && word.length() == 6) //if it is exactly six in length - store it in the "words6.txt"
- {
- dict6.println(word);
- }
- }
- }
- if(dict36 != null)
- dict36.close(); //closing the stream saves the changes on dict36 ("words3-6.txt")
- if(dict6 != null)
- dict6.close(); //closing the stream saves the changes on dict6 ("words6.txt")
- }
- /**
- * This method searches the scrabble dictionary for all
- * words that can be formed by the character array of letters
- *
- * @param theLetters - character array of the letters, can be of length 0-8
- * @return return an array of Strings of the words found in the dictionary,
- * followed by a space and their base scrabble score.
- *
- * For instance, if you find the word avatar, the array entry should be:
- * "avatar 9" as the letters a, t, r are all worth 1 point each and the
- * letter v is worth 4 points, totaling 9 points
- */
- //done with modification
- public String[] getAllMatchingWords(char[] theLetters)
- {
- for(int l = 0; l < theLetters.length; l++)
- {
- if(theLetters[l] < 'A' || theLetters[l] > 'z')
- {
- throw new IllegalArgumentException("Method [get3to6MatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
- }
- }
- if(theLetters.length > 8)
- {
- throw new IllegalArgumentException("Method [getAllMatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
- }
- ArrayList<String>matchingWords = new ArrayList<String>();
- Scanner in = null;
- try{
- in = new Scanner(new File(dictFile));
- }
- catch(Exception e)
- {
- System.out.println("Unable to access file: [" + dictFile + "]");
- }
- while(in != null && in.hasNext()) //for each word
- {
- boolean valid = true;
- String word = in.nextLine();
- String rack = new String(theLetters);
- for(int i = 0; i<word.length(); i++) //for each letter in word
- {
- char temp = word.charAt(i); //the current letter in the word
- int t2 = rack.indexOf(temp); //index of the character on my rack
- if(t2 < 0) //if temp (the current letter) is not in the rack, then it is not a valid word
- {
- valid = false;
- break;
- }
- else
- {
- if(t2 != 0) //if character is not in the first slot
- {
- if(t2 != rack.length()-1) //if this is not the last character in the rack
- rack = rack.substring(0,t2)+rack.substring(t2 + 1);
- else
- rack = rack.substring(0, t2);
- }
- else //if the character is in index 0
- {
- if(rack.length() > 1)
- rack = rack.substring(t2+1); //remove the first character
- else //if this is the last character in the rack
- rack = ""; //set the rack to null
- }
- }
- }
- if(valid)
- {
- int[] ArrayScores;
- ArrayScores = new int[26];
- Scanner read = null;
- int counter = 0;
- try
- {
- read = new Scanner(new File("letterscores.txt"));
- }
- catch(Exception e)
- {
- System.out.println("Unable to access file: [letterscores.txt]");
- }
- while(read.hasNext())
- {
- read.next();
- ArrayScores[counter] = read.nextInt();
- counter++;
- }
- int count = 0;
- //this section reads the word and calculates it's score based on which characters it contains
- for(int i = 0; i < word.length(); i++)
- {
- char letter = (""+word.charAt(i)).toLowerCase().charAt(0);
- if(letter < 'A' || letter > 'z')
- {
- throw new IllegalArgumentException("Method [getAllMatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
- }
- char temp = 'a';
- for(int j = 0; j<26; j++)
- {
- if(letter == temp)
- {
- count += ArrayScores[j];
- break;
- }
- temp++;
- }
- }
- matchingWords.add(word+" "+count);
- }
- }
- String[] wordsArray = new String[matchingWords.size()];
- matchingWords.toArray(wordsArray);
- return wordsArray;
- }
- /**
- * This method searches the scrabble dictionary for all
- * words that can be formed by the character array of letters
- *
- * @param theLetters - character array of the letters, can be of length 0-8
- * @return return an array of Strings of the words found in the dictionary of
- * 3-6 length words, followed by a space and their base scrabble score.
- *
- * For instance, if you find the word avatar, the array entry should be:
- * "avatar 9" as the letters a, t, r are all worth 1 point each and the
- * letter v is worth 4 points, totaling 9 points
- */
- //done
- public String[] get3to6MatchingWords(char[] theLetters)
- {
- for(int k = 0; k<theLetters.length; k++)
- {
- if(theLetters[k] < 'A' || theLetters[k] > 'z')
- {
- throw new IllegalArgumentException("Method [get3to6MatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
- }
- }
- if(theLetters.length > 8)
- {
- throw new IllegalArgumentException("Method [get3to6MatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
- }
- Scanner in = null;
- ArrayList<String>matchingWords = new ArrayList<String>();
- try
- {
- in = new Scanner(new File(dictFile));
- }
- catch(Exception e)
- {
- System.out.println("Unable to access file: [" + dictFile + "]");
- }
- while(in != null && in.hasNext())
- {
- boolean valid = true;
- String word = in.nextLine(); //scrolls down the file
- String rack = new String(theLetters);
- if(word.length() > 2 && word.length() < 7)
- {
- //TLDR; this section of code removes characters that have been used in order to match words correctly.
- //It took a while to figure out how to use substring and indexOf to correctly remove the object and
- //have the counter correctly reset and move after the rack was modified in order to hit all the objects.
- for(int i = 0; i<word.length(); i++)
- {
- char temp = word.charAt(i);
- if(rack.indexOf(temp) == -1)
- {
- valid = false;
- break;
- }
- else
- {
- int t2 = rack.indexOf(temp);
- if(t2 > 0)
- {
- if(t2 < rack.length()-1)
- rack = rack.substring(0,t2)+rack.substring(t2 + 1);
- else
- rack = rack.substring(0, t2);
- }
- else
- {
- if(t2 < rack.length()-1)
- rack = rack.substring(t2+1);
- else
- rack = "";
- }
- }
- }
- if(valid)
- {
- int[] ArrayScores;
- ArrayScores = new int[26];
- Scanner read = null;
- int counter = 0;
- try
- {
- read = new Scanner(new File("letterscores.txt"));
- }
- catch(Exception e)
- {
- System.out.println("Unable to access file: [letterscores.txt]");
- return null;
- }
- while(read.hasNext())
- {
- read.next();
- ArrayScores[counter] = read.nextInt();
- }
- int count = 0;
- for(int i = 0; i < word.length(); i++)
- {
- char letter = (""+word.charAt(i)).toLowerCase().charAt(0);
- if(letter < 'A' || letter > 'z')
- {
- throw new IllegalArgumentException("Method [get3to6MatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
- }
- char temp = 'a';
- for(int j = 0; j<26; j++)
- {
- if(letter == temp)
- {
- count += ArrayScores[j];
- j = 27;
- }
- temp++;
- }
- }
- matchingWords.add(word+" "+count); //add the string and numeric score to a slot in the ArrayList
- }
- }
- }
- String[] wordsArray = new String[matchingWords.size()];
- matchingWords.toArray(wordsArray);
- return wordsArray;
- }
- /**
- * This method takes in a String array of words and scores and selects the top scoring word
- * and returns it
- *
- * @param theWords - String array formatted like the output from the getAllMatchingWords
- * method
- * @return - String containing the word and score of the top scoring word in the String Array
- */
- //done with modification
- public String getTopScoreWord(String[] theWords)
- {
- String word = null;
- int newScore = -1;
- int score = -1;
- for(int i = 0; i < theWords.length; i++) //iterates through theWords
- {
- String[] splitWords = theWords[i].split(" "); //defines delimiter as a space
- try
- {
- newScore = new Integer(splitWords[1]); //uses split words to grab only the numeric value
- }
- catch(NumberFormatException e)
- {
- throw new IllegalArgumentException("Method [getTopScoreWord] had an invalid parameter [theWords], so the program cannot run correctly.");
- }
- if(score<newScore) //if new score is larger than the previous score - store it as score
- {
- score = newScore;
- word = theWords[i];
- }
- }
- if(word == null)
- throw new IllegalArgumentException("Method [getTopScoreWord] had an invalid parameter [theWords], so the program cannot run correctly.");
- return word;
- }
- /**
- * This method takes in a String array of words and scores and returns the word with the
- * highest score per tile value (score/length)
- *
- * @param theWords - String array formatted like the output from the getAllMatchingWords
- * method
- * @return - String containing the word and score word with the highest score per tile
- * value in the String array
- */
- //done with modification
- public String getTopScorePerTileWord(String[] theWords)
- {
- if(theWords == null)
- {
- throw new IllegalArgumentException("Method [getTopScorePerTileWord] had an invalid parameter [theWords], so the program cannot run correctly.");
- }
- double highestRatio = 0; //stores the highest ratio found among theWords
- int index = -1;
- for(int i = 0; i < theWords.length; i++)
- {
- String[] splitWords = theWords[i].split(" "); //defines delimiter as a space
- double wordscore = -1;
- if(splitWords != null)
- {
- double wordlength = splitWords[0].length(); //calculates the word length
- try{
- wordscore = new Integer(splitWords[1]); //separates the wordscore from the word
- }
- catch(NumberFormatException e)
- {
- throw new IllegalArgumentException("Method [getTopScorePerTileWord] had an invalid parameter [theWords], so the program cannot run correctly.");
- }
- if(wordscore != -1)
- {
- double currentRatio = (wordscore/wordlength); //finds the ratio of the current word
- if(currentRatio>highestRatio) //if this newly calculated ratio is higher than the previously stored ratio - replace it
- {
- highestRatio = currentRatio;
- index = i;
- }
- }
- }
- else
- {
- throw new IllegalArgumentException("Method [getTopScorePerTileWord] had an invalid parameter [theWords], so the program cannot run correctly.");
- }
- }
- if(index == -1) //edge case condition
- {
- throw new IllegalArgumentException("Method [getTopScorePerTileWord] had an invalid parameter [theWords], so the program cannot run correctly.");
- }
- return theWords[index];
- }
- /**
- * This method returns a random word from the file containing only 6 letter words
- *
- * It should NOT append the scrabble score to the word.
- *
- * HINT: Math.random() will probably be very useful for this method.
- *
- * @return - String of the 6 letter word found
- */
- //done with modification
- public String random6LetterWord()
- {
- Scanner in = null;
- try {
- in = new Scanner(new File("words6.txt"));
- } catch (FileNotFoundException e) {
- System.out.println("Unable to access the file: [words6.txt]");
- e.printStackTrace();
- return null;
- } //reads in already separated 6 letter words
- ArrayList<String> randomArray = new ArrayList<String>(); //create new ArrayList to store 6 letter words
- while(in.hasNext())
- {
- randomArray.add(in.nextLine()); //add text from "words6.txt" to cell in ArrayList
- }
- if(!randomArray.isEmpty())
- {
- String randomWord = randomArray.get((int)(Math.random()*randomArray.size())); //generate a random cell in the ArrayList (had to multiply by Array size to get whole numbers)
- return randomWord.split(" ")[0]; //again use space as delimiter - but only return first half (ignore the score)
- }
- else
- {
- return null;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement