python初學---猜數字游戲(游戲與AI,原創)


最近在學習python,並用python寫了一個小時候玩的益智游戲,猜數字游戲,python語言真的是簡潔啊,上來就是寫代碼邏輯,不用加一堆外殼的東西,話不多說,貼代碼,取個名字叫guessL1.py,L1顧名思義是初級版本,就是能玩而已,后面會出個稍微高級一點的版本,加點智能化(AI)的東西。

#*********************************L1********************************

import random
print("/*******************************猜數字游戲***********************************/ \
游戲規則:系統隨機給出1-9的4位數字,您可以輸入您猜測的4位數字,系統會比較並給予反饋,A表示數字對,且位置對,B表示數字對位置不對,如1A2B表示有1位您猜對了數字和位置,有2位您猜對數字,但位置不對。您總共有6次機會,加油哦!")
total='123456789'
answer=random.sample(total,4)
for guessTimes in range(6):
guess=""
for inputErros in range(3):
guess=input("請輸入4位1-9的不重復數字:")
if guess.isdigit()==True and len(guess)==4:
guessSet=set(guess)
if len(guessSet)==4 and guessSet.isdisjoint(set('0')):
break
else:
print("您沒有理解游戲規則,游戲結束。")
break
A=0
B=0
for j in range(4):
if guess[j]==answer[j]:
A+=1
else:
for k in range(4):
if guess[j]==answer[k]:
B+=1
if A<4:
if guessTimes<5:
print("%dA%dB,您還有%d次機會。" %(A,B,5-guessTimes))
else:
print("很遺憾您沒有猜對,答案是%s,再玩一局吧。" %(answer))
else:
print("恭喜您猜對了!")
break

先玩一局吧,python3 guessL1.py,開始

/*******************************猜數字游戲***********************************/ 游戲規則:系統隨機給出1-9的4位數字,您可以輸入您猜測的4位數字,系統會比較並給予反饋,A表示數字對,且位置對,B表示數字對位置不對,如1A2B表示有1位您猜對了數字和位置,有2位您猜對數字,但位置不對。您總共有6次機會,加油哦!
請輸入4位1-9的不重復數字:1234
1A0B,您還有5次機會。
請輸入4位1-9的不重復數字:5678
0A2B,您還有4次機會。
請輸入4位1-9的不重復數字:7839
1A2B,您還有3次機會。
請輸入4位1-9的不重復數字:7694
1A1B,您還有2次機會。
請輸入4位1-9的不重復數字:7982
0A3B,您還有1次機會。
請輸入4位1-9的不重復數字:1897
恭喜您猜對了!

 

初戰告捷!很牛逼的樣子。下面簡單說一下我玩這游戲的思路(說着說着就啰嗦了。。。):

第一步,1234,沒啥說的,因為4位數字是隨機的,第一步輸啥都行

第二步,5678,第一步反饋是1A0B,說明1234中有一位數字猜對了,那么另外三位數字,就分布在56789中,就嘗試5678好了

接下來,第三步要開始動腦了,這里結合第一步和第二步的反饋結果進行猜測,第二步反饋0A2B,說明5678中有兩位數字對了(位置不對),第一步1234有一位數字對了(位置也對),加起來3位數字對了,那么最后一位數字9肯定是對的,這里再假定5678中78是對的,位置調整一下,1234中假定3是對的,位置不變,然后就是9,看看運氣如何吧

第三步,7839,反饋1A2B

有點接近了,這里9數字肯定是對的,位置可能不對吧,因為總共才有1位位置是對的,9換一下位置,3對的概率是1/4,姑且假設他不對吧,換成4,78假設是對的吧,假設7的位置也對,換成76試試,

第四步,7694,反饋1A1B

有點崩潰,7694不是一個好的嘗試,在9數字肯定對的情況下,764只有一位是對的,返回第三步,7839有三位是對的,789應該是對的吧,換回來,3和4都嘗試過了,再嘗試一下2

