CIS 162[M] Laboratory Activity #07:
More Experience with an Array — Hangman

2009:October:19(Mon)

Introduction

There's a stereotype that there's too much violence in computer-games. Well... let's go ahead and conform to this stereotype by writing a program for someone to play the game of "Hangman". (Would you prefer "Wheel of Fortune"? You know, there are further stereotypes such as banality/mind-numbingness associated with television... ;-}

Sample Output(s)

Here are sample outputs showing how this game should proceed, played once unsuccessfully  and then once sucessfully:
Welcome to the game of Hangman!

     ______   
     |    |   
     |        
     |        
     |        
     |        
   __|_____   
   |      |___
   |_________|

_ _ _ _ _ _ _ _ 

Enter a guess:  e
Good, 'e' is in the word.

_ _ _ _ _ _ e _ 

Enter a guess:  t
Good, 't' is in the word.

_ _ _ _ _ t e _ 

Enter a guess:  a
Sorry, 'a' is not in the word.

     ______   
     |    |   
     |    O   
     |        
     |        
     |        
   __|_____   
   |      |___
   |_________|

_ _ _ _ _ t e _ 

Enter a guess:  o
Good, 'o' is in the word.

_ o _ _ _ t e _ 

Enter a guess:  i
Sorry, 'i' is not in the word.

     ______   
     |    |   
     |    O   
     |    |  
     |        
     |        
   __|_____   
   |      |___
   |_________|

_ o _ _ _ t e _ 

Enter a guess:  n
Sorry, 'n' is not in the word.

     ______   
     |    |   
     |    O   
     |    |  
     |    |   
     |        
   __|_____   
   |      |___
   |_________|

_ o _ _ _ t e _ 

Enter a guess:  s
Sorry, 's' is not in the word.

     ______   
     |    |   
     |    O   
     |    |  
     |    |   
     |   /    
   __|_____   
   |      |___
   |_________|

_ o _ _ _ t e _ 

Enter a guess:  h
Sorry, 'h' is not in the word.

     ______   
     |    |   
     |    O   
     |   /|   
     |    |   
     |   /    
   __|_____   
   |      |___
   |_________|

_ o _ _ _ t e _ 

Enter a guess:  r
Good, 'r' is in the word.

_ o _ _ _ t e r 

Enter a guess:  d
Sorry, 'd' is not in the word.

     ______   
     |    |   
     |    O   
     |   /|\  
     |    |   
     |   /    
   __|_____   
   |      |___
   |_________|

_ o _ _ _ t e r 

Enter a guess:  l
Sorry, 'l' is not in the word.

     ______   
     |    |   
     |    O   
     |   /|\  
     |    |   
     |   / \  
   __|_____   
   |      |___
   |_________|

Sorry, the limit for incorrect guesses is 7.
The word was "computer".
Better luck next time you play Hangman!


Welcome to the game of Hangman!

     ______   
     |    |   
     |        
     |        
     |        
     |        
   __|_____   
   |      |___
   |_________|

_ _ _ _ _ _ _ 

Enter a guess:  a
Sorry, 'a' is not in the word.

     ______   
     |    |   
     |    O   
     |        
     |        
     |        
   __|_____   
   |      |___
   |_________|

_ _ _ _ _ _ _ 

Enter a guess:  e
Good, 'e' is in the word.

_ _ _ e _ _ e 

Enter a guess:  i
Good, 'i' is in the word.

_ _ i e _ _ e 

Enter a guess:  o
Sorry, 'o' is not in the word.

     ______   
     |    |   
     |    O   
     |    |  
     |        
     |        
   __|_____   
   |      |___
   |_________|

_ _ i e _ _ e 

Enter a guess:  t
Sorry, 't' is not in the word.

     ______   
     |    |   
     |    O   
     |    |  
     |    |   
     |        
   __|_____   
   |      |___
   |_________|

_ _ i e _ _ e 

Enter a guess:  n
Good, 'n' is in the word.

_ _ i e n _ e 

Enter a guess:  s
Good, 's' is in the word.

s _ i e n _ e 

Enter a guess:  c
Good, 'c' is in the word.

s c i e n c e 

You guessed all of the word; very good!

Outline of Specification

I'm providing a framework and some of the code for this program below. The organization of it is as follows:
display()
This method/function needs to display the elements of an array of characters on one line separated by spaces.
You need to write this method/function. Specific instructions for the code you should write are in comments in the provided code (below).

equivalent()
This method/function needs to determine whether the characters in an array are the same as the characters in a String.
You need to write this method/function. Specific instructions for the code you should write are in comments in the provided code (below).

MAX_ERRS
This constant has the value of the maximum number of incorrect guesses the player can make.
You need to write this code, as specified below in a comment in the program.

