CS303E Homework 5

Instructor: Dr. Bill Young
Due Date: Friday, September 22, 2023 at 11:59pm

Did you know that gaming is a massive multibillion dollar industry with worldwide revenues in excess of $200 billion, according to Market Watch? This is more than is earned by the global film industry and all North American professional sports combined. In this assignment, you'll be programming a very simple game; you won't make millions, but maybe it will set you on a path that will lead you there. If so, don't forget who got you started!

Assignment

Write a program that allows the user to play a guessing game. The game will choose a ``secret number,'' a positive integer less than 1000. The user has 10 tries to guess the number.

Your program should be defined with a main( initialAnswer ) function and a call to that function at the bottom of your program file. Note that main in this program takes a single argument, which can be any number from 0 to 999. If passed 0, the secret number is selected randomly by the program; if passed a number in the range 1 to 999, that value is used as the secret number. You main() function should be defined as follows:


def main( initialAnswer ):
   # Loop to play any number of games.  Before each, ask
   # the player if she wants to continue.  
   # 
   # * If 'N', print a Goodbye message and return
   # * If 'Y', choose an answer and play the game, which 
   #   involves looping to accept up to 10 answers.
   # * Otherwise, print an error message and try again. 
   # 
   ...


# If you (or the TA) want to test your program with a specific answer
# you can supply that as a parameter to main.  If you pass 0 as your 
# 'initialAnswer', the program will run with a randomly chosen anwer
# in range 1 to 999.  For example: to program with a randomly chosen answer:
#    main( 0 )    
# On the other hand, 
#    main( 500 )
# would run your program with a specific initial answer of 500.

main( num )
Your program should begin by printing a welcome message (see examples below). Then ask the player if she is ready to play. The answer should be 'Y' or 'N'. If the answer is 'Y' play a game and ask again. If 'N', print a goodbye message and exit. If anything else, print an error message and ask again.

When you call main( num ), if you do specify an answer other than 0, that answer will be used in all games. If you call main( 0 ), the program will choose a different random answer in each game. Here's how to do that. In your code, when the player has specified 'Y', meaning she'd like to continue, you must decide what the answer for this game is. You can do that with the following code (within main( initialAnswer )):

      # User has just specified 'Y'
      if initialAnswer != 0:    
          thisGameAnswer = initialAnswer
      else:
          thisGameAnswer = random.randint( 1, 999 )
      < play the game with thisGameAnswer >

In each game, accept up to 10 guesses from the user, one at a time. If a guess is correct, congratuate the user and end the game. If the user makes 10 tries without success, say so and end the game. Short of 10 tries, if the guess is too low, say so and continue. If too high, say so and continue. See the examples below.

You can assume that the user will enter an integer as a guess; however, your program must verify that each guess is non-negative and less than 1000. If it is not, it should print an error message and reprompt the user. Don't count illegal guesses against the user's allowed guesses.

Sample Output:

You should match the following output exactly. Note for the following games, I specified an answer of 500, by calling main(500). Notice also that this shows several separate calls to the game program from the OS level, in addition to multiple games within several of the calls.
> python GuessingGame.py                              # I set the answer to 500

Welcome to the guessing game! Good luck!

Are you ready to play (Y/N): Y                       

See if you can guess the 'secret number'!

Enter an integer from 1 to 999: 10000
That's an illegal guess. Try again! You have 10 guesses left.

Enter an integer from 1 to 999: -14
That's an illegal guess. Try again! You have 10 guesses left.

Enter an integer from 1 to 999: 500
Congratulations, you got it! You took 1 guesses!

Are you ready to play (Y/N): Y

See if you can guess the 'secret number'!

Enter an integer from 1 to 999: 500                  # The answer stays at 500
Congratulations, you got it! You took 1 guesses!

Are you ready to play (Y/N): Z
Sorry, I didn't recognize your answer. Try again!

Are you ready to play (Y/N): N

Well, come again later. Goodbye!

> python GuessingGame.py                # I set answer to 0, meaning
                                        # to chooose a random value

