# 破解 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` 不可能作為答案的結果篩掉。