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):
py()
for answerStr in answerSetCopy:
A1,B1=compareAnswer(inputStr,answerStr)
if A!=A1 or B!=B1:
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个python可以做什么游戏
第4步----尝试:2451----反馈:1A3B----排除可能答案:1个
第5步----尝试:2514----反馈:4A0B----排除可能答案:0个
猜数字成功,总⽤时:0.105326秒,总步数:5。