Python 多只海龟(看似)同时移动

问题描述 投票:0回答:2

我正在为我的老师测试一些东西,他想看看如果我们模拟同步,下面的程序如何运行得更快(我知道它不可能完全同步,这只是一个为了学习而进行的实验/练习)多只海龟的移动。我尝试过使用诸如多处理、线程之类的模块,甚至一些疯狂愚蠢的时间和延迟尝试(我在高中,我刚刚了解了Python中的课程,因为我上周问过一个问题) 因此,在多次失败的尝试之后,我想问是否有人有一些其他可以尝试的想法,或者模拟海龟同时运动的方向

进口龟 从海龟进口海龟

turtle.getscreen().delay(0)
class MyTurtle(Turtle):
    def petal(self):
        for i in range(90):
            self.fd(1)
            self.rt(1)
        self.rt(90)
        for i in range(90):
            self.fd(1)
            self.rt(1)

    def stem(self):
        self.pencolor('green')
        self.fd(250)

    def flowerhead(self):
        for i in range(9):
          self.pencolor('red')
          self.begin_fill()
          self.petal()
          self.lt(230)
          self.end_fill()

    def stempetal(self):
        self.seth(90)
        self.rt(15)
        self.fillcolor('green')
        self.begin_fill()
        self.petal()
        self.end_fill()

    

tony = MyTurtle(shape='turtle')
todd = MyTurtle(shape='turtle')
tina = MyTurtle(shape='turtle')
tiny = MyTurtle(shape='turtle')
tweeny = MyTurtle(shape='turtle')


def flower1():
    todd.speed('fastest')
    todd.fillcolor('blue')
    todd.flowerhead()
    todd.seth(270)
    todd.stem()
    todd.stempetal()
            
def flower2():
    tony.speed('fastest')
    tony.setpos(80, -15)
    tony.pencolor('green')
    tony.goto(0, -200)
    tony.fillcolor('purple')
    tony.goto(80,-15)
    tony.rt(40)
    tony.flowerhead()
    

def flower3():
    tina.speed('fastest')
    tina.setpos(-80, -15)
    tina.pencolor('green')
    tina.goto(0, -200)
    tina.fillcolor('teal')
    tina.goto(-80,-15)
    tina.lt(40)
    tina.flowerhead()
    
    
def flower4():
    tiny.speed('fastest')
    tiny.setpos(160, -25)
    tiny.pencolor('green')
    tiny.goto(0, -200)
    tiny.fillcolor('black')
    tiny.goto(160, -25)
    tiny.flowerhead()
    
    
def flower5():
    tweeny.speed('fastest')
    tweeny.setpos(-160, -25)
    tweeny.pencolor('green')
    tweeny.goto(0, -200)
    tweeny.fillcolor('pink')
    tweeny.goto(-160,-25)
    tweeny.lt(40)
    tweeny.flowerhead()
    
    
flower2()
tony.hideturtle()
flower4()
tiny.hideturtle()
flower3()
tina.hideturtle()
flower5()
tweeny.hideturtle()
flower1()
todd.hideturtle()
python turtle-graphics python-turtle simultaneous
2个回答
5
投票

解决方案是禁用更新每只海龟的位置,然后在计算出新位置后强制整个屏幕更新。

import turtle

# our two turtle instances
first, second = turtle.Turtle(), turtle.Turtle()

first.tracer(False)  # disable updating view on screen for this turtle!
second.tracer(False)

# make one move - note this will not appear on screen.
first.forward(50)
second.left(20)

# when you are ready to see the whole screen update
turtle.update()

要做你想做的事,你必须确保新动作在

turtle.update()
之前完成。您无法像现在一样将其保持为串行执行 - 换句话说,您无法按顺序运行
flower1
,然后运行
flower2

这是一对乌龟的示例,它们将同时在屏幕上生成随机图案:

import turtle
import random

# our two turtle instances
turtles = [turtle.Turtle(), turtle.Turtle()]
for turtle_object in turtles:
    turtle_object.tracer(False)