main()
As usual, this method is the main thread of execution of the program. It uses the other elements of the code (the methods/functions etc. discussed above and below) as needed.
You need to complete some code in main() to declare some variables and implement the main loop, repeatedly handling the player's guesses. Specific instructions for the code you should write are in comments in main() below.

init_word()
This method/function picks a word for the player to guess.
This method/function has already been written for you; you do not need to do any work for it.

draw_scaffold()
This method/function draws the scaffold.
This method/function has already been written for you; you do not need to do any work for it.

Incidentally, if you want the program to use a specific word that you choose for the player to guess, give the word as an argument to main() I recommend that you do this while you are initially developing your program.


Code Provided

Please use the name "Hangman" for this program, not anything like Lab7.

Here (below) is the code I'm giving you to start with. (You should be able to compile and execute this code almost immediately when you copy it into BlueJ; it should display an empty scaffold.)

// <your name>

import java.util.Scanner;

// Acknowledgement:  Some of this material is derived from the University
// of California.

public class Hangman {

    // HERE YOU WRITE CODE:
    // Write a |static| method/function |display()| returning nothing
    // but taking an argument that is an array of characters and outputting
    // the elements of the given array on one line with spaces between them.
    // Note: if your output from this looks something like the following:
    //      127127127...
    // then try using  "..."  instead of  '...' 



    // HERE YOU WRITE CODE:
    // Write a |static| function |equivalent()| taking as arguments
    // one array of characters and one |String|,
    // returning |true| if the given array and |String| have the same length
    // and contain the same elements, or |false| otherwise.
    // Here's one way to write code for this:
    // * To begin, check whether the length of the array differs from the
    //   length of the |String|, and if that's the case, then immediately
    //   return an appropriate value.
    // - (Don't have an |else| here.)
    // * Next, in a loop for each value of i ranging through the length of
    //   the array/|String|, check whether the character at the position i in
    //   the array differs from the character at the position i in
    //   the |String|, and if that's the case, then return an appropriate
    //   value.
    // - (Don't have an |else| here either.)
    // * Finally, after all the preceding code which checked for different
    //   lengths or different elements, the only remaining possibility is
    //   that the array and the |String| are equivalent; so at this point
    //   simply return |true|.
    // - (If you used |else| anywhere here, you'd probably get the following
    //   error at this point: "missing return statement".)


    // HERE YOU WRITE CODE: 
    // Define |MAX_ERRS| to be a |static| constant having the value |7|.


    public static void main(String[] args) {
        System.out.println("Welcome to the game of Hangman!\n");

        // word for the player to guess:
        String word = init_word(args);

        // HERE YOU WRITE CODE:
        // Declare an array to contain the word's characters correctly
        // guessed so far by the player.
        // Make this array as long as the word to be guessed,
        // and set each of its elements to be the underscore character, |'_'|
        


        // count of the player's incorrect guesses; naturally, the initial
        // value is |0|:
        int num_errs = 0;
        // draw the initial scaffold:
        draw_scaffold(num_errs);
        System.out.println();


        // HERE YOU WRITE CODE:  
        // Prepare a |Scanner| for reading input.


        // HERE YOU WRITE CODE:  
        // Start a |do|-|while| loop here.  The condition for the
        // |while| part of this |do|-|while| loop is specified at the end of
        // this long comment.  Do the following inside this |do|-|while| loop:
        // * Use |display()| to display the array containing the characters
        //   guessed correctly so far by the player.
        // * Prompt the player for their next guess like the following:
        //   "Enter a guess:  ".
        // * Read the player's next guess.
        // * Use |word.indexOf(...)| to check whether the character
        //   guessed by the player is in the word.
        // * If the character guessed by the player is not in the word,
        //   then do the following:
        //    * Tell the player that this character is not in the word.
        //    * Increment |num_errs|.
        //    * Invoke |draw_scaffold()| with its argument being |num_errs|.
        // * If the character guessed by the player is in the word,
        //   then do the following:
        //    * Tell the player that this character is in the word.
        //    * In a loop for each value of i ranging through the
        //      length of |word|, check whether the character at the
        //      position i in |word| is the same as the character guessed
        //      by the player; if so, then set element #i in the array of
        //      correct guesses to be that character.
        // Remember, the various operations just specified in this long
        // comment are supposed to be inside a |do|-|while| construct.
        // The @condition_to_proceed@ for this |do|-|while| construct
        // should be that |num_errs| is less than |MAX_ERRS| and
        // the characters guessed by the player
        // are not equivalent to (i.e. not the same as) the word being
        // guessed.  Invoke |equivalent()| to check whether the characters
        // guessed by the player are the same as the word being guessed ---
        // and remember to use the Java operator for 'not'.
        // (You're supposed to write |equivalent()| above.)


        // HERE YOU WRITE CODE:
        // After the big |do|-|while| loop which you needed to write above,
        // if the player guessed the word, then invoke |display()| as before,
        // and output something like: "You guessed all of the word; very good!"
        // Otherwise, do the following:
        // * output something like "Sorry, the limit for incorrect guesses is "
        //   plus |MAX_ERRS| plus a period;
        // * output something like "The word was " plus the word in double
        //   quotes; and
        // * output something like "Better luck next time you play Hangman!"


        } // end of |main()|


