Advertisement
Guest User

Untitled

a guest
Jul 20th, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.29 KB | None | 0 0
  1. import java.util.*;
  2. import java.io.*;
  3. import java.math.*;
  4.  
  5. /**
  6.  * This program takes a given rack of letters (in an array)
  7.  * and finds words in a dictionary file that can be
  8.  * made from that given rack. Then, it computes the scores for
  9.  * each matching word and returns them to the user based on
  10.  * the desired word length (3-6 characters). Also, it has to
  11.  * randomly select a 6 letter word from a generated text file.
  12.  * Lastly, it needs to computer the top word score and the highest
  13.  * word score per tile value.
  14.  *
  15.  *
  16.  * @author Zach VanDuyn
  17.  *
  18.  * CS1122, Spring 2011
  19.  * Bryan Franklin
  20.  */
  21.  
  22.  
  23. public class ScrabbleSolver
  24. {
  25.     private String dictFile;
  26.  
  27.  
  28.     /**
  29.      * Constructor for the ScrabbleSolver Object
  30.      * This should create the files containing the lists of
  31.      * 3-6 letter words and only 6 letter words, as well as initialize
  32.      * any other class variables you need for the other methods
  33.      *
  34.      * @param dictFilename - filename of the dictionary text file
  35.      * @param scoreFilename - filename of the letter score text file
  36.      */
  37.     public ScrabbleSolver(String dictFilename, String scoreFilename)
  38.     {
  39.         dictFile = dictFilename;
  40.         Scanner in = null;
  41.         try
  42.         {
  43.             in = new Scanner(new File(scoreFilename));
  44.         }
  45.         catch(Exception e)
  46.         {
  47.             System.out.println("Unable to access file: [" + scoreFilename + "]");
  48.         }
  49.         try{
  50.             in = new Scanner(new File(dictFilename));
  51.         }
  52.         catch(Exception e)
  53.         {
  54.             System.out.println("Unable to access file: [" + dictFilename + "]");
  55.         }
  56.        
  57.  
  58.         PrintWriter dict36 = null;
  59.         try {
  60.             dict36 = new PrintWriter("words3-6.txt");
  61.         } catch (FileNotFoundException e) {
  62.             System.out.println("Unable to access file: words3-6.txt");
  63.             e.printStackTrace();
  64.         } //allows us to write to "words3-6.txt"
  65.         PrintWriter dict6 = null;
  66.         try {
  67.             dict6 = new PrintWriter("words6.txt");
  68.         } catch (FileNotFoundException e) {
  69.             System.out.println("Unable to access file: words6.txt");
  70.             e.printStackTrace();
  71.         } //allows us to write to "words6.txt"
  72.  
  73.         while(in != null && in.hasNext())
  74.         {
  75.             String word = in.nextLine();
  76.             if(word.length() > 2 && word.length() < 7) //makes sure the words length is between three and six
  77.             {
  78.                 if(dict36 != null)
  79.                     dict36.println(word);
  80.                 if(dict6 != null && word.length() == 6) //if it is exactly six in length - store it in the "words6.txt"
  81.                 {
  82.                     dict6.println(word);
  83.                 }
  84.  
  85.             }
  86.         }
  87.         if(dict36 != null)
  88.             dict36.close(); //closing the stream saves the changes on dict36 ("words3-6.txt")
  89.         if(dict6 != null)
  90.             dict6.close(); //closing the stream saves the changes on dict6 ("words6.txt")
  91.  
  92.     }
  93.  
  94.     /**
  95.      * This method searches the scrabble dictionary for all
  96.      * words that can be formed by the character array of letters
  97.      *
  98.      * @param theLetters - character array of the letters, can be of length 0-8
  99.      * @return return an array of Strings of the words found in the dictionary,
  100.      * followed by a space and their base scrabble score.
  101.      *
  102.      * For instance, if you find the word avatar, the array entry should be:
  103.      * "avatar 9" as the letters a, t, r are all worth 1 point each and the
  104.      * letter v is worth 4 points, totaling 9 points
  105.      */
  106.     //done with modification
  107.     public String[] getAllMatchingWords(char[] theLetters)
  108.     {
  109.         for(int l = 0; l < theLetters.length; l++)
  110.         {
  111.             if(theLetters[l] < 'A' || theLetters[l] > 'z')
  112.             {
  113.                 throw new IllegalArgumentException("Method [get3to6MatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
  114.  
  115.             }
  116.         }
  117.         if(theLetters.length > 8)
  118.         {
  119.             throw new IllegalArgumentException("Method [getAllMatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
  120.         }
  121.  
  122.         ArrayList<String>matchingWords = new ArrayList<String>();
  123.         Scanner in = null;
  124.         try{
  125.             in = new Scanner(new File(dictFile));
  126.         }
  127.         catch(Exception e)
  128.         {
  129.             System.out.println("Unable to access file: [" + dictFile + "]");
  130.         }
  131.         while(in != null && in.hasNext()) //for each word
  132.         {
  133.             boolean valid = true;
  134.             String word = in.nextLine();
  135.             String rack = new String(theLetters);
  136.             for(int i = 0; i<word.length(); i++) //for each letter in word
  137.             {
  138.                 char temp = word.charAt(i);  //the current letter in the word
  139.                 int t2 = rack.indexOf(temp); //index of the character on my rack
  140.                 if(t2 < 0) //if temp (the current letter) is not in the rack, then it is not a valid word
  141.                 {
  142.                     valid = false;
  143.                     break;
  144.                 }
  145.                 else
  146.                 {
  147.                     if(t2 != 0) //if character is not in the first slot
  148.                     {
  149.                         if(t2 != rack.length()-1) //if this is not the last character in the rack
  150.  
  151.                             rack = rack.substring(0,t2)+rack.substring(t2 + 1);
  152.                         else
  153.                             rack = rack.substring(0, t2);
  154.                     }
  155.                     else //if the character is in index 0
  156.                     {
  157.                         if(rack.length() > 1)  
  158.                             rack = rack.substring(t2+1);  //remove the first character
  159.  
  160.                         else //if this is the last character in the rack
  161.                             rack = "";  //set the rack to null
  162.                     }
  163.                 }
  164.             }
  165.             if(valid)
  166.  
  167.             {
  168.                 int[] ArrayScores;
  169.                 ArrayScores = new int[26];  
  170.                 Scanner read = null;
  171.                 int counter = 0;
  172.                 try
  173.                 {
  174.                     read = new Scanner(new File("letterscores.txt"));
  175.                 }
  176.                 catch(Exception e)
  177.                 {
  178.                     System.out.println("Unable to access file: [letterscores.txt]");
  179.                 }
  180.                 while(read.hasNext())
  181.                 {
  182.                     read.next();
  183.                     ArrayScores[counter] = read.nextInt();
  184.                     counter++;
  185.                 }
  186.                 int count = 0;
  187.                 //this section reads the word and calculates it's score based on which characters it contains
  188.                 for(int i = 0; i < word.length(); i++)
  189.                 {  
  190.                     char letter = (""+word.charAt(i)).toLowerCase().charAt(0);
  191.                     if(letter < 'A' || letter > 'z')
  192.                     {
  193.                         throw new IllegalArgumentException("Method [getAllMatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
  194.  
  195.                     }
  196.                     char temp = 'a';
  197.                     for(int j = 0; j<26; j++)
  198.                     {
  199.                         if(letter == temp)
  200.                         {
  201.                             count += ArrayScores[j];
  202.                             break;
  203.                         }
  204.                         temp++;
  205.                     }
  206.                 }
  207.                 matchingWords.add(word+" "+count);
  208.             }
  209.         }
  210.  
  211.         String[] wordsArray = new String[matchingWords.size()];
  212.         matchingWords.toArray(wordsArray);
  213.         return wordsArray;
  214.  
  215.     }
  216.  
  217.     /**
  218.      * This method searches the scrabble dictionary for all
  219.      * words that can be formed by the character array of letters
  220.      *
  221.      * @param theLetters - character array of the letters, can be of length 0-8
  222.      * @return return an array of Strings of the words found in the dictionary of
  223.      * 3-6 length words, followed by a space and their base scrabble score.
  224.      *
  225.      * For instance, if you find the word avatar, the array entry should be:
  226.      * "avatar 9" as the letters a, t, r are all worth 1 point each and the
  227.      * letter v is worth 4 points, totaling 9 points
  228.      */
  229.     //done
  230.     public String[] get3to6MatchingWords(char[] theLetters)
  231.     {
  232.         for(int k = 0; k<theLetters.length; k++)
  233.         {
  234.             if(theLetters[k] < 'A' || theLetters[k] > 'z')
  235.             {
  236.                 throw new IllegalArgumentException("Method [get3to6MatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
  237.  
  238.             }
  239.         }
  240.         if(theLetters.length > 8)
  241.         {
  242.             throw new IllegalArgumentException("Method [get3to6MatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
  243.         }
  244.         Scanner in = null;
  245.  
  246.         ArrayList<String>matchingWords = new ArrayList<String>();
  247.         try
  248.         {          
  249.             in = new Scanner(new File(dictFile));
  250.         }
  251.         catch(Exception e)
  252.         {
  253.             System.out.println("Unable to access file: [" + dictFile + "]");
  254.         }
  255.         while(in != null && in.hasNext())
  256.         {
  257.             boolean valid = true;
  258.             String word = in.nextLine(); //scrolls down the file
  259.             String rack = new String(theLetters);
  260.             if(word.length() > 2 && word.length() < 7)
  261.             {
  262.                 //TLDR; this section of code removes characters that have been used in order to match words correctly.
  263.                 //It took a while to figure out how to use substring and indexOf to correctly remove the object and
  264.                 //have the counter correctly reset and move after the rack was modified in order to hit all the objects.
  265.                 for(int i = 0; i<word.length(); i++)
  266.                 {
  267.                     char temp = word.charAt(i);
  268.                     if(rack.indexOf(temp) == -1)
  269.                     {
  270.                         valid = false;
  271.                         break;
  272.                     }
  273.                     else
  274.                     {
  275.  
  276.                         int t2 = rack.indexOf(temp);
  277.                         if(t2 > 0)
  278.                         {
  279.                             if(t2 < rack.length()-1)
  280.  
  281.                                 rack = rack.substring(0,t2)+rack.substring(t2 + 1);
  282.                             else
  283.                                 rack = rack.substring(0, t2);
  284.                         }
  285.                         else
  286.                         {
  287.                             if(t2 < rack.length()-1)
  288.                                 rack = rack.substring(t2+1);
  289.  
  290.                             else
  291.                                 rack = "";
  292.                         }
  293.                     }
  294.                 }
  295.                 if(valid)
  296.                 {
  297.                     int[] ArrayScores;
  298.                     ArrayScores = new int[26];  
  299.                     Scanner read = null;
  300.                     int counter = 0;
  301.                     try
  302.                     {
  303.                         read = new Scanner(new File("letterscores.txt"));
  304.                     }
  305.                     catch(Exception e)
  306.                     {
  307.                         System.out.println("Unable to access file: [letterscores.txt]");
  308.                         return null;
  309.                     }
  310.                     while(read.hasNext())
  311.                     {
  312.                         read.next();
  313.                         ArrayScores[counter] = read.nextInt();
  314.                     }
  315.                     int count = 0;
  316.                     for(int i = 0; i < word.length(); i++)
  317.                     {  
  318.                         char letter = (""+word.charAt(i)).toLowerCase().charAt(0);
  319.                         if(letter < 'A' || letter > 'z')
  320.                         {
  321.                             throw new IllegalArgumentException("Method [get3to6MatchingWords] had an invalid parameter [theLetters], so the program cannot run correctly.");
  322.  
  323.                         }
  324.                         char temp = 'a';
  325.                         for(int j = 0; j<26; j++)
  326.                         {
  327.                             if(letter == temp)
  328.                             {
  329.                                 count += ArrayScores[j];
  330.                                 j = 27;
  331.                             }
  332.                             temp++;
  333.                         }
  334.                     }
  335.                     matchingWords.add(word+" "+count); //add the string and numeric score to a slot in the ArrayList
  336.                 }
  337.             }
  338.         }
  339.  
  340.         String[] wordsArray = new String[matchingWords.size()];
  341.         matchingWords.toArray(wordsArray);
  342.         return wordsArray;
  343.  
  344.     }
  345.  
  346.  
  347.     /**
  348.      * This method takes in a String array of words and scores and selects the top scoring word
  349.      * and returns it
  350.      *
  351.      * @param theWords - String array formatted like the output from the getAllMatchingWords
  352.      * method
  353.      * @return - String containing the word and score of the top scoring word in the String Array
  354.      */
  355.     //done with modification
  356.     public String getTopScoreWord(String[] theWords)
  357.     {
  358.         String word = null;
  359.         int newScore = -1;
  360.         int score = -1;
  361.         for(int i = 0; i < theWords.length; i++) //iterates through theWords
  362.         {
  363.             String[] splitWords = theWords[i].split(" "); //defines delimiter as a space
  364.             try
  365.             {
  366.                 newScore = new Integer(splitWords[1]); //uses split words to grab only the numeric value               
  367.             }
  368.             catch(NumberFormatException e)
  369.             {
  370.                 throw new IllegalArgumentException("Method [getTopScoreWord] had an invalid parameter [theWords], so the program cannot run correctly.");
  371.             }
  372.             if(score<newScore) //if new score is larger than the previous score - store it as score
  373.             {
  374.                 score = newScore;
  375.                 word = theWords[i];
  376.             }
  377.         }
  378.         if(word == null)
  379.             throw new IllegalArgumentException("Method [getTopScoreWord] had an invalid parameter [theWords], so the program cannot run correctly.");
  380.         return word;
  381.     }
  382.  
  383.  
  384.     /**
  385.      * This method takes in a String array of words and scores and returns the word with the
  386.      * highest score per tile value (score/length)
  387.      *
  388.      * @param theWords - String array formatted like the output from the getAllMatchingWords
  389.      * method
  390.      * @return - String containing the word and score word with the highest score per tile
  391.      * value in the String array
  392.      */
  393.     //done with modification
  394.     public String getTopScorePerTileWord(String[] theWords)
  395.     {
  396.         if(theWords == null)
  397.         {
  398.             throw new IllegalArgumentException("Method [getTopScorePerTileWord] had an invalid parameter [theWords], so the program cannot run correctly.");
  399.         }  
  400.         double highestRatio = 0; //stores the highest ratio found among theWords
  401.         int index = -1;
  402.         for(int i = 0; i < theWords.length; i++)
  403.         {
  404.  
  405.             String[] splitWords = theWords[i].split(" "); //defines delimiter as a space
  406.             double wordscore = -1;
  407.  
  408.             if(splitWords != null)
  409.             {  
  410.                 double wordlength = splitWords[0].length(); //calculates the word length
  411.                 try{
  412.                     wordscore = new Integer(splitWords[1]); //separates the wordscore from the word
  413.                 }
  414.                 catch(NumberFormatException e)
  415.                 {
  416.                     throw new IllegalArgumentException("Method [getTopScorePerTileWord] had an invalid parameter [theWords], so the program cannot run correctly.");
  417.  
  418.                 }
  419.                 if(wordscore != -1)
  420.                 {
  421.                     double currentRatio = (wordscore/wordlength); //finds the ratio of the current word
  422.                     if(currentRatio>highestRatio) //if this newly calculated ratio is higher than the previously stored ratio - replace it
  423.                     {
  424.                         highestRatio = currentRatio;
  425.                         index = i;
  426.                     }
  427.                 }
  428.             }
  429.             else
  430.             {
  431.                 throw new IllegalArgumentException("Method [getTopScorePerTileWord] had an invalid parameter [theWords], so the program cannot run correctly.");
  432.             }
  433.         }
  434.         if(index == -1) //edge case condition
  435.         {
  436.             throw new IllegalArgumentException("Method [getTopScorePerTileWord] had an invalid parameter [theWords], so the program cannot run correctly.");
  437.         }
  438.         return theWords[index];
  439.     }
  440.  
  441.  
  442.     /**
  443.      * This method returns a random word from the file containing only 6 letter words
  444.      *
  445.      * It should NOT append the scrabble score to the word.
  446.      *
  447.      * HINT:  Math.random() will probably be very useful for this method.
  448.      *
  449.      * @return - String of the 6 letter word found
  450.      */
  451.     //done with modification
  452.     public String random6LetterWord()
  453.     {
  454.         Scanner in = null;
  455.         try {
  456.             in = new Scanner(new File("words6.txt"));
  457.         } catch (FileNotFoundException e) {
  458.             System.out.println("Unable to access the file: [words6.txt]");
  459.             e.printStackTrace();
  460.             return null;
  461.         } //reads in already separated 6 letter words
  462.         ArrayList<String> randomArray = new ArrayList<String>(); //create new ArrayList to store 6 letter words
  463.         while(in.hasNext())
  464.         {
  465.             randomArray.add(in.nextLine()); //add text from "words6.txt" to cell in ArrayList
  466.         }
  467.         if(!randomArray.isEmpty())
  468.         {
  469.             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)
  470.             return randomWord.split(" ")[0]; //again use space as delimiter - but only return first half (ignore the score)
  471.         }
  472.         else
  473.         {
  474.             return null;
  475.         }
  476.  
  477.     }
  478.  
  479. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement