Tictaoe Alpha Beta修剪运行时错误:pygame的最大递归深度超过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

所以,我正在编写一个非常简单的Tictatcoe程序,它使用alpha-beta修剪来搜索针对玩家的下一步行动,但在我想运行时遇到了问题。我尝试过任何我想到的方法来解决这个问题,甚至做了一个Java逐行的逻辑,这个逻辑运行得很好,但python的逻辑根本不起作用

这是我的代码:

#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(