/* Hangman Game written by Keith Fenske Friday, 24 May 2002 Copyright (c) 2002 by Keith Fenske. All rights reserved. This Java program plays the word-guessing game called "Hangman". Hangman is easy to play on paper, but has many special conditions that must be tested for to play the game well. There are different ways of implementing each part of this game. The methods below were chosen to demonstrate programming in Java. */ import cs1.Keyboard; // import Lewis/Loftus keyboard class // http://duke.csc.villanova.edu/jss/keyboard.html public class Hangman { static final int MAXGUESS = 8; // maximum number of guesses per word static final int MAXLETTER = 'z' - 'a' + 1; // number of letters in the alphabet static final String[] WORDS = {"apple", "banana", "cat", "dog", "elephant", "fish", "giraffe", "hippopotamus", "ice cream", "jelly", "kangaroo", "lion", "monkey", "noodles", "octopus", "parrot", "queen", "rabbit", "sun", "tree", "umbrella", "van", "window", "x-ray", "yellow", "zebra"}; public static void main(String[] args) { boolean again; // true while we play another game String answer; // user's input System.out.println("\nThis is the word guessing game called Hangman."); System.out.println("The computer will pick a word and you must try to"); System.out.println("guess the letters in the word. If you guess the"); System.out.println("word with less than " + MAXGUESS + " mistakes, then you win!"); do { playGame(); // play one game of Hangman System.out.println("\nWould you like to play another game? (YES or NO)"); answer = Keyboard.readString(); if (answer.equalsIgnoreCase("yes")) again = true; else if (answer.equalsIgnoreCase("no")) again = false; else { again = false; System.out.println("Your answer \"" + answer + "\" should be YES or NO."); } } while (again); System.out.println("\nThank you for playing Hangman!"); } // end of main() /* playGame() method Play one game of Hangman. There are no parameters for this method, and there is no result. */ static void playGame() { boolean[] already; // if user already guessed these letters char c; // temporary variable for a character boolean[] display; // if we display each letter in word int found; // how many times we find user's guess int i; // temporary variable for index loop char inputChar; // user's input (as one character) String inputString; // user's input (as a string) int length; // length of our random word int letters; // actual letters in word (not " " or "-") int mistakes; // number of mistakes made boolean playing; // true while we are playing game String word; // our random word from WORDS list mistakes = 0; // start with no mistakes // Pick a random word from our WORDS list. word = WORDS[(int)(Math.random() * WORDS.length)]; // System.out.println("debug: word = '" + word + "'"); length = word.length(); // get length of random word // Create a "display" array to decide if we display a letter in the // word. Note that some words have spaces (" ") or hyphens ("-"), and // those are given free to the user. display = new boolean[length]; letters = 0; // actual letters in word for (i = 0; i < length; i ++) { c = word.charAt(i); // get one character from word if ((c >= 'a') && (c <= 'z')) { display[i] = false; // hide all letters letters ++; // count number of letters found } else display[i] = true; // not a letter: show special characters } System.out.print("\nI am thinking of a word. "); if (letters == 1) System.out.println("The word has one letter."); else System.out.println("The word has " + letters + " letters."); // Make a boolean array to remember which letters the user has guessed. already = new boolean[MAXLETTER]; for (i = 0; i < MAXLETTER; i ++) already[i] = false; // Ask the user for his/her guess in a loop. playing = true; // we are playing the game while (playing) { // Display the word, with unknown letters marked by "*". System.out.print("\nThe word is:"); for (i = 0; i < length; i ++) { System.out.print(" "); // put a space between letters if (display[i]) System.out.print(word.charAt(i)); else System.out.print("*"); } System.out.print("\nWhat is your guess? "); if ((MAXGUESS - mistakes) <= 1) System.out.println("This is your last guess!"); else System.out.println("You have " + (MAXGUESS - mistakes) + " guesses remaining."); inputString = Keyboard.readString(); inputString = inputString.trim(); // remove leading/trailing spaces inputString = inputString.toLowerCase(); // convert 'A' to 'a', etc. if (inputString.length() == length) { // User is guessing the whole word. if (word.equals(inputString)) { System.out.println("Yes, the word is \"" + word + "\"!"); printMistakes(mistakes); playing = false; } else { System.out.println("Sorry, the word is not \"" + inputString + "\"."); mistakes ++; } } else if (inputString.length() != 1) { System.out.println("Your guess \"" + inputString + "\" must be one letter or the entire word."); } else { // User is guessing one letter. inputChar = inputString.charAt(0); if ((inputChar < 'a') || (inputChar > 'z')) { // User's input is not a letter. System.out.println("Your guess \"" + inputChar + "\" must be a letter from A to Z, or the entire word."); } else if (already[inputChar - 'a']) { // User already guessed this letter. Don't count as a mistake. System.out.print("You have already guessed the following letters:"); for (i = 0; i < MAXLETTER; i ++) if (already[i]) System.out.print(" " + (char)(i + 'a')); System.out.println(); } else { // Count how many times this letter is in the word, and change the // variables that control the display. already[inputChar - 'a'] = true; // this letter is now used found = 0; // clear matching letters found for (i = 0; i < length; i ++) if (word.charAt(i) == inputChar) { display[i] = true; found ++; } if (found <= 0) { System.out.println("Sorry, the letter \"" + inputChar + "\" is not in the word."); mistakes ++; } else { // Tell the user how many letters were found. Make a special // grammar case for the number one. if (found == 1) System.out.println("Yes, there is one letter \"" + inputChar + "\" in the word."); else System.out.println("Yes, there are " + found + " letters \"" + inputChar + "\" in the word."); // Check if the whole word has now been guessed. playing = false; // assume we are finished for (i = 0; i < length; i ++) playing = playing || !display[i]; if (!playing) { System.out.println("You found all the letters in the word \"" + word + "\"."); printMistakes(mistakes); } } } } if (mistakes >= MAXGUESS) { System.out.println("The word was \"" + word + "\"."); playing = false; } } } // end of playGame() /* printMistakes() method Tell the user how many mistakes he made before guessing the word. This method is called from two different places in playGame() so it is easier to have a separate method. The parameter is an integer number of mistakes. */ static void printMistakes(int n) { if (n <= 0) System.out.println("You didn't make any mistakes. Excellent!"); else if (n == 1) System.out.println("You made only one mistake. Great!"); else System.out.println("You made only " + n + " mistakes. Good!"); } } // end of class