选棒游戏 / 智能AI / Python
背景信息,如果你只想看下面的代码问题,可以不读:
希望大家都知道“火柴游戏”或者叫“尼姆游戏”。如果不知道的话,简单来说就是你先设定一个火柴的数量(在10到50之间),然后每次可以拿1到3根火柴,直到没有火柴为止,最后拿到最后一根火柴的人就输了。在我的编程课上,我们还加入了和AI对战的选项。不过,这个AI可不是随便选个1到3的傻瓜了,它会从每次的回合中学习。
实现方式:
AI为每种剩余的火柴数量准备了一个“桶”。比如,剩下1根火柴的桶、2根火柴的桶、3根火柴的桶等等。
游戏开始时,每个桶里都有3个球,每个球上标记着1、2或3。这些球代表AI选择拿1、2或3根火柴。
- 在AI的回合,它会从代表剩余火柴数量的桶里随机抽一个球。然后它会读取这个球上的数字,并从火柴堆中拿走相应数量的火柴。最后,它把这个球放在桶的前面。
- 如果AI赢了游戏,它会把所有选择的球都检查一遍,然后为每个选择的数字放回两个球。这样下次面对同样数量的火柴时,它选择那个球的机会就会增加。
- 如果AI输了,它会把那个球扔到桶旁边。不过,如果这个球是最后一次选择的球,它就会把它放回桶里。每个桶里必须至少有一个每种数字的球。所以如果用户选择的球是某个桶里最后一个数字的球,而AI输了,它就必须把这个球放回去。AI不能完全把任何选择从桶里移除。
- 随着游戏的进行,AI会用额外的球来强化它的好选择,特别是赢得的火柴。
这是我现在正在使用的代码。
choice=random.randint(1,maxchoice) #computer picks a random number
bucketnum=sticks #bucket to take ball from
pullnum=choice #ball to take
for i in bucket:
for bucket[bucketnum] in i:
bucketnum.pop(pullnum)
print(bucket[bucketnum])
我想从哪个桶里拿球,实际上就是剩下的火柴数量,我现在在找到特定的桶并拿出球时遇到了一些麻烦。现在我收到一个错误信息,说bucketnum.pop(pullnum) - 'int'对象没有'pop'这个属性?这是桶的代码(列表中的列表):
bucket=[]
for j in range(51):
bucket.append([1,2,3])
我可能说得有点混乱,但如果有人有建议或者需要澄清的问题,请回复我。谢谢大家。
编辑: 这是更多的代码,抱歉,我之前没有添加变量的定义等信息。
if option==2:
sticks=""
while True:
try:
sticks=int(input("Enter the number of sticks to begin with: "))
if sticks>=10 and sticks<=50:
print("Alright, there are",sticks,"sticks in the pile.")
break
else:
print("You mut enter an integer. (10-50)")
except ValueError:
print("You must enter an integer.")
player1=True
while sticks>0:
maxchoice=min(3,sticks)
choice=-1
countbucket=0
if player1:
while choice<1 or choice>maxchoice:
try:
choice=int(input("Player 1, how many sticks would you like to take? (1-3): "))
if choice>=1 and choice<=3:
sticks-=choice
print("There are",sticks,"sticks remaining.")
else:
print("You must enter an integer from 1-3.")
except ValueError:
print("You must enter an integer.")
player1=not player1
else:
choice=random.randint(1,maxchoice)
bucketnum=sticks
pullnum=choice
for i in bucket:
for bucket[bucketnum] in i:
bucketnum.pop(pullnum)
print(bucket[bucketnum])
sticks-=1
print("Computer drew",choice,"stick(s). There are",sticks,"sticks remaining.")
player1=not player1
if player1==False:
print("Player 1 took the last stick.\nComputer wins!")
else:
print("Player 1 wins!")
这是我程序中的选项2,因为选项1是玩家1对战玩家2。显然,我在实现AI智能方面还没走多远,这有点棘手。
-----> Fred S.,我刚开始,脑子有点转不过来。这里摘录的不是所有代码。我现在并不是在问如何完成作业,不过关于如何执行这个新的智能AI代码的建议会很有帮助,但这次我更关注的是如何搞清楚列表索引。
2 个回答
你没有定义选项。
你没有导入随机库。
看起来你在内层的循环里把变量赋值给了'bucket[bucketnum]'。这让我很惊讶,这居然不是语法错误,但我觉得这可能不是你真正想做的事情。
如果你在处理一个嵌套列表,而列表中的位置对应于剩下的棍子数量,那么你应该通过位置来索引这个列表,以便获取那个桶,而不是遍历整个列表去找它。
可以这样理解:
buckets = [[1,2,3], ..., ..., ...]
在这里,bucketnum就是桶在桶列表中的位置。所以,在你的例子中,如果你想获取'26'根棍子的桶,你应该通过这个数字来索引桶。
buckets[25] # 25 since you're counting from 0+
到这一步,你就得到了你需要的桶,可以从中取出选择。
bucket = buckets[25]
bucket.pop(pullnum)