Python寫個(gè)益智小游戲來鍛煉大腦
大家好,歡迎來到 Crossin的編程教室 !
最近一段時(shí)間,我感覺自己大腦出現(xiàn)了衰退的癥狀,說話口誤逐漸增多,也常常忘記事情。
前兩天在 B 站上看到一個(gè)兩人玩的小游戲,叫做?“珠璣棋”?,發(fā)現(xiàn)這對(duì)鍛煉大腦有一些好處。無奈找不到人一起玩,于是我決定用 Python 寫一個(gè)簡(jiǎn)單的程序來自己玩。
游戲規(guī)則
珠璣棋的規(guī)則非常簡(jiǎn)單。它分為兩方:攻擊方和防守方。具體流程如下:
防守方寫一個(gè)4位數(shù)字,每位數(shù)字不能重復(fù) 攻擊方有10次猜測(cè)的機(jī)會(huì),在每次機(jī)會(huì)里面,攻擊方可以說出一個(gè)4位數(shù),讓防守方檢查。 定義兩個(gè)字母 A 和 B 攻擊方說出的4位數(shù)里面,每有任何一位或者多位的數(shù)字和位置都對(duì),則 A+1。例如防守方的答案是1234,攻擊方的答案是6274,那么就是2A 在第4步檢查以后,如果攻擊方剩下的數(shù)字里面,有一位或者多位數(shù)字,在防守方剩下的數(shù)字里面,但位置不對(duì),則 B+1。例如防守方的數(shù)字是1234,攻擊方的數(shù)字是4190,就是2B。 防守方給出 A 和 B 的值,攻擊方根據(jù)這兩個(gè)值修正自己的猜測(cè)數(shù)。如果10次內(nèi)猜對(duì)了,那么攻擊方勝利。如果超過10次都猜不對(duì),則防守方勝利。 特別說明,在匹配數(shù)字的時(shí)候,首先檢查數(shù)字和位置都對(duì)的情況。檢查完成以后,再檢查數(shù)字對(duì)位置不對(duì)的情況。并且這個(gè)時(shí)候,是攻擊方的剩余數(shù)字從左至右依次到防守方的剩余數(shù)字中檢查。每檢查一個(gè)數(shù)字,就把這個(gè)數(shù)字從攻擊方和防守方的數(shù)字里面同時(shí)剔除。所以對(duì)于防守方的數(shù)字1234,如果攻擊方的數(shù)字為4437,那么檢查結(jié)果應(yīng)該是1A1B。因?yàn)橐婚_始把數(shù)字3剔除了,攻擊方剩余447,防守方剩余124.然后攻擊方的第一個(gè)4和防守方的4匹配上了以后也會(huì)剔除。變成攻擊方剩余47,防守方剩余12.此時(shí)防守方已經(jīng)沒有4了。
在這個(gè)游戲規(guī)則里面,防守方的作用僅僅是檢查結(jié)果而已,并沒有攻防對(duì)抗,所以我們可以用程序來代替防守方。
Python 實(shí)現(xiàn)
首先我們來生成防守方的4位數(shù)字。由于4位數(shù)字不相等,所以我們使用 Python 的隨機(jī)數(shù)來生成:
import?random
data?=?[str(x)?for?x?in?range(10)]
random.shuffle(data)??#?shuffle?會(huì)直接修改列表本身,所以不用賦值
if?data[0]?==?'0':??#?如果首尾為0,那么取后四位
????answer?=?data[-4:]
else:?#?首尾不為0,取前4位
????answer?=?data[:4]
由于要檢查的數(shù)據(jù)通過 input 輸入,所以為了保持類型一致,我們都使用字符串來表示。
運(yùn)行效果如下圖所示:

接下來,讓玩家連續(xù)進(jìn)行10次嘗試,每次輸入一個(gè)4位數(shù):
for?i?in?range(1,?11):
????while?True:
????????guess?=?input(f'進(jìn)行第{i}次嘗試,請(qǐng)輸入一個(gè)4位數(shù):')
????????if?len(guess)?==?4:
????????????break
????????print('請(qǐng)輸入4位數(shù)。')
運(yùn)行效果如下圖所示:

接下來,首先檢查位置和數(shù)字都正常的情況:
def?match_num_and_position(guess,?answer):
????A?=?0
????for?guess_num,?answer_num?in?zip(guess,?answer):?#?逐位檢查攻擊方和防守方的答案數(shù)字
????????if?guess_num?==?answer_num:
????????????A?+=?1
????????else:
????????????guess_left_num.append(guess_num)
????????????answer_left_num.append(answer_num)
????return?guess_left_num,?answer_left_num
這里,使用zip來同時(shí)迭代guess和answer,從而實(shí)現(xiàn)逐位一一對(duì)應(yīng)檢查。
下面再來處理數(shù)字對(duì),但位置不對(duì)的情況:
def?match_num(guess,?answer):
????B?=?0
????for?num?in?guess:
????????if?num?in?answer:
????????????B?+=?1
????????????answer.remove(num)??#?.remove?是一個(gè)原地操作,不需要賦值
????return?B
這個(gè)代碼就比較簡(jiǎn)單了。把guess剩下的數(shù)字一個(gè)一個(gè)到答案剩下的數(shù)字里面去查詢,如果找到了,B 就加1。然后從答案里面刪除這個(gè)數(shù)字。接著查找 guess 的下一個(gè)數(shù)字。
完整的代碼如下圖所示:

如果10次猜測(cè)都失敗了,運(yùn)行效果如下圖所示:

如果才對(duì)了,運(yùn)行效果如下圖所示:

計(jì)算過程如下圖所示:

如果文章對(duì)你有幫助,歡迎轉(zhuǎn)發(fā)/點(diǎn)贊/收藏~
_往期文章推薦_
