乌龟不响应空闲
Turtle not responding IDLE
我用海龟库写了这段代码。问题是当我在 IDLE 中 运行 这段代码时,一切正常,直到它到达函数 'putBall()' 的输入,并且 window 变成 'not responding'。
我尝试了 google 的一些建议,例如代码末尾的 'turtle.done' 或每个函数末尾的 'turtle.done',但在这两种情况下似乎什么都不做。
我想补充一点,我在在线服务 'Trinket' 中尝试了这段代码,它工作正常。
import turtle
def initialize_pen_screen():
s=turtle.getscreen()
s.setup(600,600)
t = turtle.Turtle()
ballOne = turtle.Turtle()
ballOne.shape('turtle')
ballOne.fillcolor("red")
ballOne.pencolor("red")
ballTwo = turtle.Turtle()
ballTwo.shape('turtle')
ballTwo.fillcolor("blue")
ballTwo.pencolor("blue")
t.shape("turtle")
s.bgcolor("gray")
return [t,ballOne,ballTwo]
def initialize_pen_screen_saviour():
t = turtle.Turtle()
ballOne = turtle.Turtle()
ballOne.shape('turtle')
ballOne.fillcolor("red")
ballOne.pencolor("red")
ballTwo = turtle.Turtle()
ballTwo.shape('turtle')
ballTwo.fillcolor("blue")
ballTwo.pencolor("blue")
t.shape("turtle")
return [t,ballOne,ballTwo]
def initialize_first(t,ballOne,ballTwo):
t.rt(180)
t.penup()
t.fd(150)
t.lt(90)
t.pensize(10)
ballOne.lt(90)
ballOne.penup()
ballOne.fd(90)
ballTwo.lt(90)
ballTwo.penup()
ballTwo.fd(150)
ballOne.rt(90)
ballTwo.rt(90)
#draw line that goes down
def stamp_up(t):
t.pendown()
t.stamp()
t.fd(250) #depends how long column
#print(t.pos(),'UP')
t.lt(90)
t.penup()
#draw line that goes up
def stamp_down(t):
t.fd(70)
#print(t.pos(),'Down')
t.lt(90)
t.pendown()
t.stamp()
t.fd(250) #depends how long column
t.rt(90)
t.penup()
t.fd(70)
t.rt(90)
#draw ball and save coordinate of reserved position in column
def move_ball(chosenBall,x,y):
chosenBall.goto(x+20,y+20)
chosenBall.fd(15)
chosenBall.dot(50)
newClosedPos=[x,y+50]
chosenBall.goto(0,150)
return newClosedPos
#put ball in table,and save another reserved position in column
def putBall(currentMove):
print("which column to put your ball?")
column=input()
if(column=='1'):
x=closedColumnOne[len(closedColumnOne)-1][0]
y=closedColumnOne[len(closedColumnOne)-1][1]
newClose=move_ball(currentMove,x,y)
closedColumnOne.append(newClose)
elif(column=='2'):
x=closedColumnTwo[len(closedColumnTwo)-1][0]
y=closedColumnTwo[len(closedColumnTwo)-1][1]
newClose=move_ball(currentMove,x,y)
closedColumnTwo.append(newClose)
elif(column=='3'):
x=closedColumnThree[len(closedColumnThree)-1][0]
y=closedColumnThree[len(closedColumnThree)-1][1]
newClose=move_ball(currentMove,x,y)
closedColumnThree.append(newClose)
elif(column=='4'):
x=closedColumnFour[len(closedColumnFour)-1][0]
y=closedColumnFour[len(closedColumnFour)-1][1]
newClose=move_ball(currentMove,x,y)
closedColumnFour.append(newClose)
elif(column=='5'):
x=closedColumnFive[len(closedColumnFive)-1][0]
y=closedColumnFive[len(closedColumnFive)-1][1]
newClose=move_ball(currentMove,x,y)
closedColumnFive.append(newClose)
return column
#tell state of world after put ball in table
def afterPutBall(SelectedColumn,columnBalls,tableSize,tableBall):
for k in range(0,tableSize):
for i in range(0,tableSize):
if(int(SelectedColumn)==k+1 and columnBalls[k][i]==0):
columnBalls[k][i]=tableBall
break
else:
continue
break
return columnBalls
#check if we in a win state
def checkWin(tableSize,columnBalls):
for k in range(0,tableSize-1):
for i in range(0,tableSize-1):
flagRow=1
flagColumn=1
flagDiagonalRight=1
flagDiagonalLeft=1
for j in range(0,tableSize-1):
#row win
if(columnBalls[j][i]==columnBalls[j+1][i] and columnBalls[j][i]!=0):
flagRow+=1
elif(flagRow!=0):
flagRow=1
#column win
if(columnBalls[i][j]==columnBalls[i][j+1] and columnBalls[i][j]!=0):
flagColumn+=1
#print(flagColumn)
elif(flagColumn!=0):
flagColumn=1
#diagonal right
if(i+j+1<=tableSize-1 and i+j<=tableSize-1 and j+k<=tableSize-1 and j+k+1<=tableSize-1): #end table
if(columnBalls[j+k][i+j]==columnBalls[j+k+1][i+j+1] and columnBalls[j+k][i+j]!=0):
flagDiagonalRight+=1
elif(flagDiagonalRight!=0):
flagDiagonalRight=1
#diagonal left
if(tableSize-j-i-1>=0 and tableSize-j-i-2>=0 and j+k<=tableSize-1 and j+k+1<=tableSize-1): #end table
if(columnBalls[j+k][tableSize-j-i-1]==columnBalls[j+k+1][tableSize-j-i-2] and columnBalls[j+k][tableSize-j-i-1]!=0):
flagDiagonalLeft+=1
elif(flagDiagonalLeft!=0):
flagDiagonalLeft=1
if flagRow==4 or flagColumn==4 or flagDiagonalLeft==4 or flagDiagonalRight==4:
return True
return False
def score_board():
score=turtle.Turtle()
score.ht()
score.color("green")
#score board
turtle.pensize(5)
turtle.speed(6)
turtle.penup()
turtle.goto(-250,150)
turtle.pendown()
turtle.rt(90)
for i in range(0,2):
turtle.fd(100)
turtle.lt(90)
turtle.fd(130)
turtle.lt(90)
turtle.fd(100)
turtle.lt(90)
turtle.fd(150-i*20)
turtle.lt(90)
turtle.penup()
turtle.ht()
#turtle.setposition(150,100)
#score write
score.speed('fastest')
score.penup()
score.goto(-250,150)
score.rt(90)
score.fd(50)
score.lt(90)
score.fd(35)
return score
def write_score(score,redPoints,bluePoints):
score.clear()
score.write(str(redPoints)+'-'+str(bluePoints),move=False ,font=("Verdana",
18, "normal"), align="left")
#build table
def build_table(tableSize,table,opponentOne,opponentTwo):
table.speed(6)
initialize_first(table,opponentOne,opponentTwo)
size_iter=int((tableSize-1)/2)
for i in range(0,size_iter+1):
stamp_up(table)
stamp_down(table)
if(tableSize%2==0): #even size table
stamp_up(table)
table.goto(0,250)
table.lt(90)
#tableSize=(2*(i+1)-1)
if 'main':
playAgain='yes'
s=turtle.getscreen()
s.setup(1000,1000)
s.bgcolor("gray")
score=score_board()
redPoints=0
bluePoints=0
while(playAgain=='yes' or playAgain=='Yes'):
tools=initialize_pen_screen_saviour()
table=tools[0]
opponentOne=tools[1]
opponentTwo=tools[2]
closedColumnOne=[[-150.0, -250.0]]
closedColumnTwo=[[-80.0, -250.0]]
closedColumnThree=[[-10.0, -250.0]]
closedColumnFour=[[60.0, -250.0]]
closedColumnFive=[[130.0, -250.0]]
tableSize=8
build_table(tableSize,table,opponentOne,opponentTwo)
#initilize table state balls
columnBalls=[]
for i in range(0,tableSize):
columnBall=[0]*tableSize
columnBalls.append(columnBall)
print(columnBalls)
myBall='A'
playAgain='yes'
#max moves:25
for i in range(0,25):
win=False
print("Player "+myBall+" play now")
if(myBall=='A'):
currentMove=opponentOne
myBall='B'
tableBall='A'
else:
currentMove=opponentTwo
myBall='A'
tableBall='B'
SelectedColumn=putBall(currentMove)
columnBalls=afterPutBall(SelectedColumn,columnBalls,tableSize,tableBall)
print(columnBalls)
win=checkWin(tableSize,columnBalls)
if(win):
#update score player blue
if(tableBall=='B'):
write_score(score,redPoints,bluePoints+1)
bluePoints+=1
#update score player red
else:
write_score(score,redPoints+1,bluePoints)
redPoints+=1
print('player '+tableBall+' WIN!!')
print('Do you want to play again?')
playAgain=input()
if(playAgain=='no' or playAgain=='No'):
break
elif(playAgain=='yes' or playAgain=='Yes'):
table.reset()
opponentOne.reset()
opponentTwo.reset()
break
#t.reset()
#t.clear()
请阅读https://whosebug.com/help/minimal-reproducible-example。
代码的第 80-81 行
print("which column to put your ball?")
column=input('')
向交互式 shell 打印提示并在海龟代码等待响应时暂停海龟屏幕 在单独的 shell 或终端 window 中输入。 (column = input('which column'
会做同样的事情。)要进入一个列,用户必须单击 window 并出现 'which column' 提示。你这样做,输入数字就可以了。
IDLE 与 运行 Python 模块的其他方式的区别在于,IDLE 将您的代码发送到与 IDLE UI 进程不同的单独进程来执行。我相信这就是为什么单击乌龟 window 会给您暂停消息,而当您的代码 运行 时,该消息不会出现。我将不得不做更多的实验来确定这是否适用于所有从 terminal/shell.
寻求输入的海龟程序
无论如何,GUI程序向terminal/shell请求输入是不正常的。 Turtle 提供了textinput 和numinput 的方法和功能。尝试使用其中之一。
我用海龟库写了这段代码。问题是当我在 IDLE 中 运行 这段代码时,一切正常,直到它到达函数 'putBall()' 的输入,并且 window 变成 'not responding'。 我尝试了 google 的一些建议,例如代码末尾的 'turtle.done' 或每个函数末尾的 'turtle.done',但在这两种情况下似乎什么都不做。 我想补充一点,我在在线服务 'Trinket' 中尝试了这段代码,它工作正常。
import turtle
def initialize_pen_screen():
s=turtle.getscreen()
s.setup(600,600)
t = turtle.Turtle()
ballOne = turtle.Turtle()
ballOne.shape('turtle')
ballOne.fillcolor("red")
ballOne.pencolor("red")
ballTwo = turtle.Turtle()
ballTwo.shape('turtle')
ballTwo.fillcolor("blue")
ballTwo.pencolor("blue")
t.shape("turtle")
s.bgcolor("gray")
return [t,ballOne,ballTwo]
def initialize_pen_screen_saviour():
t = turtle.Turtle()
ballOne = turtle.Turtle()
ballOne.shape('turtle')
ballOne.fillcolor("red")
ballOne.pencolor("red")
ballTwo = turtle.Turtle()
ballTwo.shape('turtle')
ballTwo.fillcolor("blue")
ballTwo.pencolor("blue")
t.shape("turtle")
return [t,ballOne,ballTwo]
def initialize_first(t,ballOne,ballTwo):
t.rt(180)
t.penup()
t.fd(150)
t.lt(90)
t.pensize(10)
ballOne.lt(90)
ballOne.penup()
ballOne.fd(90)
ballTwo.lt(90)
ballTwo.penup()
ballTwo.fd(150)
ballOne.rt(90)
ballTwo.rt(90)
#draw line that goes down
def stamp_up(t):
t.pendown()
t.stamp()
t.fd(250) #depends how long column
#print(t.pos(),'UP')
t.lt(90)
t.penup()
#draw line that goes up
def stamp_down(t):
t.fd(70)
#print(t.pos(),'Down')
t.lt(90)
t.pendown()
t.stamp()
t.fd(250) #depends how long column
t.rt(90)
t.penup()
t.fd(70)
t.rt(90)
#draw ball and save coordinate of reserved position in column
def move_ball(chosenBall,x,y):
chosenBall.goto(x+20,y+20)
chosenBall.fd(15)
chosenBall.dot(50)
newClosedPos=[x,y+50]
chosenBall.goto(0,150)
return newClosedPos
#put ball in table,and save another reserved position in column
def putBall(currentMove):
print("which column to put your ball?")
column=input()
if(column=='1'):
x=closedColumnOne[len(closedColumnOne)-1][0]
y=closedColumnOne[len(closedColumnOne)-1][1]
newClose=move_ball(currentMove,x,y)
closedColumnOne.append(newClose)
elif(column=='2'):
x=closedColumnTwo[len(closedColumnTwo)-1][0]
y=closedColumnTwo[len(closedColumnTwo)-1][1]
newClose=move_ball(currentMove,x,y)
closedColumnTwo.append(newClose)
elif(column=='3'):
x=closedColumnThree[len(closedColumnThree)-1][0]
y=closedColumnThree[len(closedColumnThree)-1][1]
newClose=move_ball(currentMove,x,y)
closedColumnThree.append(newClose)
elif(column=='4'):
x=closedColumnFour[len(closedColumnFour)-1][0]
y=closedColumnFour[len(closedColumnFour)-1][1]
newClose=move_ball(currentMove,x,y)
closedColumnFour.append(newClose)
elif(column=='5'):
x=closedColumnFive[len(closedColumnFive)-1][0]
y=closedColumnFive[len(closedColumnFive)-1][1]
newClose=move_ball(currentMove,x,y)
closedColumnFive.append(newClose)
return column
#tell state of world after put ball in table
def afterPutBall(SelectedColumn,columnBalls,tableSize,tableBall):
for k in range(0,tableSize):
for i in range(0,tableSize):
if(int(SelectedColumn)==k+1 and columnBalls[k][i]==0):
columnBalls[k][i]=tableBall
break
else:
continue
break
return columnBalls
#check if we in a win state
def checkWin(tableSize,columnBalls):
for k in range(0,tableSize-1):
for i in range(0,tableSize-1):
flagRow=1
flagColumn=1
flagDiagonalRight=1
flagDiagonalLeft=1
for j in range(0,tableSize-1):
#row win
if(columnBalls[j][i]==columnBalls[j+1][i] and columnBalls[j][i]!=0):
flagRow+=1
elif(flagRow!=0):
flagRow=1
#column win
if(columnBalls[i][j]==columnBalls[i][j+1] and columnBalls[i][j]!=0):
flagColumn+=1
#print(flagColumn)
elif(flagColumn!=0):
flagColumn=1
#diagonal right
if(i+j+1<=tableSize-1 and i+j<=tableSize-1 and j+k<=tableSize-1 and j+k+1<=tableSize-1): #end table
if(columnBalls[j+k][i+j]==columnBalls[j+k+1][i+j+1] and columnBalls[j+k][i+j]!=0):
flagDiagonalRight+=1
elif(flagDiagonalRight!=0):
flagDiagonalRight=1
#diagonal left
if(tableSize-j-i-1>=0 and tableSize-j-i-2>=0 and j+k<=tableSize-1 and j+k+1<=tableSize-1): #end table
if(columnBalls[j+k][tableSize-j-i-1]==columnBalls[j+k+1][tableSize-j-i-2] and columnBalls[j+k][tableSize-j-i-1]!=0):
flagDiagonalLeft+=1
elif(flagDiagonalLeft!=0):
flagDiagonalLeft=1
if flagRow==4 or flagColumn==4 or flagDiagonalLeft==4 or flagDiagonalRight==4:
return True
return False
def score_board():
score=turtle.Turtle()
score.ht()
score.color("green")
#score board
turtle.pensize(5)
turtle.speed(6)
turtle.penup()
turtle.goto(-250,150)
turtle.pendown()
turtle.rt(90)
for i in range(0,2):
turtle.fd(100)
turtle.lt(90)
turtle.fd(130)
turtle.lt(90)
turtle.fd(100)
turtle.lt(90)
turtle.fd(150-i*20)
turtle.lt(90)
turtle.penup()
turtle.ht()
#turtle.setposition(150,100)
#score write
score.speed('fastest')
score.penup()
score.goto(-250,150)
score.rt(90)
score.fd(50)
score.lt(90)
score.fd(35)
return score
def write_score(score,redPoints,bluePoints):
score.clear()
score.write(str(redPoints)+'-'+str(bluePoints),move=False ,font=("Verdana",
18, "normal"), align="left")
#build table
def build_table(tableSize,table,opponentOne,opponentTwo):
table.speed(6)
initialize_first(table,opponentOne,opponentTwo)
size_iter=int((tableSize-1)/2)
for i in range(0,size_iter+1):
stamp_up(table)
stamp_down(table)
if(tableSize%2==0): #even size table
stamp_up(table)
table.goto(0,250)
table.lt(90)
#tableSize=(2*(i+1)-1)
if 'main':
playAgain='yes'
s=turtle.getscreen()
s.setup(1000,1000)
s.bgcolor("gray")
score=score_board()
redPoints=0
bluePoints=0
while(playAgain=='yes' or playAgain=='Yes'):
tools=initialize_pen_screen_saviour()
table=tools[0]
opponentOne=tools[1]
opponentTwo=tools[2]
closedColumnOne=[[-150.0, -250.0]]
closedColumnTwo=[[-80.0, -250.0]]
closedColumnThree=[[-10.0, -250.0]]
closedColumnFour=[[60.0, -250.0]]
closedColumnFive=[[130.0, -250.0]]
tableSize=8
build_table(tableSize,table,opponentOne,opponentTwo)
#initilize table state balls
columnBalls=[]
for i in range(0,tableSize):
columnBall=[0]*tableSize
columnBalls.append(columnBall)
print(columnBalls)
myBall='A'
playAgain='yes'
#max moves:25
for i in range(0,25):
win=False
print("Player "+myBall+" play now")
if(myBall=='A'):
currentMove=opponentOne
myBall='B'
tableBall='A'
else:
currentMove=opponentTwo
myBall='A'
tableBall='B'
SelectedColumn=putBall(currentMove)
columnBalls=afterPutBall(SelectedColumn,columnBalls,tableSize,tableBall)
print(columnBalls)
win=checkWin(tableSize,columnBalls)
if(win):
#update score player blue
if(tableBall=='B'):
write_score(score,redPoints,bluePoints+1)
bluePoints+=1
#update score player red
else:
write_score(score,redPoints+1,bluePoints)
redPoints+=1
print('player '+tableBall+' WIN!!')
print('Do you want to play again?')
playAgain=input()
if(playAgain=='no' or playAgain=='No'):
break
elif(playAgain=='yes' or playAgain=='Yes'):
table.reset()
opponentOne.reset()
opponentTwo.reset()
break
#t.reset()
#t.clear()
请阅读https://whosebug.com/help/minimal-reproducible-example。
代码的第 80-81 行
print("which column to put your ball?")
column=input('')
向交互式 shell 打印提示并在海龟代码等待响应时暂停海龟屏幕 在单独的 shell 或终端 window 中输入。 (column = input('which column'
会做同样的事情。)要进入一个列,用户必须单击 window 并出现 'which column' 提示。你这样做,输入数字就可以了。
IDLE 与 运行 Python 模块的其他方式的区别在于,IDLE 将您的代码发送到与 IDLE UI 进程不同的单独进程来执行。我相信这就是为什么单击乌龟 window 会给您暂停消息,而当您的代码 运行 时,该消息不会出现。我将不得不做更多的实验来确定这是否适用于所有从 terminal/shell.
寻求输入的海龟程序无论如何,GUI程序向terminal/shell请求输入是不正常的。 Turtle 提供了textinput 和numinput 的方法和功能。尝试使用其中之一。