Tictaoe Alpha Beta修剪运行时错误:pygame的最大递归深度超过python
所以,我正在编写一个非常简单的Tictatcoe程序,它使用alpha-beta修剪来搜索针对玩家的下一步行动,但在我想运行时遇到了问题。我尝试过任何我想到的方法来解决这个问题,甚至做了一个Java逐行的逻辑,这个逻辑运行得很好,但python的逻辑根本不起作用 这是我的代码:Tictaoe Alpha Beta修剪运行时错误:pygame的最大递归深度超过python,python,recursion,pygame,artificial-intelligence,alpha-beta-pruning,Python,Recursion,Pygame,Artificial Intelligence,Alpha Beta Pruning,所以,我正在编写一个非常简单的Tictatcoe程序,它使用alpha-beta修剪来搜索针对玩家的下一步行动,但在我想运行时遇到了问题。我尝试过任何我想到的方法来解决这个问题,甚至做了一个Java逐行的逻辑,这个逻辑运行得很好,但python的逻辑根本不起作用 这是我的代码: #encoding: UTF-8 #Andres de Lago Gomez #A01371779 from random import randint from utils import * def getEne
#encoding: UTF-8
#Andres de Lago Gomez
#A01371779
from random import randint
from utils import *
def getEnemy(who):
return 1 if who==2 else 2
def getLetter(who):
return "X" if who==1 else "O"
class TicTacToe:
winningCombos =[[0, 1, 2], [3, 4, 5],
[6, 7, 8], [0, 3, 6],
[1, 4, 7], [2, 5, 8],
[0, 4, 8], [2, 4, 6]]
board = [0 for i in range(9)]
player = 1
cpu = 2
def __init__(self):
pass
def makeMove(self, who, pos):
self.board[pos] = who
def setCpu(self, who):
self.player = who
self.cpu = getEnemy(who)
def availableMoves(self):
return [i for i in range(9) if self.board[i]==0]
def isOver(self):
if 0 not in self.board:
return True
if self.Winner():
return True
return False
def Winner(self):
for i in [1,2]:
positions = self.getSquares(i)
for combo in self.winningCombos:
win = True
for pos in combo:
if pos not in positions:
win = False
if win:
return i
return False
def getSquares(self, player):
return [i for i in range(9) if self.board[i]==player]
def alphaBeta(self, player, alpha, beta):
if self.isOver():
return self.evaluateNode()
for move in self.availableMoves():
self.makeMove(move, player)
value = self.alphaBeta(getEnemy(player),alpha,beta)
self.makeMove(move, 0)
if player == self.cpu:
if alpha < value:
alpha = value
if alpha >=beta:
return beta
else:
if beta > value:
beta = value
if beta <= alpha:
return alpha
return alpha if player==self.cpu else beta
def evaluateNode(self):
tmp = self.Winner()
if tmp==self.cpu:
return 1
elif tmp==self.player:
return -1
else:
return 0
def getNextMove(self, player):
test = -5
possibleMoves = []
for move in self.availableMoves():
self.makeMove(player, move)
value = self.alphaBeta(getEnemy(player), -5, 5)
self.makeMove(0, move)
if value>test:
test = value
possibleMoves = [move]
elif value == test:
possibleMoves.append(move)
return possibleMoves[randint(0, len(possibleMoves)-1)]
class Tile(pygame.sprite.Sprite):
def __init__(self, rect, screen, player="X"):
pygame.sprite.Sprite.__init__(self)
self.rect = rect
self.images = [load_png(get_path()+"\\data\\TicTacToe\\"+player+"Tile\\{0:0>2d}.png".format(x)) for x in range(21)]
clock = pygame.time.Clock()
for i in range(21):
self.image = self.images[i]
screen.blit(self.image, self.rect)
pygame.display.update(self.rect)
clock.tick(80)
class GUI:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode([100,100])
self.dir = get_path()
#get background
self.background = pygame.image.load(self.dir+"\\data\\TicTacToe\\Background.png")
self.background.convert()
self.tiles = pygame.sprite.Group()
#blit to screen
self.screen = pygame.display.set_mode(self.background.get_size())
self.screen.blit(self.background,(0,0))
pygame.display.update()
#create tiles
self.places = [pygame.Rect((15+165*x, 110+165*y), (150,150) )for x in range(3) for y in range (3)]
#create game
self.board = TicTacToe()
done = False
goFirstI = load_png(get_path()+"\\data\\TicTacToe\\GoFirst.png")
goFirstR = pygame.Rect((0,0), (400,200))
goFirstR.center = self.places[4].center
self.screen.blit(goFirstI,goFirstR)
pygame.display.update(goFirstR)
yesR = pygame.Rect((97,382),(115,45))
noR = pygame.Rect((297,382),(115,45))
while not done:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
if yesR.collidepoint(event.pos):
done = True
self.board.setCpu(1)
elif noR.collidepoint(event.pos):
done = True
self.board.setCpu(2)
self.screen.blit(self.background,(0,0))
pygame.display.update(goFirstR)
#start clock
clock = pygame.time.Clock()
done = False
turn = 1
bdown = 0
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pass #pause menu?
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
bdown = event
if turn == self.board.player:
if bdown != 0:
index = 0
for rect in self.places:
if rect.collidepoint(bdown.pos):
moves = self.board.availableMoves()
if index in moves:
self.board.makeMove(turn, index)
self.tiles.add(Tile(rect, self.screen, getLetter(self.board.player)))
turn = getEnemy(turn)
index += 1
else:
pos = self.board.getNextMove(self.board.cpu)
self.board.makeMove(turn, pos)
self.tiles.add(Tile(self.tiles[pos], self.screen, getLetter(self.board.cpu)))
clock.tick(60)
a = GUI()
编码:UTF-8
#安德烈斯德拉戈麦斯
#A01371779
从随机导入randint
从utils导入*
世界卫生组织(世卫组织):
如果who==2,则返回1,否则返回2
(世卫组织):
如果who==1,则返回“X”,否则返回“O”
Tictatcoe类:
winningCombos=[[0,1,2],[3,4,5],
[6, 7, 8], [0, 3, 6],
[1, 4, 7], [2, 5, 8],
[0, 4, 8], [2, 4, 6]]
board=[0代表范围(9)中的i]
玩家=1
cpu=2
定义初始化(自):
通过
def makeMove(自我、谁、pos):
self.board[pos]=谁
def setCpu(自我,谁):
self.player=谁
self.cpu=get敌军(who)
def可用移动(自):
如果self.board[i]==0,则返回范围(9)中的[i代表i]
def isOver(自):
如果0不在self.board中:
返回真值
如果self.Winner():
返回真值
返回错误
def优胜者(自我):
因为[1,2]中的i:
位置=自取平方(i)
对于self.winningCombos中的combo:
赢=真
对于组合中的pos:
如果pos不在位置:
赢=错
如果获胜:
返回i
返回错误
def getSquares(自我,玩家):
如果self.board[i]==玩家,则返回[i为范围(9)内的i]
def alphaBeta(自身、玩家、alpha、beta):
如果self.isOver():
返回self.evaluateNode()
对于移入self.availableMoves():
self.makeMove(移动,玩家)
value=self.alphaBeta(获取敌人(玩家),alpha,beta)
self.makeMove(移动,0)
如果player==self.cpu:
如果α<值:
α=值
如果α>=β:
返回贝塔
其他:
如果β>值:
β=值
如果是beta测试:
测试=数值
可能移动=[移动]
elif值==测试:
可能移动。追加(移动)
return-possibleMoves[randint(0,len(possibleMoves)-1]
类互动程序(pygame.sprite.sprite):
定义初始化(自、矩形、屏幕、播放器=“X”):
pygame.sprite.sprite.\uuuuu init\uuuuuuu(自我)
self.rect=rect
self.images=[load_png(get_path()+“\\data\\TicTacToe\\\”+player+“Tile\\{0:0>2d}.png.”格式(x))用于范围(21)内的x]
clock=pygame.time.clock()
对于范围(21)内的i:
self.image=self.images[i]
screen.blit(self.image,self.rect)
pygame.display.update(self.rect)
时钟滴答(80)
类GUI:
定义初始化(自):
pygame.init()
self.screen=pygame.display.set_模式([100100])
self.dir=获取路径()
#获取背景
self.background=pygame.image.load(self.dir+“\\data\\TicTacToe\\background.png”)
self.background.convert()
self.tiles=pygame.sprite.Group()
#光点到屏幕
self.screen=pygame.display.set_模式(self.background.get_size())
自我屏幕blit(自我背景,(0,0))
pygame.display.update()
#创建瓷砖
self.places=[pygame.Rect((15+165*x,110+165*y),(150150))表示范围(3)中的x,表示范围(3)中的y]
#创造游戏
self.board=TicTacToe()
完成=错误
goFirstI=load\u png(get\u path()+“\\data\\TicTacToe\\GoFirst.png”)
goFirstR=pygame.Rect((0,0)、(400200))
goFirstR.center=self.places[4]。center
self.screen.blit(goFirstI,goFirstR)
pygame.display.update(goFirstR)
yesR=pygame.Rect((97382)、(115,45))
noR=pygame.Rect((297382),(115,45))
虽然没有这样做:
对于pygame.event.get()中的事件:
如果event.type==pygame.MOUSEBUTTONUP:
如果event.button==1:
如果是碰撞点(事件位置):
完成=正确
self.board.setCpu(1)
elif noR.collidepoint(事件位置):
完成=正确
self.board.setCpu(2)
自我屏幕blit(自我背景,(0,0))
pygame.display.update(goFirstR)
#启动时钟
clock=pygame.time.clock()
完成=错误
圈数=1
b下跌=0
虽然没有这样做:
对于pygame.event.get()中的事件:
如果event.type==pygame.QUIT:
完成=正确
elif event.type==pygame.KEYDOWN:
如果event.key==pygame.K_退出:
通过暂停菜单?
elif event.type==pygame.MOUSEBUTTONUP:
如果event.button==1:
bdown=事件
如果回合==self.board.player:
如果是B下跌!=0:
索引=0
对于self.places中的rect:
如果直线碰撞点(bdown.pos):
moves=self.board.availableMoves()
如果索引在移动中:
self.board.makeMove(旋转,索引)
self.tiles.add(Tile(rect、self.screen、getLetter(self.board.player)))
回合=获得敌人(回合)
指数+=1
其他:
pos=self.board.getNextMove(self.board.cpu)
自板移动(旋转,位置)
self.tiles.add(Tile(self.tiles[pos],self.screen,getLetter(