import java.io.*; import java.util.Random; import java.util.StringTokenizer; public class WheelOfFortune { /* * Instance variables. */ private Random randGen; // For random character guessing. /* * These int variables keep track of the players' scores. */ private int humansScoreForRound; private int computersScoreForRound; private int humansTotalScore = 0; private int computersTotalScore = 0; /* * These BufferedReaders are for keyboard input and file input. */ private BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in)); private BufferedReader fileInput; /* * These booleans are for controlling the loops for turns of play. */ private boolean turnOver; private boolean roundOver; private String secretPhrase; /* The phrase to be guessed. */ /* * The part of the phrase revealed to the players. It is a StringBuffer * so we can modify it easily. */ private StringBuffer pattern; /* * The main program gets the command line arguments and uses them * to start a game. */ public static void main(String[] args) { WheelOfFortune theWheel = new WheelOfFortune(); // Instance of the class. try { theWheel.fileInput = new BufferedReader(new FileReader(args[0])); theWheel.randGen = new Random(Integer.parseInt(args[1])); theWheel.playGame(); } catch(Exception e) // Probably caused by bad command-line arguments. { System.out.println("Usage: WheelOfFortune "); e.printStackTrace(); } } /* * Run the main loops for controlling the game. */ public void playGame() { try { /* * Loop for each line read from the file. This loop control is * a typical idiom for controlling a loop to read each line * from a file. It assigns the line input from the file to * the String variable secretPhrase. The assignment statement * is also an expression evaluating to the String assigned. * So it compares this expression to null so it won't * execute the body of the loop when it reaches the end * of the file. */ while ((secretPhrase = fileInput.readLine()) != null) { makePattern(); // Use * to hide the secret phrase. /* Initialize the state of a round. */ roundOver = false; humansScoreForRound = 0; computersScoreForRound = 0; while (!roundOver) // Loop until someone guesses the secret phrase. { turnOver = false; while (!turnOver) // Loop until human guesses wrong. { System.out.println(pattern); humanGuess(); } if (roundOver) // The human finished the secret phrase. { break; // So we jump out of round loop and start the next round. } turnOver = false; while(!turnOver) // Loop until computer guesses wrong. { computerGuess(); } } showRoundResult(); } showGameResult(); } catch(IOException e) { System.out.println("Something went wrong reading file."); e.printStackTrace(); } } /* * Initialize the pattern by replacing the words with *'s. */ private void makePattern() { pattern = new StringBuffer(); StringTokenizer t = new StringTokenizer(secretPhrase); while (t.hasMoreTokens()) // Loop for each word in the phrase. { hideWord(t.nextToken()); pattern.append(' '); // The space between the words. } } /* * Given a word, generate a StringBuffer of *'s of the same length. */ private void hideWord(String w) { for (int i = 1; i <= w.length(); i++) { pattern.append('*'); } } /* * Reveal all occurrences of the given character in the pattern. */ private void updatePattern(char c) { int pos = -1; /* * Loop for each occurrence of the character in the word. * Note that the indexOf function returns -1 if the character * is not found, so we can use this to control the loop. * Similar to the loop through each line in the file, this * loop control combines an assignment with a comparison. */ while ((pos = secretPhrase.indexOf(c, ++pos)) != -1) { pattern.setCharAt(pos, c); // Replace the * with the character. } } /* * Count the number of occurrences of the character in the pattern. */ private int numOccurrences(char c, String s) { int count = 0; int pos = -1; /* Loop for each occurrence of the character in the word. */ while ((pos = secretPhrase.indexOf(c, ++pos)) != -1) { count++; } return count; } /* * Return true if and only if all characters in the word have been revealed. */ private boolean isPatternComplete() { return (pattern.toString().indexOf('*') == -1); // No more *'s. } /* * One turn by the human player. */ private void humanGuess() { while (!turnOver) // Keep guessing until player guesses wrong. { System.out.println("Please guess a letter."); char guess; try { guess = userInput.readLine().charAt(0); // First letter of input line. guess = Character.toUpperCase(guess); // Convert to upper case. } catch(IOException e) { e.printStackTrace(); guess = 'A'; // If the I/O fails, default to 'A'. } /* * If the letter is in the secret phrase but hasn't been guessed * already and been revealed in the pattern, then it's a right guess. */ if ((secretPhrase.indexOf(guess) != -1) && (pattern.toString().indexOf(guess) == -1)) { updatePattern(guess); // Reveal the occurrences of the letter. System.out.println(pattern); humansScoreForRound += numOccurrences(guess, secretPhrase); System.out.println("You guessed right."); System.out.println("Your score is now " + humansScoreForRound + "."); if (isPatternComplete()) // The human found the secret phrase. { turnOver = true; roundOver = true; System.out.println("You win this round."); humansTotalScore += humansScoreForRound; } } else // It's a wrong guess. { System.out.println("You guessed wrong."); turnOver = true; } } } /* * One turn by the computer player. */ private void computerGuess() { while (!turnOver) { char guess = randomChar(); System.out.println("The computer guesses " + guess + "." ); /* * If the letter is in the secret phrase but hasn't been guessed * already and been revealed in the pattern, then it's a right guess. */ if ((secretPhrase.indexOf(guess) != -1) && (pattern.toString().indexOf(guess) == -1)) { updatePattern(guess); // Reveal the occurrences of the letter. System.out.println(pattern); computersScoreForRound += numOccurrences(guess, secretPhrase); System.out.println("The computer guessed right."); System.out.println("The computer's score is now " + computersScoreForRound + "."); if (isPatternComplete()) // The computer found the secret phrase. { turnOver = true; roundOver = true; System.out.println("The computer wins this round."); computersTotalScore += computersScoreForRound; } } else // It's a wrong guess. { System.out.println("The computer guessed wrong."); turnOver = true; } } } /* * Generate a random letter from 'A' to 'Z'. */ private char randomChar() { return (char)('A' + randGen.nextInt(26)); } /* * Print out the results of one round. */ private void showRoundResult() { System.out.println("Your total score for all rounds is now " + humansTotalScore + "."); System.out.println("The computer's total score for all rounds is now " + computersTotalScore + "."); } /* * Print out the results of the game. */ private void showGameResult() { if (humansTotalScore > computersTotalScore) { System.out.println("You win this game."); } else if (humansTotalScore < computersTotalScore) { System.out.println("The computer wins this game."); } else { System.out.println("The game is tied."); } } }