【问题标题】:How can I make a turtle do something when it gets close to another turtle?当一只乌龟靠近另一只乌龟时,我怎样才能让它做点什么?
【发布时间】:2020-05-06 11:55:43
【问题描述】:

下午好,

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

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

提前致谢

【问题讨论】:

    标签: python python-3.x turtle-graphics python-turtle


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      当你感染第一批人时

      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

      • 还要使用保存被感染者索引的列表吗?

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

      【讨论】:

        猜你喜欢
        • 2022-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-06
        • 1970-01-01
        相关资源
        最近更新 更多