Python编程快速上手2
上QQ阅读APP看书,第一时间看更新

切记,这个程序使用的不是整数值,而是包含数字的字符串值。例如,'426'与426是不同的值。之所以这么做,是因为我们需要与秘密数字进行字符串比较,而不是进行数学运算。记住,0可以作为前导数字,在这种情况下,字符串'026'与'26'不同,但整数026与26相同。

 1. """
 2. Pico Fermi Bagels猜数字游戏,作者:Al Sweigart al@inventwithpython.com
 3. 一个逻辑推理游戏,你必须根据线索猜数字
 4. 本游戏的一个版本在《Python游戏编程快速上手》中有相应介绍
 5. 标签:简短,游戏,谜题
 6. """
 7. 
 8. import random
 9. 
10. NUM_DIGITS = 3  # (!) 请试着将3设置为1或10
11. MAX_GUESSES = 10  # (!) 请试着将10设置为1或100
12. 
13. 
14. def main():
15.     print('''Bagels, a deductive logic game.
16. By Al Sweigart al@inventwithpython.com
17. 
18. I am thinking of a {}-digit number with no repeated digits.
19. Try to guess what it is. Here are some clues:
20. When I say:    That means:
21.   Pico         One digit is correct but in the wrong position.
22.   Fermi        One digit is correct and in the right position.
23.   Bagels       No digit is correct.
24. 
25. For example, if the secret number was 248 and your guess was 843, the
26. clues would be Fermi Pico.'''.format(NUM_DIGITS))
27. 
28.     while True:  # 主循环
29.         # secretNum存储了玩家所要猜测的秘密数字
30.         secretNum = getSecretNum()
31.         print('I have thought up a number.')
32.         print(' You have {} guesses to get it.'.format(MAX_GUESSES))
33. 
34.         numGuesses = 1
35.         while numGuesses <= MAX_GUESSES:
36.             guess = ''
37.             # 保持循环,直到玩家输入正确的猜测数字
38.             while len(guess) != NUM_DIGITS or not guess.isdecimal():
39.                 print('Guess #{}: '.format(numGuesses))
40.                 guess = input('> ')
41. 
42.             clues = getClues(guess, secretNum)
43.             print(clues)
44.             numGuesses += 1
45. 
46.             if guess == secretNum:
47.                 break  # 玩家猜对了数字,结束当前循环
48.             if numGuesses > MAX_GUESSES:
49.                 print('You ran out of guesses.')
50.                 print('The answer was {}.'.format(secretNum))
51. 
52.         # 询问玩家是否想再玩一次
53.         print('Do you want to play again? (yes or no)')
54.         if not input('> ').lower().startswith('y'):
55.             break
56.     print('Thanks for playing!')
57. 
58. 
59. def getSecretNum():
60.     """返回唯一一个长度为NUM_DIGITS且由随机数字组成的字符串"""
61.     numbers = list('0123456789')  # 创建数字0~9的列表
62.     random.shuffle(numbers)  # 将它们随机排列
63. 
64.     # 获取秘密数字列表中的前NUM_DIGITS位数字
65.     secretNum = ''
66.     for i in range(NUM_DIGITS):
67.         secretNum += str(numbers[i])
68.     return secretNum
69. 
70. 
71. def getClues(guess, secretNum):
72.     """返回一个由Pico、Fermi、Bagels组成的字符串,用于猜测一个三位数"""
73.     if guess == secretNum:
74.         return 'You got it!'
75. 
76.     clues = []
77. 
78.     for i in range(len(guess)):
79.         if guess[i] == secretNum[i]:
80.             # 正确的数字位于正确的位置
81.             clues.append('Fermi')
82.         elif guess[i] in secretNum:
83.             # 正确的数字不在正确的位置
84.             clues.append('Pico')
85.     if len(clues) == 0:
86.         return 'Bagels'  # 没有正确的数字
87.     else:
88.         # 将clues列表按字母顺序排序,使其不会泄露数字的信息
89.         clues.sort()
90.         # 返回一个由clues列表中所有元素组成的字符串
91.         return ' '.join(clues)
92. 
93. 
94. # 程序运行入口(如果不是作为模块导入的话)
95. if __name__ == '__main__':
96.     main()

输入源代码并运行几次后,请试着对其进行更改。标有!的注释给你提供了更改建议。你也可以自己尝试执行以下操作。

通过更改NUM_DIGITS修改秘密数字的位数。

通过更改MAX_GUESSES修改玩家的最大猜测次数。

尝试创建秘密数字中包含字母和数字的程序版本。