CS 161 Lab E - Guessing Game

Due Fri Feb 20 at the start of class

Overview

In this lab, you will create a simple game to play! The game is a "number guessing game"---the computer will pick a random number between 1 and 50 (inclusive), and then the player will try to guess it in as few guesses as possible.

The player will enter guesses through the BlueJ interface, calling a guess() method and providing a parameter. The program will let the player know how close their guess is (if they are "hot" or "cold", and in what direction). When finished, your program's output might look something like:

Welcome to the Guessing Game. I picked a number between 1 and 50. Try and guess!

You guessed 25. 
Your guess is cold. Try a little higher.

You guessed 15. 
Your guess is icy freezing miserable cold. Try a little higher.

You guessed 30.
Your guess is warm. Try a little higher

You guessed 40.
Your guess is extremely warm. Try a little lower.

You guessed 38.
Your guess is scaldingly hot! Try a little lower.

You guessed 37.
Congratulations, you figured it out in 7 guesses!

Note that I called a guess() method multiple times with parameters 25, 15, 30, 40, 38, and 37. If you have BlueJ's Terminal set to "Clear screen at method call", then you will only see one of these at a time. Uncheck that option to be able to see your game history!

This lab should be completed in pairs. You will need to find a different partner than you had for the last lab. Be sure to review the pair programming guidelines before you begin; remember to switch off who is driving and who is navigating!

Objectives

Necessary Files

There are no necessary files for this class, but you might want to have the textbook handy!

Details

To create this program, you will need just one Java class: a SecretNumber.

Part 1: The SecretNumber class

  1. The SecretNumber class represents the secret number, as well as the number of times the user has tried to guess that number. This is a "model" class: it should have attributes, a constructor, and methods.
  2. Think about what types of attributes are needed to keep track of the number to guess and the number of guesses made so far. You can assume that the secret number is an integer.
  3. Your SecretNumber class should have two constructors:
    1. A default constructor (with no parameters) that picks a random number between 1 and 50
    2. A second constructor with a parameter of the upperBound of the random number (e.g., a number between 1 and x, where x is the parameter value). The upperBound should be inclusive (so a value of 50 would make this work the same as the default constructor).

  4. To create these constructors, you'll need to figure out how to ask Java to generate a random number:
    1. You can use another build-in Java class called Random. Like the Scanner, this class is inside the java.util package, so you'll need to
      import java.util.Random;
      • Place the import line at the very top of your class!
    2. Instantiate a new Random object (use the default constructor--the one without a parameter). Then you can call the .nextInt(int n) method to fetch a random number between 0 (inclusive) and n (not inclusive). For example:

      Random randomGenerator = new Random(); //a random generator
      int randomNumber = randomGenerator.nextInt(10); //a random number between 0 (inclusive) and 10 (exclusive)
    3. If you want to have a different lower bound, you can offset the result by adding the minimum value to it. For example:
      int randomNumber = randomGenerator.nextInt(10) + 1; 
      // random number is now between 0+1 (inclusive) and 10+1 (exclusive), 
      // or between 1 and 10 (inclusive)
    4. More details on creating random numbers can be found on page 283 of the Horstmann text.

  5. Your constructors should also welcome the player (e.g., via System.out.println()), and let them know the range of numbers to guess.
  6. Your SecretNumber class will need a method guess() that can be called when the user guesses a number. This method should take a number as a parameter, and return whether or not the guess was correct. The method then compares the parameter with the secret number, and prints a message depending on how close the guess is to the secret number, and what direction the guess needs to be.

    When the user called guess(), several things need to happen:

    1. You need to determine if the guess is correct. If so, you should print out a message congratulating them, and telling them how many guessed they used (see the above example).
    2. If the user's guess is wrong, You need to (a) tell the user if their guess should be "higher" or "lower", and (b) tell the user how close they are.
    3. You should determine if the guess should be "higher" or "lower" by using an if statement and comparison operators.
      • Try to avoid duplicated code! Can you make this "check" only once? Hint: think about making the check once at the beginning and then storing some information--like the String you want to print out--in a local variable for later!
    4. You can see how "close" the guess is by subtracting the guess from the secret number to get the difference. Use a if/else if/else block to print a different message as the numbers get closer, such as:
      Within 1 "scalding hot"
      Within 2 "extremely warm"
      Within 3 "very warm"
      Within 5 "warm"
      Within 8 "cold"
      Within 13 "very cold"
      Within 20 "extremely cold"
      More than 20 away "icy freezing miserably cold"

      Remember to handle both positive AND negative differences! There are many ways to handle this. While you can use absolute value, for practice you should use boolean operators like && and || to check both cases. For example:

        if (age >= 18 && age <= 21)
        {
            //do somewhere where you know
            //age is between 18 and 21
        }
        else
        {
            //do somewhere where you know
            //age is outside the range of 18 to 21
        }                  

      You must avoid writing the same print statement more than once--it makes it difficult to change the message later!

    5. Finally, don't forget that if the guess is wrong, you'll also need to increase (increment) the number of guesses by 1. You might even do this work first, before you get into your conditionals!
    6. Remember, you should also return whether or not the user guessed correctly, so that other classes will know.
  7. Debugging tips: Be sure to test and retest your code at each step of the process! You may want to (temporarily) print out the secret number so you know what you are looking for, then you can guess() numbers that are within a certain range to test your conditionals.
    • Advanced: If you use the Random constructor that takes a number as a parameter, your random generator will always produce the same number when you first ask it. This won't be the number you give as a parameter, but it will be the same!

    Double-check that your program works perfectly by playing multiple games. If there is ever any behavior that seems wrong, stop and figure out what caused that! "Play computer" and work through the program by hand to see what Java is doing.

  8. Food for thought: What's your strategy (your "algorithm") for guessing the secret number in as few guesses as possible? If you use larger and larger random numbers (e.g., from 1 to 100; or from 1 to 1000), how many more guesses do you need to make?