第五步,7982,反饋0A3B,結果還不錯,猜測789數字是對的,2也不對,那第一步就剩1了,參考第一步的反饋,1肯定在第一位,第四步中7694反饋1A1B,只有7和9是對的,7的位置顯然不對,那9的位置就是對的,9在第三位,剩下7和8的位置,根據第二步5678反饋0A2B,8肯定不在第四位,那8只能在第二位了,7在第四位,大概這樣吧1897

第六步,1897,恭喜您猜對了!

其實,這不是一個很完美的猜數字過程,人腦就是這樣,無法時刻精確抓住所有信息,比如第四步猜7694,顯然7894更合適點,還有第五步7982也不合適,因為既然選擇2,根據第一步反饋結果,應該把2放在第二位,不過就因為玩的過程中的模糊和不確定性,最終猜對數字時才有了更多的喜悅(辛苦沒白費)

 

#*********************************L2**************************

多玩幾局游戲,有了稍微深入一點的思考,整個猜數字的過程,還是有一個相對固定的思路的,初次接觸可能有點沒頭緒,慢慢的就找到方法和套路了,這就是常說的經驗吧,我發覺我6步內猜出數字的概率還是挺高的。那么能不能改進一下游戲,把玩家的經驗體現在游戲里,一般游戲里常有提示或者錦囊啥的,就加這個吧,每做完一步,就給個提示,下一步猜什么合適,或者還剩下多少可能,這個提示,玩家可以選擇查看,或者不查看,把每步的提示連起來,就是電腦模擬人玩游戲的過程(AI),聽起來就高大上了,雖然是很簡單的AI,話不多說,先貼代碼

 

import random
import time

def runGame(testAnswer):
for i in range(10):
playGuess(testAnswer);
if i==9:
print("您已經玩了10局了,休息一下吧。")
else:
again=input("您還想再玩一局嗎?輸入y再玩一局,按其他鍵退出:")
if again!='y':
break

def playGuess(testAnswer):
print("/*******************************猜數字游戲***********************************/ \
游戲規則:系統隨機給出1-9的4位數字,您可以輸入您猜測的4位數字,系統會比較並給予反饋,A表示數字對,且位置對,B表示數字對位置不對,如1A2B表示有1位您猜對了數字和位置,有2位您猜對數字,但位置不對。您總共有6次機會,加油哦!")
answer=getAnswer(testAnswer)
answerSet=answerSetInit(set())
for guessTimes in range(6):
for inputErros in range(3):
guess=input("請輸入4位1-9的不重復數字:")
if guess.isdigit()==True and len(guess)==4:
guessSet=set(guess)
if len(guessSet)==4 and guessSet.isdisjoint(set('0')):
break
else:
print("您沒有理解游戲規則,游戲結束。")
return
A,B=compareAnswer(guess,answer)
if A<4:
if guessTimes<5:
print("%dA%dB,您還有%d次機會。" %(A,B,5-guessTimes))
delCount=answerSetDelNum(answerSet,guess,A,B)
answerSetUpd(answerSet,guess,A,B)
helpFlag=input("輸入h查看幫助,按其他鍵繼續游戲:")
if helpFlag=='h':
print("本次排除可能答案:%d個,剩余:%d個" %(delCount,len(answerSet)))
print(helpInfo(answerSet))
if len(answerSet)<=200:
print(answerSet)
print("推薦數字:",suggestedNum(answerSet,100) )
else:
print("很遺憾您沒有猜對,答案是%s,再玩一局吧。" %(answer))
else:
print("恭喜您猜對了!")
break

def guessTrainner(testAnswer):
start =time.time()
answer=getAnswer(testAnswer)
print (answer)
answerSet=answerSetInit(set())
for i in range(6):
inputStrMax=suggestedNum(answerSet,100)
print('第%d步----' %(i+1), end="")
print('嘗試:' +inputStrMax, end="")
print('----', end="")
AMax,BMax = compareAnswer(inputStrMax, answer)
print('反饋:%dA%dB' % (AMax, BMax), end="")
print('----', end="")
print('排除可能答案:%d個' % (answerSetDelNum(answerSet,inputStrMax,AMax,BMax)))
answerSetUpd(answerSet,inputStrMax,AMax,BMax)
if AMax==4:
elapsed = (time.time() - start)
print("猜數字成功,總用時:%f秒,總步數:%d。" %(elapsed,i+1))
break
elif i==5:
print("猜數字失敗!")