Welcome to the guessing game! Good luck!

Are you ready to play (Y/N): Y

See if you can guess the 'secret number'!

Enter an integer from 1 to 999: 500
Your guess is too high. Try again! You have 9 guesses left.

Enter an integer from 1 to 999: 250
Your guess is too low. Try again! You have 8 guesses left.

Enter an integer from 1 to 999: 325
Your guess is too low. Try again! You have 7 guesses left.

Enter an integer from 1 to 999: 412
Your guess is too high. Try again! You have 6 guesses left.

Enter an integer from 1 to 999: 368
Your guess is too low. Try again! You have 5 guesses left.

Enter an integer from 1 to 999: 390
Your guess is too low. Try again! You have 4 guesses left.

Enter an integer from 1 to 999: 401
Your guess is too low. Try again! You have 3 guesses left.

Enter an integer from 1 to 999: 407
Your guess is too high. Try again! You have 2 guesses left.

Enter an integer from 1 to 999: 409
Your guess is too high. Try again! You have 1 guesses left.

Enter an integer from 1 to 999: 408
Your guess is too high. Try again! You have 0 guesses left.
Sorry! You took too many guesses. The answer was 403. Better luck next time!

Are you ready to play (Y/N): N

Well, come again later. Goodbye!

>
As always, write your own code. Don't work together, use code from anyone else or from the internet. If you encounter issues, ask your TA or instructor. The penalty for cheating is severe, so don't do it!

Turning in the Assignment:

The program should be in a file named GuessingGame.py. Submit the file via Canvas before the deadline shown at the top of this page. Submit it to the assignment weekly-hw5 under the assignments sections by uploading your python file.

Your file must compile and run before submission. It must also contain a header with the following format:

# File: GuessingGame.py
# Student: 
# UT EID:
# Course Name: CS303E
# 
# Date:
# Description of Program: 

If you submit multiple times to Canvas, it will rename your file name to something like Filename-1.py, Filename-2.py, etc. Don't worry about that; we'll grade the latest version.

Programming Tips

Program incrementally: Don't try to write this entire program all at once. In the first version, you might code to just play one game. This will ensure you can handle the loop involved in playing one game without worrying about playing multiple games. Then figure out how to wrap that in another loop that allows playing successive games. Or you can do it the other way around: write the outer loop to play multiple games, but just "stub in" the game playing, perhaps just printing a message that you're playing a game. Some of you will think: "It's easier to just do it all at once." You're wrong!

Using Loops: You usually write a for loop if you know in advance how many times the loop will run and a while loop if you don't. For this problem, you don't know how many times the loop will run (iterations). So you have to figure out the loop test and ensure that the loop test makes sense the first time you enter the loop.

For this problem, it seems to make sense to stop when the number of guesses left is zero. Think about what must be true the first time you enter the loop, where in the loop you need to ask the user for input, and what you need to change so that the loop will eventually terminate.

Sometimes, it makes sense to write a loop test of True when you don't know how many iterations there will be. But then you run the risk of an infinite loop. You have to test inside the loop body to see if you are ready to exit and break if so. If not, you can always continue to another iteration of the loop. Years ago, I worked on a language called "Gypsy" in which all loops were like this. The loop statement had no test and the only way to exit a loop was an explicit break statement. That's probably why I often write loops that way.

Binary Search: Notice that there are 1000 possible answers in this game. If you were to guess randomly, you'd have only 1 in 100 chances to get the right answer in 10 guesses. There's a better way, if you guess strategically.

Say your first guess is 500. There are three possibilities: either you guessed correctly, your guess is too high, or your guess is too low. In either of the two cases where you guess incorrectly, you have still eliminated a lot of possibilities. If your guess was too low, you know the answer is in [501..999]; if too high, the answer is in [0..499]. Notice that you've cut the search space in half! Your next guess should be the midpoint of the new range, and so on. You can only do this log(1000) (approximately 10) times until there's only one number left. This is called binary search, and it's a very efficient searching algorithm for ordered lists.