27
loading...
This website collects cookies to deliver better user experience
# Adding Al's header
# His version and my subsequent version of it are
# CC-BY-NC-SA - https://creativecommons.org/licenses/by-nc-sa/4.0/
"""Bagels, by Al Sweigart [email protected]
A deductive logic game where you must guess a number based on clues.
View this code at https://nostarch.com/big-book-small-python-projects
A version of this game is featured in the book "Invent Your Own
Computer Games with Python" https://nostarch.com/inventwithpython
Tags: short, game, puzzle"""
import random
NUM_DIGITS = 3
MAX_GUESSES = 10
def main():
print('''Bagels, a deductive logic game.
By Al Sweigart [email protected]
I am thinking of a {}-digit number with no repeated digits
Try to guess what it is. Here are some clues:
When I say: That means:
Pico One digit is correct but in the wrong position.
Fermi One digit is correct and in the right position
Bagels No digit is correct.
For example, if the secret number was 248 and your guess was 843, the
clues would be Fermi Pico.'''.format(NUM_DIGITS))
# If the program is run (instead of imported), run the game:
if __name__ == '__main__':
main()
python programname.py
on the command-line. My process for authoring is to write to a point where I can run the code and it should work, then test and make sure it works before I move on.%s
or %d
in JavaScript string formatting. Seeing him use {}
on line 18 of his code (20 of mine) made me go look this up to understand how and why he used it. I found an article on Python string formatting that helped me understand the how and why of using curly braces. I have a feeling I'll revisit that article and get a deeper understanding of string formatting a few times before I'm done with this book.while True:
#This stores the secret number the player needs to guess:
secretNum = getSecretNum()
print('I have thought up a number.');
print(' You have {} guesses to get it.'.format(MAX_GUESSES))
numGuesses = 1
while numGuesses <= MAX_GUESSES:
guess = ''
#Keep looping until they enter a valid guess
#Greg's Note: "valid" = 3 digits
while len(guess) != NUM_DIGITS or not guess.isdecimal():
print('Guess #{}: '.format(numGuesses))
guess = input('> ')
clues = getClues(guess, secretNum);
print(clues)
numGuesses += 1
if guess == secretNum:
break # they're correct, so break the loop
# Greg's note: Congrats come in the getClues function
if numGuesses > MAX_GUESSES:
print('You ran out of guesses.')
print('The answer was {}'.format(secretNum))
# Ask player if they want to play again
print('Do you want to play again? (yes or no)')
if not input('> ').lower().startswith('y'):
break
print('Thanks for playing!')
True
(a boolean literal) is capitalized in Python, though it isn't in a number of other languages. That caught me up the first few times I tried writing Python. Nice to get an early reminder of it.numGuesses
from line 36 as the variable in the string formatting. But something looked wrong to me. At this point A) numGuesses
hadn't been defined and B) the number used there should have been a constant. Since a constant is usually defined in ALL CAPS.def getSecretNum():
# Returns a string made up of NUM_DIGITS unique random digits
numbers = list('0123456789') #create a list of digits from 0-9
random.shuffle(numbers) #shuffle them into random order
# Get the first NUM_DIGITS in the list for the secret number
secretNum = ''
for i in range(NUM_DIGITS):
secretNum += str(numbers[i]);
return secretNum
def getClues(guess, secretNum):
#Returns a string with the clues based on the guess
if guess == secretNum:
return 'You got it!'
clues = []
for i in range(len(guess)):
if guess[i] == secretNum[i]:
clues.append('Fermi')
elif guess[i] in secretNum:
clues.append('Pico')
if len(clues) == 0:
return "Bagels"
else:
# sort the clues into alpha order so their position doesn't give info away
clues.sort()
# join the clues into a single string
return ' '.join(clues)
# If the program is run (instead of imported), run the game:
if __name__ == '__main__':
main()
random
anywhere else except the getSecretNum()
function. I wondered if it might be better to import it at the top (where it is imported) or in the function. numbers
was like a string, and thus wondered why we were iterating through it to create the secret number rather than just lopping off the bit we needed. lower
in line 58 of the Game Loop section and used square brackets instead of parentheses around NUM_DIGITS
on line 69 here in the Helper Functions.numbers
list because I was mistaken about its datatype. I didn't blog most of them because they made no sense if it wasn't a string.K:\MyProjects\PyProj>python 01-bagels.py
Bagels, a deductive logic game.
By Al Sweigart [email protected]
I am thinking of a 3-digit number with no repeated digits
Try to guess what it is. Here are some clues:
When I say: That means:
Pico One digit is correct but in the wrong position.
Fermi One digit is correct and in the right position
Bagels No digit is correct.
For example, if the secret number was 248 and your guess was 843, the
clues would be Fermi Pico.
I have thought up a number.
You have 10 guesses to get it.
Guess #1:
> 123
Pico
Guess #2:
> 345
Bagels
Guess #3:
> 678
Pico Pico
Guess #4:
> 278
Pico
Guess #5:
> 168
Pico Pico
Guess #6:
> 167
Pico Pico Pico
Guess #7:
> 716
You got it!
Do you want to play again? (yes or no)
> n
Thanks for playing!