def getAnswer(testAnswer):
total = '123456789'
answer = random.sample(total, 4)
if testAnswer > 999:
answer = str(testAnswer)
return answer

def compareAnswer(inputStr,answerStr):
A=0
B=0
for j in range(4):
if inputStr[j]==answerStr[j]:
A+=1
else:
for k in range(4):
if inputStr[j]==answerStr[k]:
B+=1
return A,B

def answerSetInit(answerSet):
answerSet.clear()
for i in range(1234,9877):
seti=set(str(i))
if len(seti)==4 and seti.isdisjoint(set('0')):
answerSet.add(str(i))
return answerSet

def answerSetUpd(answerSet,inputStr,A,B):
answerSetCopy=answerSet.copy()
for answerStr in answerSetCopy:
A1,B1=compareAnswer(inputStr,answerStr)
if A!=A1 or B!=B1:
answerSet.remove(answerStr)

def answerSetDelNum(answerSet,inputStr,A,B):
i=0
for answerStr in answerSet:
A1, B1 = compareAnswer(inputStr, answerStr)
if A!=A1 or B!=B1:
i+=1
return i

def helpInfo(answerSet):
answer0=set()
answer1=set()
answer2=set()
answer3=set()
for answerStr in answerSet:
answer0.add(answerStr[0])
answer1.add(answerStr[1])
answer2.add(answerStr[2])
answer3.add(answerStr[3])
helpInfoStr="提示:第一位可能是"+"|".join(answer0)+",第二位可能是"+"|".join(answer1)+",第三位可能是"+"|".join(answer2)+",第四位可能是"+"|".join(answer3)
return helpInfoStr

def suggestedNum(answerSet,lvl):
suggestedNum=''
delCountMax=0
if len(answerSet) > lvl:
suggestedNum = list(answerSet)[0]
else:
for inputStr in answerSet:
delCount = 0
for answerStr in answerSet:
A,B = compareAnswer(inputStr, answerStr)
delCount += answerSetDelNum(answerSet, inputStr,A,B)
if delCount > delCountMax:
delCountMax = delCount
suggestedNum = inputStr
if delCount == delCountMax:
if suggestedNum == '' or int(suggestedNum) > int(inputStr):
suggestedNum = inputStr
# print(inputStr+'-----'+str(delCount)+'-----'+str(delCountMax)+'-----'+suggestedNum)
return suggestedNum


代碼量翻了不少倍!玩玩看!

➜ python python3 -c "import guess;guess.runGame(1)"

/*******************************猜數字游戲***********************************/ 游戲規則:系統隨機給出1-9的4位數字,您可以輸入您猜測的4位數字,系統會比較並給予反饋,A表示數字對,且位置對,B表示數字對位置不對,如1A2B表示有1位您猜對了數字和位置,有2位您猜對數字,但位置不對。您總共有6次機會,加油哦!
請輸入4位1-9的不重復數字:1234
2A0B,您還有5次機會。
輸入h查看幫助,按其他鍵繼續游戲:h
本次排除可能答案:2904個,剩余:120個
{'1538', '8264', '1268', '9634', '6934', '7236', '8734', '1297', '8534', '1674', '1974', '1754', '7834', '1287', '1537', '5236', '1279', '6534', '1637', '7934', '1954', '1784', '1738', '6734', '9834', '7254', '1539', '5934', '7238', '8254', '1964', '6238', '5274', '1295', '1594', '6274', '6235', '5834', '8294', '8235', '1864', '1739', '1298', '9238', '1894', '6294', '1984', '1684', '9734', '6284', '1938', '8274', '1584', '9534', '8634', '8934', '1836', '1639', '6254', '1735', '1564', '1694', '7239', '5734', '9274', '6237', '1286', '6239', '1267', '1935', '5239', '5634', '9254', '9237', '5237', '1638', '7534', '1854', '1289', '1574', '1276', '1794', '7264', '8237', '5238', '1278', '1764', '1936', '5264', '1937', '1259', '7235', '9236', '1635', '8239', '9284', '7634', '1839', '5294', '7294', '9264', '1874', '8236', '1285', '1296', '1256', '1837', '1835', '1257', '1265', '1654', '7284', '1269', '1258', '1736', '6834', '5284', '1275', '9235', '1536'}

