Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 游戏人工智能在一边强大地工作,而在另一边则变得哑巴_Python_Pygame_Artificial Intelligence_Tic Tac Toe_Minimax - Fatal编程技术网

Python 游戏人工智能在一边强大地工作,而在另一边则变得哑巴

Python 游戏人工智能在一边强大地工作,而在另一边则变得哑巴,python,pygame,artificial-intelligence,tic-tac-toe,minimax,Python,Pygame,Artificial Intelligence,Tic Tac Toe,Minimax,我正在尝试用PyGame和MiniMax算法在Python中制作一个Tic-Tac-Toe游戏。当第一次有机会扮演“X”时,AI的表现非常出色,但当没有第一次有机会扮演“O”时,AI会变得愚蠢到足以帮助用户获胜。我想我知道问题是什么,但是改变它会扰乱整个程序,而不是按照给定的docstring。 我已经创建了两个python文件——一个用于GUI runner.py,另一个用于游戏背后的逻辑和AI tictactoe.py 这就是游戏背后的逻辑: 为函数“deepcopy”导入模块“copy”,

我正在尝试用PyGame和MiniMax算法在Python中制作一个Tic-Tac-Toe游戏。当第一次有机会扮演“X”时,AI的表现非常出色,但当没有第一次有机会扮演“O”时,AI会变得愚蠢到足以帮助用户获胜。我想我知道问题是什么,但是改变它会扰乱整个程序,而不是按照给定的docstring。 我已经创建了两个python文件——一个用于GUI runner.py,另一个用于游戏背后的逻辑和AI tictactoe.py

这就是游戏背后的逻辑:

为函数“deepcopy”导入模块“copy”,以深度复制 原始可变对象,用于从突变中保存对象 导入副本 X='X' O='O' 空=无 def初始_状态: 返回板的开始状态 返回[ [空,空,空], [空,空,空], [空,空,空] ] def显示板,自动打印=错误: 将板嵌套列表显示为 用于电路板可视化的3x3矩阵 可视电路板= 对于板中的行: 对于行中的playr: 如果playr为None: playr='' playr+='' 可视板+=播放器 可视电路板+='\n' 如果自动打印: 印刷电路板 返回视盘 def播放板: 返回棋盘上下一回合的玩家 全局X,O 函数每次调用的初始值 X_计数=0 O_计数=0 对于板中的行: 对于行中的playr: 如果playr==X: X_计数+=1 elif playr==O: O_计数+=1 `总是先开始 如果O_计数最佳分数: 最佳分数=分数 最佳行动 返回最佳行动 GUI代码文件:

为GUI导入模块“PyGame” 导入pygame 导入系统 导入时间 从与导入模块相同的文件夹导入模块'tictactoe' 这个文件用于游戏AI的逻辑 将Tictatcoe作为ttt导入 pygame.init 尺寸=宽度,高度=600,400 颜色 黑色=0,0,0 白色=255,255,255 screen=pygame.display.set\u modesize mediumFont=pygame.font.font'OpenSans-Regular.ttf',24 largeFont=pygame.font.font'OpenSans-Regular.ttf',40 moveFont=pygame.font.font'OpenSans-Regular.ttf',60 用户=无 线路板=ttt.初始状态 ai_turn=错误 尽管如此: 对于pygame.event.get中的事件: 如果event.type==pygame.QUIT: 系统出口 屏幕。黑色 让用户选择一个播放器。 如果用户为无: 抽签标题 title=largeFont。呈现“玩井字游戏”,真,白色 titleRect=title.get\u rect titleRect.center=圆宽/2,50 萤幕、闪电、标题等 绘图按钮 playXButton=pygame.Rectroundwidth/8,roundheight/2,roundwidth/4,50 playX=mediumFont。渲染“按X播放”,真,黑色 playXRect=playX.get\u rect playXRect.center=playXButton.center pygame.draw.rectscreen,白色,playXButton screen.blitplayX,playXRect playOButton=pygame.Rect5*roundwidth/8,roundheight/2,roundwidth/4,50 playO=mediumFont。渲染“按O播放”,真,黑色 playORect=playO.get\u rect playORect.center=playOButton.center pygame.draw.rectscreen,白色,playOButton screen.blitplay,playORect 检查按钮是否已单击 单击,u,u=pygame.mouse.get\u按 如果单击==1: mouse=pygame.mouse.get\u pos 时间是0.5 如果playXButton.collidepointmouse: user=ttt.X elif playOButton.collidepointmouse: 用户=ttt.O 其他: 画游戏板 瓷砖尺寸=80 瓷砖原点=宽度/2-1.5*瓷砖尺寸, 高度/2-1.5*瓷砖尺寸 瓷砖=[] 对于范围3中的i: 行=[] 对于范围3中的j: rect=pygame.rect 圆形平铺原点[0]+j*平铺尺寸, 圆形瓷砖原点[1]+i*瓷砖尺寸, 圆形瓷砖尺寸,圆形瓷砖尺寸 pygame.draw.rectscreen,白色,矩形,3 如果板[i][j]!=ttt.EMPTY: move=moveFont.renderboard[i][j],真,白色 moveRect=move.get\u rect moveRect.center=rect.center screen.blitmove,moveRect 行.appendrect 瓦片.appendrow 游戏结束=ttt终端板 player=ttt.playboard 显示标题 如果游戏结束: 赢家=ttt.Winnboard 如果没有获胜者: title=f‘比赛结束:平局。’ 其他: title=f'游戏结束:{胜者}获胜。' elif user==玩家: title=f'Play as{user}' 其他: title=f'AI thinking…' title=largeFont.rendertitle,真,白色 titleRect=title.get\u rect titleRect.center=圆宽/2,30 萤幕、闪电、标题等 检查AI移动 如果用户!=玩家而非游戏结束: 如果你转身: 时间是0.5 移动=ttt.minimaxboard 线路板=ttt.resultboard,移动 ai_turn=错误 其他: 真的吗 检查是否有用户移动 单击,u,u=pygame.mouse.get\u按 如果单击==1且用户==玩家且未结束游戏: mouse=pygame.mouse.get\u pos 对于范围3中的i: 对于范围3中的j: 如果电路板[i][j]==ttt.EMPTY且平铺[i][j]。鼠标: board=ttt.resultboard,i,j 如果游戏结束: againButton=pygame.rectrondwidth/3,roundheight-65,roundwidth/3,50 再次=中等字体。呈现“再次播放”,真,黑色 againRect=再次。获取正确 againRect.center=againButton.center pygame.draw.rectscreen,白色,againButton screen.blitagain,再次引用 单击,u,u=pygame.mouse.get\u按 如果单击==1: mouse=pygame.mouse.get\u pos 如果再次单击Button.collidepointmouse: 时间是0.2 用户=无 线路板=ttt.初始状态 ai_turn=错误 pygame.display.flip 以下是给出这些问题的组织给出的答案的旁注:

不得更改任何函数中的参数数量或参数本身。 遵循所有函数中编写的docstring 可以定义新的功能 如你所愿 请让我知道是否有任何错误/错误导致AI在作为“O”播放时变哑。我相信这个bug在实用程序中,但我不能更改代码,因为它不允许写在docstring中

谢谢大家!

编辑:问题几乎解决了,但人工智能有时会变得愚蠢,比如不试图用相反的符号阻止用户的移动,等等

best_score = -float('inf')  # Least possible score
你需要根据你计算移动的玩家的不同来改变这一点。我认为正因为如此,消极的玩家选择了随机/第一个看似合理的举动


我已经实现了2次minimax和相关的启发式方法,并且总是发现使用negamax方法效果最好,因为你不需要担心何时根据玩家应用max和min。

我想我更新了minimaxEdit中for循环中的best_分数值:非常感谢!!!我不明白你先说了什么,所以评论。但现在我想我意识到了你说的话,这真的帮了我大忙!现在AI不再像以前那样第一次有机会就装傻了。再次,非常感谢!!!编辑2:人工智能有时又变傻了。像这次一样,它不是用一个O来阻止用户的三个连续,而是通过将O放在不需要的地方来播放。请将其减少并增强到预期值。显示中间结果与预期结果的偏差。这篇文章表明,您已经确定整个显示框架是EPR问题的一个固有部分——我对此深表怀疑。