【问题标题】:How to move multiple turtles in a for loop?如何在 for 循环中移动多个海龟?
【发布时间】:2021-02-25 23:20:10
【问题描述】:

所以,我最近刚开始接触 Python,在我的课堂上,我的任务是让 10 只乌龟都在移动并且应该在终点线停下来进行一场乌龟赛跑。我被指示为海龟制作一个列表,并有一个 while 循环让它们移动随机数量,并有一个嵌套的 if 循环来检查获胜者。我无法让所有海龟同时移动,当我运行我的代码时,它会一个接一个地移动海龟,而不是一起移动,有什么想法吗?

import turtle as trtl
import random as rand
zoomers = []
zom = [0,1,2,3,4,5,6,7,8,9]
tloc = -130
trtl.penup()
trtl.goto(-150, 150)
trtl.pendown()
trtl.goto(-150,-140)
trtl.penup()
trtl.goto(180,150)
trtl.pendown()
trtl.goto(180,-140)
trtl.hideturtle()
for z in zom:
  zoom = trtl.Turtle("turtle")
  zoom.penup()
  zoom.goto(-150,-tloc)
  tloc += 25
  robux = rand.randrange(0,20)
  zoomers.append(zoom)
  for n in zoomers:
    cash = 0
    while cash < 100:
      zoom.forward(robux)
      cash = cash + 1
    if zoom.xcor() == 180:
      print("We have a winner!")
      break```

【问题讨论】:

  • 您是否假设它们平行移动,例如如果两只海龟在同一个 while 循环迭代中到达终点线,它们是 both 赢家吗?还是会按顺序进行,例如首先找到阈值的乌龟获胜
  • 请提供预期的minimal, reproducible example。显示中间结果与您的预期不同的地方。我们应该能够复制和粘贴您的代码的连续块,执行该文件,并重现您的问题以及跟踪问题点的输出。这让我们可以根据您的测试数据和所需的输出来测试我们的建议。在这种情况下,“这不符合我的要求”是不够的。
  • 目前还不清楚您希望它如何工作。看来您在测试之前编写了大约 30 行代码。请正确描述您的方法:您的三重嵌套循环(for-for-while)似乎与您想要的结果背道而驰。您的 while 循环只是一个 100 次迭代的循环;你在做什么,为什么不使用for?恐怕“解决”您描述的问题将涉及为您编写程序的主体,这超出了这里的范围。
  • 我必须使用 while 语句使它们向前移动一个随机量,而 while 循环为 100 是我放置的可能会更改为更低的值。

标签: python turtle-graphics python-turtle


【解决方案1】:

没有直接的方法可以做到这一点,但这是下一个最好的方法。

创建一个乌龟Screen。将其tracer() 设置为0,并在循环的每次迭代中更新屏幕。它可能会变得太快,因此请从 time 模块中导入 sleep 以减慢速度。

小例子:

from turtle import Turtle, Screen
from random import randrange
from time import sleep

wn = Screen()
wn.tracer(0)

t1 = Turtle('turtle')
t2 = Turtle('turtle')

t1.penup()
t2.penup()

t1.goto(-100, 50)
t2.goto(-100, -50)

while True:
    sleep(0.1)
    t1.forward(randrange(0, 20))
    t2.forward(randrange(0, 20))
    wn.update()

【讨论】:

    【解决方案2】:

    到目前为止,所有其他解决方案都在固定时间片内将海龟移动了随机距离。让我们把它转过来,在随机时间片中移动海龟一个恒定的距离:

    from turtle import Turtle, Screen
    from random import randrange
    
    def run(turtle):
        turtle.forward(5)
    
        if turtle.xcor() < half_width:
            screen.ontimer(lambda: run(turtle), randrange(20, 150))
    
    screen = Screen()
    
    half_width = screen.window_width() / 2
    lane_width = 20
    
    for order, color in enumerate(['red', 'green', 'blue']):
        turtle = Turtle('turtle')
        turtle.speed('fastest')
        turtle.color(color)
        turtle.penup()
    
        turtle.goto(-half_width, (order | 1) * lane_width)
        lane_width *= -1
        run(turtle)
    
    screen.exitonclick()
    

    【讨论】:

      【解决方案3】:

      你正在使用一只乌龟。您可以通过创建多个海龟对象轻松做到这一点。我用了 3 个海龟对象,它们有一个小种族。

      试试这段代码,你可以在这段代码中实现你的获胜者逻辑。

      import turtle as trtl
      import random as rand
      
      zoom1 = trtl.Turtle()
      zoom2 = trtl.Turtle()
      zoom3 = trtl.Turtle()
      
      zoomers = [zoom1, zoom2, zoom3]
      
      for zoom in zoomers:
        zoom.penup()
      
      zoom1.goto(-150, 150)
      zoom2.goto(-120, 150)
      zoom3.goto(-90, 150)
      
      for zoom in zoomers:
        zoom.pendown()
        zoom.right(90)
      
      for zoom in zoomers:
        robux = rand.randrange(10,50)
        zoom.forward(robux)
      
      

      编辑:您需要非阻塞代码来实现海龟同时且彼此独立地移动。您可以通过使用多线程来做到这一点。试试this

      【讨论】:

      • @AnnZen 我想同时移动海龟,实现多线程并启动那些海龟?因为在循环中运行它们会阻塞下一个海龟。你能推荐一些更简单的东西吗?
      • 是的,但每次迭代更新屏幕是准确的。问题仍然是相同的海龟一个接一个地移动,它们的移动不是相互独立的。 Found this by the way
      【解决方案4】:

      我们甚至可以在不使用 turtle 库的情况下对此进行建模:

      import random
      
      twerbles = list(zip(range(10), [0]*10)) #list of turtles all starting at position 0 (numbered 0-10)
      finishline = 10 #the threshold they must pass
      
      while True:
          twerbles = [(twerble, position+random.randint(1,2)) for twerble, position in twerbles] #move each turtle up a random amount.
      
          print(twerbles) #this can be removed if you dont want to see their positions as they go
      
          winners = [twerble for twerble, position in twerbles if position >= finishline] #list of turtles that passed the threshold (if any)
          if winners: print(winners); break #if there are winners print them and stop looping
      
      [(0, 1), (1, 2), (2, 1), (3, 2), (4, 1), (5, 2), (6, 1), (7, 1), (8, 1), (9, 2)]
      [(0, 2), (1, 3), (2, 2), (3, 3), (4, 2), (5, 4), (6, 3), (7, 3), (8, 3), (9, 3)]
      [(0, 4), (1, 5), (2, 4), (3, 4), (4, 4), (5, 6), (6, 5), (7, 5), (8, 4), (9, 5)]
      [(0, 5), (1, 7), (2, 6), (3, 5), (4, 6), (5, 8), (6, 6), (7, 7), (8, 5), (9, 6)]
      [(0, 6), (1, 8), (2, 8), (3, 6), (4, 7), (5, 9), (6, 7), (7, 9), (8, 7), (9, 7)]
      [(0, 8), (1, 9), (2, 10), (3, 7), (4, 9), (5, 11), (6, 8), (7, 11), (8, 8), (9, 9)]
      
      [2, 5, 7] #winning turtles
      

      与海龟一起移动

      import turtle as trtl
      import random
      
      finishline = 30
      
      twerbles = [(trtl.Turtle("turtle"), 0) for i in range(10)]
      
      for i,(twerble,position) in enumerate(twerbles):
        twerble.penup()
        twerble.goto(-150,150 - i*25)
      
      while True:
          twerbles = [(twerble, position+random.randint(1,2)) for twerble, position in twerbles]
      
          for twerble, position in twerbles:
              twerble.forward(position)
      
          winners = [twerble for twerble, position in twerbles if position >= finishline]
          if winners:
              break
      

      【讨论】:

        【解决方案5】:

        您需要创建一个海龟集合。每只乌龟循环移动(一步),直到乌龟完成。

        试试这个代码:

        import turtle as trtl
        import random as rand
        zoomers = []
        zom = [0,1,2,3,4,5,6,7,8,9]
        tloc = -130
        trtl.penup()
        trtl.goto(-150, 150)
        trtl.pendown()
        trtl.goto(-150,-140)
        trtl.penup()
        trtl.goto(180,150)
        trtl.pendown()
        trtl.goto(180,-140)
        trtl.hideturtle()
        
        zoomers = [trtl.Turtle("turtle") for z in zom]
        
        for i,t in enumerate(zoomers):
          t.penup()
          t.goto(-150,150 - i*25)
        
        
        for i,z in enumerate(zom):
          zoom = zoomers[i]   #trtl.Turtle("turtle")
          tloc += 25
        #  zoomers.append(zoom)
        
        running = True
        while running:
            for zoom in zoomers:
              robux = rand.randrange(0,20)
              zoom.forward(robux)
              if zoom.xcor() >= 180:
                print("We have a winner!")
                running = False
                break
        
        input('Press enter to exit...')
        

        【讨论】:

          猜你喜欢
          • 2018-04-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-29
          • 1970-01-01
          相关资源
          最近更新 更多