提示:第一位可能是7|5|6|9|1|8,第二位可能是7|5|6|9|8|2,第三位可能是7|5|6|9|8|3,第四位可能是7|5|6|9|8|4
推薦數字: 1538
請輸入4位1-9的不重復數字:1538
0A1B,您還有4次機會。
輸入h查看幫助,按其他鍵繼續游戲:h
本次排除可能答案:108個,剩余:12個

{'8264', '7254', '5274', '8294', '6284', '8274', '6254', '9254', '5264', '9284', '5294', '7284'}
提示:第一位可能是7|5|6|9|8,第二位可能是2,第三位可能是7|5|6|9|8,第四位可能是4
推薦數字: 5264
請輸入4位1-9的不重復數字:5264
恭喜您猜對了!
您還想再玩一局嗎?輸入y再玩一局,按其他鍵退出:y
/*******************************猜數字游戲***********************************/ 游戲規則:系統隨機給出1-9的4位數字,您可以輸入您猜測的4位數字,系統會比較並給予反饋,A表示數字對,且位置對,B表示數字對位置不對,如1A2B表示有1位您猜對了數字和位置,有2位您猜對數字,但位置不對。您總共有6次機會,加油哦!
請輸入4位1-9的不重復數字:1234
0A2B,您還有5次機會。
輸入h查看幫助,按其他鍵繼續游戲:h
本次排除可能答案:2184個,剩余:840個
提示:第一位可能是7|5|6|9|8|2|3|4,第二位可能是7|5|6|9|1|8|3|4,第三位可能是7|5|6|9|1|8|2|4,第四位可能是7|5|6|9|1|8|2|3
推薦數字: 4378
請輸入4位1-9的不重復數字:4378
1A1B,您還有4次機會。
輸入h查看幫助,按其他鍵繼續游戲:h
本次排除可能答案:692個,剩余:148個
{'4752', '8329', '7319', '4517', '3972', '5346', '7392', '5472', '4527', '7315', '2648', '9471', '4761', '6382', '8319', '4157', '9382', '4197', '4729', '7352', '7128', '7361', '4862', '4725', '4829', '4185', '3628', '6349', '8316', '2386', '9148', '3572', '3158', '7329', '8362', '3518', '2458', '4693', '6381', '4627', '4953', '4762', '2973', '4715', '5382', '8351', '4819', '9345', '6327', '7391', '2475', '8391', '9381', '4581', '4682', '5173', '4917', '3928', '4653', '6428', '4861', '4927', '7325', '3672', '7316', '4825', '6173', '4681', '2871', '4892', '2476', '8352', '2718', '9317', '4593', '6317', '7351', '8392', '2948', '4719', '5428', '5148', '3528', '7362', '8361', '9472', '5418', '7326', '3618', '2389', '4792', '2479', '6345', '3176', '4851', '2468', '4815', '2357', '2673', '9428', '9346', '4563', '8326', '8172', '3571', '4716', '8315', '4891', '6471', '9173', '4189', '4582', '8325', '6148', '9327', '2498', '4981', '4852', '4982', '2548', '4816', '4826', '2397', '9418', '5471', '4963', '5327', '3168', '3175', '5349', '6472', '4791', '3918', '6418', '2573', '3971', '3179', '2385', '5381', '4617', '3671', '5317', '4186', '2367', '4751', '4167', '3198', '4726'}

提示:第一位可能是7|5|6|9|8|2|3|4,第二位可能是7|5|6|9|1|8|3|4,第三位可能是7|5|6|9|1|8|2|4,第四位可能是7|5|6|9|1|8|2|3
推薦數字: 4752
請輸入4位1-9的不重復數字:4752
0A3B,您還有3次機會。
輸入h查看幫助,按其他鍵繼續游戲:h
本次排除可能答案:140個,剩余:8個
{'7325', '2476', '5428', '2479', '2548', '5471', '5327', '2573'}

