Python程序在if语句后未返回函数

时间:2018-10-24 11:05:23

标签: python-3.x

我正在编写一个Python Tic-Tac-Toe机器人,它在发出一条if语句后一直停止运行,而不是重新启动该函数(下面的代码)。我是Python的初级入门者,希望能得到更简单的答案。

代码:

def process():
    uin = input('enter a move...')
    if uin == 'A1':
        atwo.remove('A1')
        bone.remove('A1')
        btwo.remove('A1')
        sou = random.choice(aone)
        print(sou)
        aone.remove(sou)
        return process
    elif uin == 'A2':
        aone.remove('A2')
        athree.remove('A2')
        btwo.remove('A2')
        sou = random.choice(atwo)
        print(sou)
        atwo.remove(sou)
        return process
    elif uin == 'A3':
        atwo.remove('A3')
        btwo.remove('A3')
        bthree.remove('A3')
        sou = random.choice(athree)
        print(sou)
        athree.remove(sou)
        return process
    elif uin == 'B1':
        aone.remove('B1')
        btwo.remove('B1')
        cone.remove('B1')
        sou = random.choice(bone)
        print(sou)
        bone.remove(sou)
        return process
    elif uin == 'B2':
        aone.remove('B2')
        atwo.remove('B2')
        athree.remove('B2')
        bone.remove('B2')
        bthree.remove('B2')
        cone.remove('B2')
        ctwo.remove('B2')
        cthree.remove('B2')
        sou = random.choice(btwo)
        print(sou)
        btwo.remove(sou)
        return process
    elif uin == 'B3':
        athree.remove('B2')
        btwo.remove('B2')
        cthree.remove('B2')
        sou = random.choice(bthree)
        print(sou)
        bthree.remove(sou)
        return process
    elif uin == 'C1':
        bone.remove('C1')
        btwo.remove('C1')
        ctwo.remove('C1')
        sou = random.choice(cone)
        print(sou)
        bthree.remove(sou)
        return process
    elif uin == 'C2':
        btwo.remove('C2')
        cone.remove('C2')
        cthree.remove('C2')
        sou = random.choice(ctwo)
        ctwo.remove(sou)
        return process
    elif uin == 'C3':
        btwo.remove('C3')
        btwo.remove('C3')
        ctwo.remove('C3')
        sou = random.choice(cthree)
        print(sou)
        cthree.remove(sou)
        return process 
process()

4 个答案:

答案 0 :(得分:0)

将函数放入while循环

while True:
    process()

然后,在达到赢得游戏的条件的情况下,在您的函数内部,稍作休息,使其结束循环。

答案 1 :(得分:0)

根据我在您的代码中看到的,您正在管理3个不同的“哪里有空位”列表。我认为只照看一个列表,然后在选择放置位置之前获得“开放”位置会更容易。

您正试图自行调用相同的函数-这将导致每个函数调用产生大量的堆栈帧(python通过为该函数准备一个“可变堆栈”存储区来隔离函数调用,该函数将在之后清除如果您的函数递归调用自身(它们会累积并阻塞计算机内存),则大多数情况下最好避免这种情况,并使用循环非递归地进行编码。

一块木板自然会产生一个2维的清单,您还选择通过字母和1个索引对其进行处理,从而导致清单中的索引与“输出”之间进行一些来回的计算。 / p>

我添加了一些功能来执行某些操作(返回所有未使用的空间,设置空间,漂亮地打印板子,检查获胜):

ordA = ord("A")  # get the ascii value of A so we can compute the letter by the list-index

def getFieldsNotUsed(f):
    """Return all possible fields that are empty (if .strip()ed)"""
    for r_idx,row in enumerate(field):
        for c_idx,col in enumerate(row):
            if col.strip() == "":
                # get the letter that belongs to "A" + the 0bases list index
                yield chr(ordA+r_idx)+str(c_idx+1)

def setField(player,coord,f):
    """Places player (X or O) at coord [A1,A2,A3,B1,B2,B3,C1,C2,C3]-string"""
    print(f"{player} sets at {coord}:\n")
    r_idx = ord(coord[0])-ordA # compute the list index for row 
    c_idx = int(coord[1])-1    # colum is easier, just int-ify the string and subtract 1
    f[r_idx][c_idx]=player

def printField(f):
    """Pretty prints the field given by f"""
    middle = 2
    for r in f:
        print("\t " + " | ".join( r ))
        if middle: # 0 is False
            print("\t" + "---|---|---")
            middle -= 1
    print("\n")

def checkWin(f):
    """Retunrs a winner-string or None - checks all rows && columns && both diagonals"""
    # check rows
    for r in f:
        if all( v == r[0] and v.strip() for v in r):
            return f"{r[0]} won!"
    # check cols
    for c in zip(*f):
        if all( v == c[0] and v.strip() for v in c):
            return f"{r[0]} won!"
    # check diag
    if (f[0][0] == f[1][1] == f[2][2] or 
        f[0][2] == f[1][1] == f[2][0]) and f[1][1].strip() :
        return f"{r[0]} won!"

    return None # no wins

主程序

import random

# prepare the empty field with spaces - it is the only list to tend to
field = [[" "," "," "],[" "," "," "],[" "," "," "]]
player = ""
# get all fields that are still open
open_fields = list(getFieldsNotUsed(field)) 

# loop while open fields are present
while open_fields:
    # toggle the player from "" (at start) to X, then from X to O and back
    player = "X" if player != "X" else "O"

    # choose randomly, set player, print field
    place_where = random.choice(open_fields)
    setField(player, place_where,field)
    printField(field)     

    # check win-conditions, continue loop if None else break
    win = checkWin(field)
    if win is None:
        open_fields = list(getFieldsNotUsed(field))
    else:
        # we got a winner - print it and exit loop
        print(win)
        break
else:
    print("Draw")

您可以在这里找到大多数使用的功能(ordchrintrangezip)的文档:{{3 }}

答案 2 :(得分:0)

了解return processreturn process()之间的区别很重要:

return process不会执行任何操作,只会退出该函数,其结果是对流程函数的引用。您的最后一行可以像result = process()那样使用它,然后可以循环显示该结果,并且可以在游戏结束时退出该应用程序,只需返回None而不是该函数即可。

return process()将执行process()函数并返回其自己的结果。您可能会不止一次地进入函数,但这意味着它将开始将对函数的调用链接起来,并在游戏结束时将所有函数链接退出。对于井字游戏,它应该可以工作,但是对于更复杂的东西,这可能会导致堆栈溢出。

正确的方法是在对process()的调用上有一个循环,而不必理会返回过程本身。

答案 3 :(得分:-1)

您不应在每个display() { this.dashboardInfoService.findOneByOne() .then((res) => { const tab = []; for (let i = 0; i < res.length; i++) { tab.push(res[i][0]); } this.findPaths(tab); this.loadItems(tab); }) .catch((err: any) => { if (environment.debugLevel >= 3) console.error(err); }); } -return循环之后使用if。而是将其分配给变量,然后为每个循环递增该变量。每elifreturn

def