我正在编写一个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()
答案 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")
您可以在这里找到大多数使用的功能(ord
,chr
,int
,range
,zip
)的文档:{{3 }}
答案 2 :(得分:0)
了解return process
和return 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
。而是将其分配给变量,然后为每个循环递增该变量。每elif
仅return
个
def