提示:第一位可能是7|5|2,第二位可能是5|4|3,第三位可能是7|4|2,第四位可能是7|5|6|9|1|8|3
推薦數字: 2476
請輸入4位1-9的不重復數字:2476
1A1B,您還有2次機會。
輸入h查看幫助,按其他鍵繼續游戲:h
本次排除可能答案:6個,剩余:2個
{'5428', '2548'}

提示:第一位可能是5|2,第二位可能是5|4,第三位可能是4|2,第四位可能是8
推薦數字: 2548
請輸入4位1-9的不重復數字:2548
1A3B,您還有1次機會。
輸入h查看幫助,按其他鍵繼續游戲:h
本次排除可能答案:1個,剩余:1個
{'5428'}

提示:第一位可能是5,第二位可能是4,第三位可能是2,第四位可能是8
推薦數字: 5428
請輸入4位1-9的不重復數字:5428
恭喜您猜對了!
您還想再玩一局嗎?輸入y再玩一局,按其他鍵退出:

玩這游戲變的輕松好多,幾乎不用動腦,根據提示的可能性,隨便玩玩就能猜出答案!

 

還有更高級的,模擬電腦玩游戲

➜ python python3 -c "import guess;guess.guessTrainner(1)"
['6', '4', '7', '3']
第1步----嘗試:7861----反饋:0A2B----排除可能答案:2184個
第2步----嘗試:6947----反饋:1A2B----排除可能答案:786個
第3步----嘗試:6729----反饋:1A1B----排除可能答案:43個
第4步----嘗試:6374----反饋:2A2B----排除可能答案:10個
第5步----嘗試:6473----反饋:4A0B----排除可能答案:0個
猜數字成功,總用時:0.541268秒,總步數:5。
➜ python python3 -c "import guess;guess.guessTrainner(1)"
['5', '8', '2', '3']
第1步----嘗試:9642----反饋:0A1B----排除可能答案:2304個
第2步----嘗試:8795----反饋:0A2B----排除可能答案:502個
第3步----嘗試:1983----反饋:1A1B----排除可能答案:171個
第4步----嘗試:5184----反饋:1A1B----排除可能答案:41個
第5步----嘗試:3586----反饋:0A3B----排除可能答案:5個
第6步----嘗試:5823----反饋:4A0B----排除可能答案:0個
猜數字成功,總用時:0.411014秒,總步數:6。
➜ python python3 -c "import guess;guess.guessTrainner(1)"
['4', '1', '2', '6']
第1步----嘗試:7569----反饋:0A1B----排除可能答案:2304個
第2步----嘗試:5842----反饋:0A2B----排除可能答案:502個
第3步----嘗試:9421----反饋:1A2B----排除可能答案:199個
第4步----嘗試:1624----反饋:1A3B----排除可能答案:18個
第5步----嘗試:4126----反饋:4A0B----排除可能答案:0個
猜數字成功,總用時:0.082934秒,總步數:5。
➜ python python3 -c "import guess;guess.guessTrainner(1)"
['7', '6', '4', '2']
第1步----嘗試:1258----反饋:0A1B----排除可能答案:2304個
第2步----嘗試:9316----反饋:0A1B----排除可能答案:598個
第3步----嘗試:7489----反饋:1A1B----排除可能答案:104個
第4步----嘗試:2467----反饋:0A4B----排除可能答案:16個
第5步----嘗試:7624----反饋:2A2B----排除可能答案:1個
第6步----嘗試:7642----反饋:4A0B----排除可能答案:0個
猜數字成功,總用時:0.080719秒,總步數:6。
➜ python python3 -c "import guess;guess.guessTrainner(1)"
['2', '5', '1', '4']
第1步----嘗試:2173----反饋:1A1B----排除可能答案:2544個
第2步----嘗試:2345----反饋:1A2B----排除可能答案:455個
第3步----嘗試:2754----反饋:2A1B----排除可能答案:23個
第4步----嘗試:2451----反饋:1A3B----排除可能答案:1個
第5步----嘗試:2514----反饋:4A0B----排除可能答案:0個
猜數字成功,總用時:0.105326秒,總步數:5。

 

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM