Advertisement
Guest User

Untitled

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