Pico Fermi Bagels猜數字遊戲

袁文澤博客 發佈 2023-01-27T23:21:35.260129+00:00

在Pico Fermi Bagels這個邏輯推理遊戲中,你要根據線索猜出一個三位數。

在Pico Fermi Bagels這個邏輯推理遊戲中,你要根據線索猜出一個三位數。遊戲會根據你的猜測給出以下提示之一:如果你猜對一位數字但數字位置不對,則會提示「Pico」;如果你同時猜對了一位數字及其位置,則會提示「Fermi」;如果你猜測的數字及其位置都不對,則會提示「Bagels」。你有10次猜數字機會。

運行程序

運行bagels.py,輸出如下所示:

Bagels, a deductive logic game.
By Al Sweigart al@inventwithpython.com
I am thinking of a 3-digit number. 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.
I have thought up a number.
You have 10 guesses to get it.
Guess #1:
> 123
Pico
Guess #2:
> 456
Bagels
Guess #3:
> 178
Pico Pico
--snip--
Guess #7:
> 791
Fermi Fermi
Guess #8:
> 701
You got it!
Do you want to play again? (yes or no)
> no
Thanks for playing!

工作原理

切記,這個程序使用的不是整數值,而是包含數字的字符串值。例如,'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修改玩家的最大猜測次數。

● 嘗試創建秘密數字中包含字母和數字的程序版本。

探索程序

請嘗試找出以下問題的答案。可嘗試對代碼進行一些修改,再次運行程序,並查看修改後的效果。

1.如果更改NUM_DIGITS常量,則會發生什麼?

2.如果更改MAX_GUESSES常量,則會發生什麼?

3.如果將NUM_DIGITS設置為大於10的數字會發生什麼?

4.如果將第30行的secretNum = getSecretNum()替換為secretNum = '123',會發生什麼?

5.如果刪除或注釋掉第34行的numGuesses = 1,會得到什麼錯誤消息?

6.如果刪除或注釋掉第62行的random.shuffle(numbers),會發生什麼?

7.如果刪除或注釋掉第73行的if guess == secretNum:和第74行的return'You got it!',會發生什麼?

8.如果注釋掉第44行的numGuesses += 1,會發生什麼?

關鍵字: