当乌龟靠近另一只乌龟时,如何让乌龟做某事? [英] How can I make a turtle do something when it gets close to another turtle?

查看:37
本文介绍了当乌龟靠近另一只乌龟时,如何让乌龟做某事?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下午好,

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

I am simulating a virus outbreak with the use of turtles. I have come up with the following code, my question will be after the code:

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 像素内,它们也会被感染并变成红色.然而,这些新感染"的海龟不会感染其他海龟,因为与最初的海龟相比,它们没有被感染".我曾尝试将其更改为受感染 = infect_person(person) 但这只是给了我一个错误.我现在被困了一段时间,想知道是否有人可以提供帮助.我还考虑过制作两个列表:population 和fected_population 也许这可以解决我的问题,但我不知道如何在我的其余代码中实现它.

So when the simulation starts I infect 1 random person, and if other turtles get close, e.g. within 50 pixels, they will get infected too and turn red. However, these newly 'infected' turtles won't infect other turtles since they are not 'infected' as compared to the initial turtle. I have tried changing it to infected = infect_person(person) but this just gives me an error. I am stuck for a while now and was wondering if there is anyone who can help. I have also thought about making two lists: population and infected_population maybe that can solve my issue but I couldn't figure out how to implement that in the rest of my code.

提前致谢

推荐答案

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

I believe the solution is separating low level turtle operations into a Person subclass of Turtle from high level operations on people in the simulation:

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): 循环.

We could go further with turtle timer events to make the people more autonomous instead of the for _ in range(moves): loop.

这篇关于当乌龟靠近另一只乌龟时,如何让乌龟做某事?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