# 破解 1A2B 演算法 # 1A2B 破解演算法 在破解 1A2B 遊戲前,我們要先來設計這個遊戲。 ### 產生答案 我們可以使用 `random` 套件嚇得 `sample` 語法, 去隨機產生數字不重複的答案。 ```python import random answer = ''.join(random.sample('123456789', 4)) print(answer) ``` 但現在我們刻意不使用 `sample` 語法來產生答案, 而是用迴圈去產生答案組合,並從中隨機挑選一個, 這麼做的目的,是為了之後破解密碼時會用到類似的程式片段。 ```python import random arr = [] for i in range(1234, 9876): s = str(i) if len(s) == len(set(s)): arr.append(s) rand = random.randrange(len(arr)) answer = arr[rand] print(answer) ``` ### 判斷結果 接下來我們設計一個 `diff` 函式,它可以比較答案跟玩家猜的, 並返回幾 a 幾 b 表示結果。 ```python def diff(answer, guess): a = 0 b = 0 for i in range(4): if guess[i] == answer[i]: a += 1 for j in range(4): if guess[i] == answer[j]: b += 1 b -= a return { 'a': a, 'b': b } ``` 你可以做以下測試 ```python print(diff('1234', '1234')) # { 'a': 4, 'b': 0 } print(diff('1234', '1243')) # { 'a': 2, 'b': 2 } print(diff('1234', '1325')) # { 'a': 1, 'b': 2 } ``` ### 玩家遊玩 接下來設計 `guess` 函式讓玩家可以猜答案, 它除了判斷結果外,還會記錄猜的次數並顯示。 ```python count = 1 def guess(g): global count result = diff(answer, g) print(f'第 {count} 次猜 {g} 結果為 {result.a}a{result.b}b') count += 1 return result ``` 接著使用 `while` 迴圈讓玩家不斷猜直到猜對 ```python while True: g = input('請輸入:') result = guess(g): if result.a == 4: break ``` ### 完整遊戲 ```python import random answer = ''.join(random.sample('123456789', 4)) count = 0 def diff(answer, guess): a = 0 b = 0 for i in range(4): if guess[i] == answer[i]: a += 1 for j in range(4): if guess[i] == answer[j]: b += 1 b -= a return { 'a': a, 'b': b } def guess(g): global count result = diff(answer, g) print(f'第 {count} 次猜 {g} 結果為 {result["a"]}A{result["b"]}B') count += 1 return result while True: g = input('請輸入:') result = guess(g) if result['a'] == 4: break ``` ### 破解答案 現在我們要改成用程式去模擬玩家猜答案,所以我們要把 `input` 替換掉。 你只能修改這段程式,並根據猜的結果 `result` 去決定下一次要猜的內容。 ```python while True: # g = input('請輸入:') result = guess(g) if result['a'] == 4: break ``` 老師提示你一個解題方向,就是你可以建立一個 `arr` 去存放所有可能的答案, 每次猜完後根據結果將 `arr` 不可能作為答案的結果篩掉。