1

下午好,

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

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) 但这只会给我一个错误。我现在被困了一段时间,想知道是否有人可以提供帮助。我还考虑过制作两个列表:人口和感染人口也许可以解决我的问题,但我无法弄清楚如何在我的其余代码中实现它。

提前致谢

4

2 回答 2

2

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

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

在此处输入图像描述

于 2020-05-06T19:20:00.387 回答
1

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

您不会将该人重新指定为感染者。

当你感染了第一批人

infected = infect_random(population)

您将其指定为已感染,但是当您感染其他人时,您没有将其变为红色,返回该人:

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

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

infect_person(person)

我建议要么使用一种方法来了解谁被感染或谁没有被感染。例如:如果您使用过 POO :

  • 您可以添加一个字段 is_infected

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

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

于 2020-05-06T12:36:31.067 回答