乌龟不响应空闲

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 的方法和功能。尝试使用其中之一。