Part 2: Upgrading the Game

With a basic version of the SecretNumber class and game in place, let's add further functionality to make the game more interesting.

  1. Upgrade 1: You may have noticed that once the user guesses the number correctly, they are able to keep guessing! You should modify your game so this isn't a problem.
    1. You should keep track of whether the user correctly guessed the number or not. This can be an attribute of the SecretNumber. Think: what data type would be good for this?
    2. If they have already guessed the number and try to call guess() again, you should let them know:
      You already guessed that the number was 37!
  2. Upgrade 2: It would be really nice if we could limit the number of guesses the player gets. Before you dive into the code for this, think critically about what needs to happen in the guess() method. Are you going to need more attributes? Can you work without them? Only then should you start writing code:
    1. Add a parameter to your second constructor (the one that takes an upper bound) that allows you to initialize the game with a given number of guesses. This raises two questions: (1) what limit should the default constructor allow, and (2) what if we don't want any limit? Zero is probably a good value to use for both of these questions (and think about why!)
    2. Your initial "welcome" message should let the user know the limit on the number of guesses.
    3. If the limit is reached without the user guessing the value, then the game is over and the user should be disallowed from further guessing (using the work you did in Upgrade 1 will be helpful).
    4. However, this logic will break some of the code you wrote for Upgrade 1. That is, when the user tries to guess again, the message it prints assumes they got it right! This is no longer sufficient. If the user met the limit, and still didn't get it right, you should instead print something like:
      Game Over: You've reached the limit of 8 tries. The secret number was 37.
    5. Make sure to keep your code organized--think about putting different "sets" of logic statement together, and using comments to mark them!

Submission

  1. Make sure both of your names are on all your class (SecretNumber). If your names aren't on your assignment, we can't give you credit!
  2. Right-click on the project folder you downloaded, then:
    • If using Linux, select Compress...
    • If using Windows, select Send to and then Zip file
    • If using Mac, select Compress ... items

    This will let you take the selected folder (or files) and generate a new compressed .zip file.

  3. Navigate to the course on Moodle (Lecture Section A), (Lecture Section B). Upload your .zip file to the Lab E Submission page. Remember to click "Save Changes"! You may submit as often as you'd like before the deadline; we will grade the most recent copy.
  4. While you're on Moodle, remember to fill out the Lab E Partner Evaluation. Both partners need to submit evaluations.

Extensions

No extra credit for this one, but there are a couple of options that might be fun:

Grading

This assignment will be graded out of 27 points.