最大递归深度超出(无法确定无限循环的原因)

时间:2015-07-07 23:53:13

标签: python loops recursion limit

希望那里的某个人可以理解一些非常混乱的代码。我在空闲时间慢慢进入python并决定做一个tic tac toe游戏。

问题是,在游戏结束时,如果人类玩家没有获胜,计算机的转弯功能会进入无限循环并使代码崩溃。

代码:

import random
board = [[' ',' ',' ',],[' ',' ',' ',],[' ',' ',' ',]]

def printboard():
    spacercount = 0
    print "    |     |  "
    for row in board:
        print row[0] + "   | " + row[1] + "   | " + row[2]
        if spacercount < 2:
            print "---------------"
            print "    |     |  "
            spacercount += 1
    print "\n"
    print "____________________ \n \n"


def userturn():
    x = raw_input("Choose row: ")
    y = raw_input("Choose column: ")
    print "\n"
    if board[int(x)][int(y)] == " ":
        board[int(x)][int(y)] = "X"
        printboard()
        if checkwin("X") == True:
            print "player has won!"
        elif checkfull() == True:
            print "it's a tie!"
        else:
            computerturn()
    else:
        print "this space is already taken, try again"
        userturn()

def computerturn():
    x = random.randint(1,2)
    y = random.randint(1,2)
    print "\n"
    if board[int(x)][int(y)] == " ":
        board[int(x)][int(y)] = "O"
        printboard()
        if checkwin("O") == True:
            print "computer has won!"
        elif checkfull() == True:
            print "it's a tie!"
        else:
            userturn()
    else:
        computerturn()

def checkwin(le):
    return ((board[0][2] == le and board[1][1] == le and board[2][0] == le) or
    (board[0][0] == le and board[1][1] == le and board[2][2] == le) or
    (board[0][0] == le and board[1][0] == le and board[2][0] == le) or
    (board[0][1] == le and board[1][1] == le and board[2][1] == le) or
    (board[0][2] == le and board[1][2] == le and board[2][2] == le) or
    (board[0][0] == le and board[0][1] == le and board[0][2] == le) or
    (board[1][0] == le and board[1][1] == le and board[1][2] == le) or
    (board[2][0] == le and board[2][1] == le and board[2][2] == le))

def checkfull():
    for x in board:
        if x[0] != " " and x[1] != " " and x[2] != " ":
            return True
        else:
            return False

printboard()
userturn()

我必须经过computerturn函数一百次试图确定为什么启动无限循环但是没有成功。

任何帮助非常感谢:)希望代码很简单,不需要评论,但如果是这样,我会将它们添加到

1 个答案:

答案 0 :(得分:1)

首先,您的空board

board = [[' ',' ',' ',],[' ',' ',' ',],[' ',' ',' ',]]

单个空格字符表示空方格。

接下来,打印电路板后,程序执行的第一件事就是调用userturn()。用户进行某种移动,如果成功,程序将调用computerturn()。但是,计算机是如何移动的?

它在电路板的一部分中查找空方块(不是全部 - 仅因为randint(1,2)而不是randint(0,2)而在第二和第三列和行中查找)。如果随机选择的方格被占用,则计算机会再次尝试。一旦它检查的所有方格都被占用,它将永远无法做任何事情,只能再次尝试。然后它将反复执行,直到它被最大递归深度停止。

我们如何解决这个问题?而不是让计算机反复从整个电路板中随机移动并使其继续尝试直到它选择有效的移动,我们将其移动限制为实际可用的移动。

def computerturn():
    available = [(x, y) for x,row in enumerate(board)
                 for y,column in enumerate(row)
                 if board[x][y] == ' ']
                # this is a list of actual available moves
    x,y = random.choice() # select from actual available moves
    # x = random.randint(0,2) # don't want this
    # y = random.randint(0,2) # don't want this
    print "\n"
    # don't need the following conditional
    #if board[x][y] == " ": # don't need the int() calls
    board[x][y] = "O" # this is the only thing that a successful move should do
    printboard() # unindent all this stuff
    if checkwin("O"): # don't need to compare a Boolean to True
        print "computer has won!"
    elif checkfull():
        print "it's a tie!"
    else:
        userturn()

    #else: # let's just take out this whole recursive call and fix the random move
    #    computerturn()

现在删除了评论和过时代码的“干净”版本:

def computerturn():
    available = [(x, y) for x,row in enumerate(board)
                 for y,column in enumerate(row)
                 if board[x][y] == ' ']
    x,y = random.choice()
    print "\n"
    board[x][y] = "O"
    printboard()
    if checkwin("O"):
        print "computer has won!"
    elif checkfull():
        print "it's a tie!"
    else:
        userturn()

我们hardly even need the comments - 你可以看到代码本身发生了什么。