In: Computer Science
For this lab you will write a Java program that plays a simple Guess The Word game. The program will prompt the user to enter the name of a file containing a list of words. These words mustbe stored in an ArrayList, and the program will not know how many words are in the file before it starts putting them in the list. When all of the words have been read from the file, the program randomly chooses one word from the list to be the target of the game. The user is then allowed to guess characters one at a time. The program checks to see if the user has previously guessed that character and if it has been previously guessed the program forces the user to guess another character. Otherwise it checks the word to see if that character is part of the target word. If it is, it reveals all of the positions with that target word. The program then asks the user to guess the target, keeping count of the number of guesses. When the user finally guesses the correct word, the program indicates how many guesses it took the user to get it right.
For this assignment you must start with the following "skeleton" of Java code. Import this into your Eclipse workspace and fill in the methods as directed. In addition, for this assignment you MUST add at least one extra method beyond the methods defined in the skeleton. This must be a method that does something useful - if you are stuck for an idea for a method, get the program working first and then see if there is some part of your main method that you can break out to be its own function or procedure instead.
Feel free to add any additional methods you find useful, but for all of the methods you add you must also add comments indicating what they do following the form of the rest of the comments in the code.
NOTE: If the file that the user enters for the word list does not exist or if it is an empty file with no words in it, your program should print the Goodbye! message and exit gracefully without crashing.
/**
* Your description here
* @author ENTER YOUR NAME HERE
* @version ENTER DATE HERE
*
*/
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class WordGuessing {
/**
* Takes a filename as input. Reads a list of words from the file into a
* list and returns the list. Ensures that all of the words in the list are
* in UPPERCASE (i.e. transforms lowercase letters to uppercase before
* adding them to the list). Assumes that the file will be correctly
* formatted with one word per line (though there may be blank lines with
* no words on them). If the file cannot be read prints the
* error message "ERROR: File fname not found!" where "fname" is the name of
* the file and returns an empty list. Note that the order of the words in the
* list must be the same as the order of the words in the file to pass the
* test cases.
*
* @param fname
* the name of the file to read words from
* @return a list of words read from the file in all uppercase letters.
*/
public static List<String> readWords(String fname) {
List<String> words = new ArrayList<String>();
// TODO - complete this function
// TODO - the following line is only here to allow this program to
// compile. Replace it and remove this comment when you complete
// this method.
return words;
}
/**
* Takes a Random object and a list of strings and returns a random String
* from the list. Note that this method must not change the list. The list
* is guaranteed to have one or more elements in it.
*
* @param rnd
* Random number generator object
* @param inList
* list of strings to choose from
* @return an element from a random position in the list
*/
public static String getRandomWord(Random rnd, List<String> inList) {
// TODO - complete this function
// TODO - the following line is only here to allow this program to
// compile. Replace it and remove this comment when you complete
// this method.
return null;
}
/**
* Given a String, returns a StringBuilder object that is the same length
* but is only '*' characters. For example, given the String DOG as input
* returns a StringBuilder object containing "***".
*
* @param inWord
* The String to be starred
* @return a StringBuilder with the same length as inWord, but all stars
*/
public static StringBuilder starWord(String inWord) {
// TODO - complete this function
// TODO - the following line is only here to allow this program to
// compile. Replace it and remove this comment when you complete
// this method.
return null;
}
/**
* Prompts the user to enter a single character. If the user enters a blank
* line or more than one character, give an error message as given in the
* assignment and prompt them again. When the user enters a single
* character, return the uppercase value of the character they typed.
*
* @param inScanner
* A scanner to take user input from
* @return the uppercase value of the character typed by the user.
*/
public static char getCharacterGuess(Scanner inScanner) {
// TODO - complete this function
// TODO - the following line is only here to allow this program to
// compile. Replace it and remove this comment when you complete
// this method.
return 0;
}
/**
* Count the number of times the character ch appears in the String word.
*
* @param ch
* character to count.
* @param word
* String to examine for the character ch.
* @return a count of the number of times the character ch appears in the
* String word
*/
public static int charCount(char ch, String word) {
// TODO - complete this function
// TODO - the following line is only here to allow this program to
// compile. Replace it and remove this comment when you complete
// this method.
return 0;
}
/**
* Modify the StringBuilder object starWord everywhere the char ch appears
* in the String word. For example, if ch is 'G', word is "GEOLOGY", and
* starWord is "**O*O*Y", then this method modifies starWord to be
* "G*O*OGY". Your code should assume that word and starWord are
* the same length.
*
* @param ch
* the character to look for in word.
* @param word
* the String containing the full word.
* @param starWord
* the StringBuilder containing the full word masked by stars.
*/
public static void modifyStarWord(char ch, String word,
StringBuilder starWord) {
// TODO - complete this function
}
public static void main(String[] args) {
// TODO - complete this function
}
}
You can use the following word list for your program, but the list below is the one that the test cases will use. Create a new text file in your project directory and paste the following words into it. Note that your program must be able to deal correctly with blank lines (i.e. ignore them when it reads the file and do not add empty strings to the word list).
MIGHTY crimes FLIGHT FRIGHT Grimes PLACES TRACES plates Fisher fishes WISHES dishes
When your program runs, you must be able to produce the following transcript. Note the behavior that the transcript produces when the player tries to guess a character they have previously guessed, when they enter blank lines for the character or the word guess, and when they enter anything but a 'Y' or 'N' (upper or lowercase) for the rematch question.
Enter a random seed: 33 Enter a filename for your wordlist: words.txt Read 12 words from the file. The word to guess is: ****** Previous characters guessed: [] Enter a character to guess: f The character F occurs in 1 positions. The word to guess is: F***** Enter your guess for the word: flames That is not the word. The word to guess is: F***** Previous characters guessed: [F] Enter a character to guess: i The character I occurs in 1 positions. The word to guess is: F*I*** Enter your guess for the word: flight That is not the word. The word to guess is: F*I*** Previous characters guessed: [F, I] Enter a character to guess: tjkl Enter only a single character! Enter a character to guess: Enter only a single character! Enter a character to guess: t The character T occurs in 1 positions. The word to guess is: F*I**T Enter your guess for the word: That is not the word. The word to guess is: F*I**T Previous characters guessed: [F, I, T] Enter a character to guess: o The character O occurs in 0 positions. The word to guess is: F*I**T Enter your guess for the word: flitter That is not the word. The word to guess is: F*I**T Previous characters guessed: [F, I, T, O] Enter a character to guess: G The character G occurs in 1 positions. The word to guess is: F*IG*T Enter your guess for the word: fight That is not the word. The word to guess is: F*IG*T Previous characters guessed: [F, I, T, O, G] Enter a character to guess: h The character H occurs in 1 positions. The word to guess is: F*IGHT Enter your guess for the word: Fright Yes! FRIGHT is the correct word! That took you 6 guesses. Would you like a rematch [Y/N]?: jsdf Please enter only a Y or an N. Would you like a rematch [Y/N]?: Please enter only a Y or an N. Would you like a rematch [Y/N]?: yes Please enter only a Y or an N. Would you like a rematch [Y/N]?: no Please enter only a Y or an N. Would you like a rematch [Y/N]?: n Goodbye!
Another run of the same program should be able to produce the following transcript:
Enter a random seed: 2048 Enter a filename for your wordlist: words.txt Read 12 words from the file. The word to guess is: ****** Previous characters guessed: [] Enter a character to guess: s The character S occurs in 1 positions. The word to guess is: *****S Enter your guess for the word: slimes That is not the word. The word to guess is: *****S Previous characters guessed: [S] Enter a character to guess: r The character R occurs in 1 positions. The word to guess is: *R***S Enter your guess for the word: grimes That is not the word. The word to guess is: *R***S Previous characters guessed: [S, R] Enter a character to guess: c The character C occurs in 1 positions. The word to guess is: CR***S Enter your guess for the word: crimes Yes! CRIMES is the correct word! That took you 3 guesses. Would you like a rematch [Y/N]?: y The word to guess is: ****** Previous characters guessed: [] Enter a character to guess: s The character S occurs in 2 positions. The word to guess is: **S**S Enter your guess for the word: dishes That is not the word. The word to guess is: **S**S Previous characters guessed: [S] Enter a character to guess: f The character F occurs in 1 positions. The word to guess is: F*S**S Enter your guess for the word: fishes Yes! FISHES is the correct word! That took you 2 guesses. Would you like a rematch [Y/N]?: y The word to guess is: ****** Previous characters guessed: [] Enter a character to guess: s The character S occurs in 1 positions. The word to guess is: *****S Enter your guess for the word: slimes That is not the word. The word to guess is: *****S Previous characters guessed: [S] Enter a character to guess: r The character R occurs in 1 positions. The word to guess is: *R***S Enter your guess for the word: drimes That is not the word. The word to guess is: *R***S Previous characters guessed: [S, R] Enter a character to guess: g The character G occurs in 1 positions. The word to guess is: GR***S Enter your guess for the word: grimes Yes! GRIMES is the correct word! That took you 3 guesses. Would you like a rematch [Y/N]?: n Goodbye!
Please find the answer below, all the details are mentioned in the comments.
WordGuessing.java
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class WordGuessing {
/**
* Takes a filename as input. Reads a list of words from the file into a
* list and returns the list. Ensures that all of the words in the list are
* in UPPERCASE (i.e. transforms lowercase letters to uppercase before
* adding them to the list). Assumes that the file will be correctly
* formatted with one word per line. If the file cannot be read prints the
* error message "ERROR: File fname not found!" where "fname" is the name of
* the file and returns an empty list. Note that the order of the words in the
* list must be the same as the order of the words in the file to pass the
* test cases.
*
* @param fname
* the name of the file to read words from
* @return a list of words read from the file in all uppercase letters.
*/
public static List<String> readWords(String fname) {
List<String> words = new ArrayList<String>();
// TODO - complete this function
// TODO - the following line is only here to allow this program to
// compile. Replace it and remove this comment when you complete
// this method.
//read the file and add the words to the list
try(BufferedReader reader = new BufferedReader(new FileReader(new File(fname)))){
String line;
while((line = reader.readLine())!= null){
if(line.length()>0) {
words.add(line.toUpperCase());
}
}
}
catch (Exception ex){
System.out.println("ERROR: File " + fname + " not found!");
}
return words;
}
/**
* Takes a Random object and a list of strings and returns a random String
* from the list. Note that this method must not change the list. The list
* is guaranteed to have one or more elements in it.
*
* @param rnd
* Random number generator object
* @param inList
* list of strings to choose from
* @return an element from a random position in the list
*/
public static String getRandomWord(Random rnd, List<String> inList) {
// TODO - complete this function
// TODO - the following line is only here to allow this program to
// compile. Replace it and remove this comment when you complete
// this method.
//get the random number from list as index
int index = rnd.nextInt(inList.size());
return inList.get(index);
}
/**
* Given a String, returns a StringBuilder object that is the same length
* but is only '*' characters. For example, given the String DOG as input
* returns a StringBuilder object containing "***".
*
* @param inWord
* The String to be starred
* @return a StringBuilder with the same length as inWord, but all stars
*/
public static StringBuilder starWord(String inWord) {
// TODO - complete this function
// TODO - the following line is only here to allow this program to
// compile. Replace it and remove this comment when you complete
// this method.
//create new StringBuilder object and create it as same length of the secret word
StringBuilder sb = new StringBuilder("");
for(int i=0;i<inWord.length();i++){
sb.append("*");
}
return sb;
}
/**
* Prompts the user to enter a single character. If the user enters a blank
* line or more than one character, give an error message as given in the
* assignment and prompt them again. When the user enters a single
* character, return the uppercase value of the character they typed.
*
* @param inScanner
* A scanner to take user input from
* @return the uppercase value of the character typed by the user.
*/
public static char getCharacterGuess(Scanner inScanner) {
// TODO - complete this function
// TODO - the following line is only here to allow this program to
// compile. Replace it and remove this comment when you complete
// this method.
//get the char from user and validate it
boolean flagToGo = false;
String userIn = "";
while(!flagToGo) {
flagToGo = true;
System.out.print("Enter a character to guess: ");
userIn = inScanner.nextLine();
if (userIn.length() > 1 || userIn.length() <= 0) {
System.out.println("Enter only a single character!");
flagToGo = false;
}
}
return Character.toUpperCase(userIn.charAt(0));
}
/**
* Count the number of times the character ch appears in the String word.
*
* @param ch
* character to count.
* @param word
* String to examine for the character ch.
* @return a count of the number of times the character ch appears in the
* String word
*/
public static int charCount(char ch, String word) {
// TODO - complete this function
// TODO - the following line is only here to allow this program to
// compile. Replace it and remove this comment when you complete
// this method.
//count the character in the string using indexOf method
int index = 0;
int count = 0;
index = word.indexOf(ch);
while(index!=-1){
count++;
index = word.indexOf(ch,index+1);
}
return count;
}
/**
* Modify the StringBuilder object starWord everywhere the char ch appears
* in the String word. For example, if ch is 'G', word is "GEOLOGY", and
* starWord is "**O*O*Y", then this method modifies starWord to be
* "G*O*OGY". Your code should assume that word and starWord are
* the same length.
*
* @param ch
* the character to look for in word.
* @param word
* the String containing the full word.
* @param starWord
* the StringBuilder containing the full word masked by stars.
*/
public static void modifyStarWord(char ch, String word,
StringBuilder starWord) {
// TODO - complete this function
//modify the character in the string using indexOf method
int index = 0;
index = word.indexOf(ch);
while(index!=-1){
starWord.setCharAt(index,ch);
index = word.indexOf(ch,index+1);
}
}
//function to check if input for the continue game is valid or not
public static boolean checkTOContinue(Scanner sc,String in){
if(in.length()==0 || in.length()>1 || (in.length()==1 && (in.charAt(0)!='Y' && in.charAt(0)!='y' && in.charAt(0)!='N' && in.charAt(0)!='n' ))){
return true;
}
return false;
}
public static void main(String[] args) {
// TODO - complete this function
//scanner to read user value
Scanner sc = new Scanner(System.in);
//input from user
String in = "";
//ask intial values to the user : seed,filename
System.out.print("Enter a random seed: ");
int seed = sc.nextInt();
sc.nextLine();
System.out.print("Enter a file name for your wordlist: ");
String filename = sc.nextLine();
//get the list of words from file
List<String> words = readWords(filename);
System.out.println("Read " + words.size() + " words from the file.");
System.out.println();
//get the random number generator
Random rand = new Random(seed);
//loop till user wants but atlease 1 time
do {
System.out.println();
//get the secreat word randomly
String secreatWord = getRandomWord(rand,words);
//generate the guess word
StringBuilder guessWord = starWord(secreatWord);
//to maintain the list of characters entered so far
ArrayList<Character> prevChar = new ArrayList<>();
//to record the number of guesses
int noOfGuess = 0;
boolean flag = true;
//loop till guess doesn't equal to the secreat word
while (!guessWord.toString().equals(secreatWord) && flag) {
//print values for user
System.out.println("The word to Guess is: " + guessWord);
System.out.println("Previous characters guessed: " + prevChar.toString());
//get the character from user
char ch = getCharacterGuess(sc);
noOfGuess++;
int chCount = charCount(ch, secreatWord);
//check if character already exists in the list
if (!prevChar.contains(ch)) {
prevChar.add(ch);
}
System.out.println("The character " + ch + " occurs in " + chCount + " positions.");
System.out.println();
//if character is present in the list ask for word guess
if (chCount > 0) {
modifyStarWord(ch, secreatWord, guessWord);
System.out.println("The word to guess is: " + guessWord);
System.out.print("Enter your guess for the word: ");
String word = sc.nextLine();
//if user guesses the correct word
if (word.equalsIgnoreCase(secreatWord)) {
System.out.println("Yes!" + secreatWord + " is the correct word!");
System.out.println("That took you " + noOfGuess + " guesses.");
flag = false;
} else {
System.out.println("That is not the word.");
System.out.println();
}
}
}
//ask user if user wants to continue or not
System.out.print("Would you like a rematch [Y/N]?: ");
in = sc.nextLine();
while(checkTOContinue(sc,in)){
System.out.println("Please enter only a Y or an N.");
System.out.print("Would you like a rematch [Y/N]?: ");
in = sc.nextLine();
}
}while(in.charAt(0) == 'Y' || in.charAt(0) == 'y');
System.out.println("Goodbye!");
}
}
Output:



Output 2:



Please let us know in the comments if you face any problems.