Lab 8: Branches and Loops, Part II (Updated)
Objectives
- Practice writing programs that use loops and branches
- Understand the purpose and application of the
randmethod - Understand the semantics and possible application of the
%(modulus) operator
A Better Guessing Game
Remember the guessing game we wrote in class? (You can check it out at github, if you like — you can download and play it if you’ve forgotten how it works.) For the first part of this lab you’ll be improving it in two ways.
First, you’ll update it so that the “goal” number is different each time — that is, the computer will invent its own, random number each time you run the program. This is fairly simple to do, thanks to the rand method. The rand method, given an argument of some integer N, will return a random number between 0 (inclusive) and N (exclusive). If you run the following program, for instance, you’ll find that it always prints out a number between 0 and 9999:
puts rand(10000)
Second, and this is the more interesting bit, you’ll update the program so that with each guess the program will print out “Warmer” or “Colder”, depending on whether the guess is closer or further from the goal number than the previous guess. If there is no previous guess (i.e., it’s the first guess, the program should just print out “Nope! Guess again!”.
Let’s assume a goal number of 1588; a session with the program might go as follows:
Enter a number:
5000
Nope! Guess again!
Enter a number:
2500
Warmer!
Enter a number:
3000
Colder!
Enter a number:
1500
Warmer!
Enter a number:
1000
Colder!
Enter a number:
1800
Warmer!
Enter a number:
1600
Warmer!
Enter a number:
1550
Colder!
Enter a number:
1575
Warmer!
Enter a number:
1590
Warmer!
Enter a number:
1585
Colder!
Enter a number:
1588
You guessed it!
To do this, you’ll need to build in memory (as a variable) of the “last” guess into your program, and update this value with each succeeding guess.
Exercise 1
Implement the guessing game as described above and save your program in a file named “guesser.rb”. Feel free to change the feedback messages to your liking (so long as you preserve the essence of the idea). Have fun!
Mastermind
The reigning king of (simple) guessing games is Mastermind, be it one form or other. If you haven’t played Mastermind before, here’s how it goes:
The game is usually played with a fixed number of colored balls or pegs (between 4 and 10 of them) that are arranged a certain way by the game master (or computer, as the case may be). The arrangement is a secret that the player must attempt to guess. With each guess the game master will give a pair of hints indicating the number of pegs that are the right color and in the right position, and the number of pegs that are the right color but in the wrong position. If we substitute numbers for colored pegs (lets go with a 4 digit number), then we have a game that might go something as follows:
Assuming the secret number 1588 (again):
Enter your guess:
1111
1 in the right place
Enter your guess:
2222
0 right
Enter your guess:
3333
0 right
Enter your guess:
4444
0 right
Enter your guess:
5555
1 in the right place
Enter your guess:
6666
0 right
Enter your guess:
7777
0 right
Enter your guess:
8888
2 in the right place
Enter your guess:
8851
4 in the wrong place
Enter your guess:
5881
1 in the right place
3 in the wrong place
Enter your guess:
1885
2 in the right place
2 in the wrong place
Enter your guess:
1858
2 in the right place
2 in the wrong place
Enter your guess:
1588
You got it!
Exercise 2
Implement the Mastermind game as described above (as before, your program should come up with a random secret number in the range 0000-9999 each time it is run) and save your code in a file named “mastermind.rb”. Again, feel free to change the feedback messages to your liking (so long as you preserve the essence of the idea). Good luck!
Hints for Exercise 2
While you have all the tools you need to complete this second exercise on your own, there are a few pieces of information that might serve as useful hints. Read on if you’re interested.
First, there is the matter of how to extract individual digits out of a number. This can be done a number of ways, but the easiest is through a combination of the division (/) and modulus (%) operators. The following example will serve to illustrate the technique.
Consider the number 1982. In your program you’ll likely want to inspect the digits 1, 9, 8, and 2 separately (so as to be able to compare their values and positions to the digits in another number). Let’s start with the digit in the one’s place — 2. To extract it, we need to apply an operation that will effectively “clear out” the rest of the number; it turns out that the modulus is the perfect operation for the job.
What happens when we divide the number 1982 by 10 and take the remainder? Try it. 1982 % 10 → 2. Pretty convenient, huh? Any number “modded” by 10 will in fact yield the value in the one’s position. So how do we get the digit in the ten’s position (i.e., 8 in our example)? Simple. Divide by 10 first, then mod the result by 10. (1982 / 10) % 10 → 8. And to obtain the digit in the hundred’s position, divide by 100 first, then mod the result by 10: (1982 / 100) % 10 → 9. And so forth and so on.
Next, there is the bigger issue of how to go about checking the secret code and the user’s guess against each other to come up with the hints. This can be a bit challenging, but the first step is to make sure you know how to do it by hand. Try working through a few examples on paper yourself to be sure you understand the process completely. The following are good ones to try:
- Secret code “1234″, Guess “1111″
- Secret code “1234″, Guess “0123″
- Secret code “0110″, Guess “1111″
- Secret code “0110″, Guess “1221″
- Secret code “1233″, Guess “2313″
- Secret code “1234″, Guess “1234″
Okay. So now that you’ve got the general idea, see if the following procedure makes sense:
- If we have a perfect match, we’re done. Otherwise, continue.
- Try and find digits from the guess that are in the right position. If we find any of these, we basically “cross off” the corresponding digits in the secret code so that we don’t check against them again in the future. Keep doing this until there are no perfect matches left.
- Making sure to not check against the digits we crossed off earlier, now search for digits in the guess that match up with the secret, but are in the incorrect position. Again, if we find a match, we cross off the digit in the secret number so as not to check it again in the future.
- We now have the number of guessed digits in the right position, and those that match but are in the wrong position. Done!
Good luck!
Leave a comment
You must be logged in to post a comment.