for _ in range(10000):  # make ten thousand moves.

    for t in turtles:
        # list the possible moves available
        possible_moves = [t.forward, t.back, t.right, t.left]
        # give it a random value
        random_value = random.randint(0, 100)
        # make a random move 
        random.choice(possible_moves)(random_value)

    # update the whole screen now that the new positions have been calculated
    turtle.update()

这里的技巧是要注意,计算每只乌龟的每个新位置,然后告诉整个屏幕进行更新,然后才继续进行下一步。每一步都必须尽可能细致。


3
投票

您要求了两个不同的东西,“跑得更快”和“模拟同时运动”。我相信我们可以(分别)做到这两点,但我相信

tracer()
update()
是这种情况下的答案,因为它们只是一个创可贴来掩盖真正的问题。

想看看下面的程序如何运行得更快

如果你想让它运行得更快,请修复bottleneck,即

petal()
函数。将其替换为使用海龟内置
circle()
函数的东西,速度更快。例如:

def petal(self):
    self.circle(-60, 90)
    self.rt(90)
    self.circle(-60, 90)

这会将您的代码速度提高 25 倍,而无需进行其他任何更改。

模拟海龟的同时移动

这可以通过海龟自己的

ontimer()
事件处理程序和一些仔细的编程来完成。令人惊讶的是,我们使用您原来的
petal()
逻辑,因为它将图形分解为微小的步骤,在这些步骤之间我们可以关闭对另一个定时事件的处理:

from random import randint
from turtle import Turtle, Screen

class MyTurtle(Turtle):

    def petals(self, size=30, count=8, speed=100):
        if size == 30:
            self.begin_fill()

        if size > 0:  # drawing leading edge of petal
            self.fd(3)
            self.rt(3)

            screen.ontimer(lambda: self.petals(size - 1, count, speed), speed)
            return

        if size == 0:  # switch to other edge of petal
            self.rt(90)

        if size > -30:  # drawing trailing edge of petal
            self.fd(3)
            self.rt(3)

            screen.ontimer(lambda: self.petals(size - 1, count, speed), speed)
            return

        self.end_fill()  # finish this petal
        self.lt(230) # prepare for the next petal

        if count > 0:  # drawing the next petal
            screen.ontimer(lambda: self.petals(count=count - 1, speed=speed), speed)
            return

        self.hideturtle()  # finished drawing

    def stem(self):
        self.pencolor('green')
        self.fd(250)

    def flowerhead(self):
        self.pencolor('red')

        self.petals(speed=randint(50, 250))

def flower2():
    tony.color('green', 'purple')
    tony.penup()
    tony.goto(0, -200)
    tony.pendown()
    tony.showturtle()
    tony.goto(80, -15)
    tony.rt(40)
    tony.flowerhead()

def flower3():
    tina.color('green', 'turquoise')
    tina.penup()
    tina.goto(0, -200)
    tina.pendown()
    tina.showturtle()
    tina.goto(-80, -15)
    tina.lt(40)
    tina.flowerhead()

def flower5():
    tweeny.color('green', 'pink')
    tweeny.penup()
    tweeny.goto(0, -200)
    tweeny.pendown()
    tweeny.showturtle()
    tweeny.goto(-160, -25)
    tweeny.lt(40)
    tweeny.flowerhead()

tony = MyTurtle(shape='turtle', visible=False)
tina = MyTurtle(shape='turtle', visible=False)
tweeny = MyTurtle(shape='turtle', visible=False)

screen = Screen()

screen.ontimer(flower2, 100)
screen.ontimer(flower3, 120)
screen.ontimer(flower5, 100)

screen.mainloop()

运行图像

它不会更快,因为这只是一个模拟。 (嗯,它确实走得更快一点,因为我把花瓣画得稍微粗糙一些,以换取速度。)如果你仔细观察,你可以看到海龟(故意)以它们自己的速度移动。

© www.soinside.com 2019 - 2024. All rights reserved.