    // This method/function is provided for you.  You should not modify it.
    static String init_word(String[] program_args) {
        String[] word_source =
            {
            "\u0061\u0062\u0073\u0074\u0072\u0061\u0063\u0074",
            "\u0062\u006F\u006F\u006C\u0065\u0061\u006E",
            "\u0062\u0072\u0065\u0061\u006B",
            "\u0062\u0079\u0074\u0065",
            "\u0063\u0061\u0073\u0065",
            "\u0063\u0061\u0074\u0063\u0068",
            "\u0063\u006C\u0061\u0073\u0073",
            "\u0063\u006F\u006E\u0074\u0069\u006E\u0075\u0065",
            "\u0064\u0065\u0066\u0061\u0075\u006C\u0074",
            "\u0064\u006F",
            "\u0064\u006F\u0075\u0062\u006C\u0065",
            "\u0065\u006C\u0073\u0065",
            "\u0065\u0078\u0074\u0065\u006E\u0064\u0073",
            "\u0066\u0061\u006C\u0073\u0065",
            "\u0066\u0069\u006E\u0061\u006C",
            "\u0066\u0069\u006E\u0061\u006C\u006C\u0079",       
            "\u0066\u006C\u006F\u0061\u0074",
            "\u0066\u006F\u0072",                       
            "\u0069\u0066",
            "\u0069\u006D\u0070\u006C\u0065\u006D\u0065\u006E\u0074\u0073",
            "\u0069\u006D\u0070\u006F\u0072\u0074",
            "\u0069\u006E\u0074\u0065\u0072\u0066\u0061\u0063\u0065",
            "\u006C\u006F\u006E\u0067",                 
            "\u006E\u0061\u0074\u0069\u0076\u0065",
            "\u006E\u0065\u0077",                       
            "\u006E\u0075\u006C\u006C",
            "\u0070\u0061\u0063\u006B\u0061\u0067\u0065",       
            "\u0070\u0072\u0069\u0076\u0061\u0074\u0065",
            "\u0070\u0072\u006F\u0074\u0065\u0063\u0074\u0065\u0064",
            "\u0070\u0075\u0062\u006C\u0069\u0063",             
            "\u0072\u0065\u0074\u0075\u0072\u006E",
            "\u0073\u0068\u006F\u0072\u0074",           
            "\u0073\u0074\u0061\u0074\u0069\u0063",
            "\u0073\u0075\u0070\u0065\u0072",           
            "\u0073\u0077\u0069\u0074\u0063\u0068",
            "\u0074\u0068\u0069\u0073",                 
            "\u0074\u0068\u0072\u006F\u0077",
            "\u0074\u0068\u0072\u006F\u0077\u0073",
            "\u0074\u0072\u0061\u006E\u0073\u0069\u0065\u006E\u0074",
            "\u0074\u0072\u0075\u0065",                 
            "\u0074\u0072\u0079",
            "\u0076\u006F\u0069\u0064",
            "\u0076\u006F\u006C\u0061\u0074\u0069\u006C\u0065", 
            "\u0077\u0068\u0069\u006C\u0065"
            };
        if ( program_args.length > 0 )
            word_source = program_args;

        Random random = new Random();
        int index_r = random.nextInt(word_source.length);

        return  word_source[index_r];
        }


    // This method/function is provided for you.  You should not modify it.
    static void draw_scaffold(int extent) {
        System.out.println(    "     ______   ");
        System.out.println(    "     |    |   ");

        if ( extent < 1 )
            System.out.println("     |        ");
        else
            System.out.println("     |    O   ");

        if ( extent < 2 )
            System.out.println("     |        ");
        else if ( extent < 5 )
            System.out.println("     |    |  ");
        else if ( extent < 6 )
            System.out.println("     |   /|   ");
        else
            System.out.println("     |   /|\\  ");

        if ( extent < 3 )
            System.out.println("     |        ");
        else
            System.out.println("     |    |   ");

        if ( extent < 4 )
            System.out.println("     |        ");
        else if ( extent < 7 )
            System.out.println("     |   /    ");
        else
            System.out.println("     |   / \\  ");

        System.out.println(    "   __|_____   ");
        System.out.println(    "   |      |___");
        System.out.println(    "   |_________|");
        }

    } // end of the program

Submission

Submit the following:



(Copyright © 2009 by Hugh McGuire   -- for thoughts about this, see   http://www.csis.gvsu.edu/~mcguire/teaching/copyright_thoughts.html .)