当一只乌龟靠近另一只乌龟时,我怎样才能让它做某事?

How can I make a turtle do something when it gets close to another turtle?

下午好,

我正在使用海龟模拟病毒爆发。我想出了以下代码,我的问题将在代码之后:

import turtle
import random
import time

def make_population(amount):
    """
    Creates a list representing a population with a certain amount of people.
    """
    population = []
    for person in range(amount):
        population.append(turtle.Turtle())
    for person in population:
        person.shape("circle")
        person.shapesize(0.2)
    return population

def random_move(person):
    """
    Makes a turtle move forward a random amount and then turn a random amount.
    """
    person.forward(random.randint(0,20))
    person.right(random.randint(-180,180))

def check_boundary(person):
    """
    Checks if a turtle is still within the given boundaries.
    """
    if -250 <= person.xcor() <= 250 and -250 <= person.ycor() <= 250:
        return
    person.setpos(random.randint(-200,200),random.randint(-200,200))

def infect_random(population):
    """
    Gets a random item from the population list and turns one red
    """
    infected = random.choice(population)
    infected.color("red")
    return infected

def infect_person(person):
    """
    Makes the turtle infected
    """
    infected_person = person.color("red")
    return infected_person

def simulation(amount, moves = 0):
    """
    Simulates a virus outbreak
    """
    border = 500
    window = turtle.Screen()
    turtle.setup(500,500)
    turtle.tracer(0)
    population = make_population(amount)
    for person in population:
        person.penup()
        person.setpos(random.randint(-250,250),random.randint(-250,250))
    turtle.update()
    infected = infect_random(population)
    for move in range(moves):
        turtle.tracer(0)
        for person in population:
            random_move(person)
            if person.distance(infected) < 50:
                infect_person(person)
            check_boundary(person)
        turtle.update()
        time.sleep(0.5)

    window.exitonclick()

所以当模拟开始时,我会感染 1 个随机人,如果其他海龟靠近,例如在 50 像素以内,它们也会被感染并变红。但是,这些新 'infected' 的海龟不会感染其他海龟,因为与最初的海龟相比,它们不是 'infected'。我尝试将其更改为 infected = infect_person(person) 但这只会给我一个错误。我现在被困了一段时间,想知道是否有人可以提供帮助。我还考虑过制作两个列表:population 和 infected_population 也许这可以解决我的问题,但我无法弄清楚如何在我的其余代码中实现它。

提前致谢

我相信你做了一个小例子但是我们错过了关于数据结构的信息,人是class吗?

您没有将此人重新指定为感染者。

当你感染第一批人时

infected = infect_random(population)

您将其指定为已感染, 但是当你感染其他人时你并没有, 你把它变成红色 return 那个人:

def infect_person(person):
    """
    Makes the turtle infected
    """
    infected_person = person.color("red")
    return infected_person

但是在你的代码中你没有分配它,

infect_person(person)

我建议要么使用一种方法来知道谁被感染了,谁没有被感染。例如: 如果你用过POO :

  • 你可以添加一个字段is_infected

  • 否则使用保存被感染者索引的列表?

如果附近有人被感染,那么您将不得不改变检测方式。对于一个人附近的所有人,如果一个人被感染,那么我也会被感染...

我认为解决方案是将低级别海龟操作从模拟中对人的高级操作分离到 TurtlePerson 子类:

from turtle import Screen, Turtle
from random import randint, choice
from time import sleep

class Person(Turtle):
    population = []

    def __init__(self):
        super().__init__(shape='circle')

        self.shapesize(0.2)
        self.penup()
        self.setpos(randint(-250, 250), randint(-250, 250))

        Person.population.append(self)

    @classmethod
    def all_infected(cls):
        return [person for person in cls.population if person.infected()]

    def infect(self):
        self.color('red')

    def infected(self):
        return self.pencolor() == 'red'

    def random_move(self):
        """
        Makes a turtle move forward a random amount and then turn a random amount.
        """

        self.right(randint(-180, 180))
        self.forward(randint(0, 20))

        # checks if turtle is still within the given boundaries.

        if not (-250 < self.xcor() < 250 and -250 < self.ycor() < 250):
            self.undo()  # undo forward()

def make_population(amount):
    """
    Creates a list representing a population with a certain amount of people.
    """

    for _ in range(amount):
        Person()

def infect_random():
    """
    Gets a random item from the population list and turns one red
    """

    person = choice(Person.population)
    person.infect()

def simulation(amount=20, moves=100):
    """
    Simulates a virus outbreak
    """

    make_population(amount)

    infect_random()

    screen.update()

    for _ in range(moves):
        for person in Person.population:
            person.random_move()

            if not person.infected():
                for infected in Person.all_infected():
                    if person.distance(infected) < 50:
                        person.infect()

        screen.update()
        sleep(0.5)

screen = Screen()
screen.setup(500, 500)
screen.tracer(0)

simulation()

screen.exitonclick()

我们可以进一步使用海龟计时器事件来让人们更加自主,而不是 for _ in range(moves): 循环。