[英]How can I make a turtle do something when it gets close to another turtle?
Good afternoon,下午好,
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()
So when the simulation starts I infect 1 random person, and if other turtles get close, eg within 50 pixels, they will get infected too and turn red.因此,当模拟开始时,我会感染 1 个随机人,如果其他海龟靠近,例如在 50 像素内,它们也会被感染并变成红色。 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.
我曾尝试将其更改为受感染的 = infect_person(person) 但这只会给我一个错误。 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.
我还考虑过制作两个列表:人口和感染人口也许可以解决我的问题,但我无法弄清楚如何在我的代码的 rest 中实现它。
Thanks in advance提前致谢
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:我相信解决方案是将低级海龟操作与模拟中对人的高级操作分离为
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()
We could go further with turtle timer events to make the people more autonomous instead of the for _ in range(moves):
loop.我们可以 go 进一步使用海龟计时器事件,以使人们更加自主,而不是
for _ in range(moves):
循环。
I believe you have made a small example but we miss information about data structure, is person a class?我相信你做了一个小例子,但我们错过了有关数据结构的信息,人是 class 吗?
You do not reassign the person as infected.您不会将该人重新指定为感染者。
When you infected the first people当你感染了第一批人
infected = infect_random(population)
you assign it as infected, but when you infect other persone you don't, you turn it in red return the person:您将其指定为已感染,但是当您感染其他人时,您没有将其变为红色,返回该人:
def infect_person(person):
"""
Makes the turtle infected
"""
infected_person = person.color("red")
return infected_person
but hen In your code you don't assign it,但是在你的代码中你没有分配它,
infect_person(person)
I suggest either to use a way to know who is infected or who is not.我建议要么使用一种方法来了解谁被感染或谁没有被感染。 For example: If you have used POO:
例如:如果您使用过 POO:
you can add a field is_infected你可以添加一个字段 is_infected
else use a list that keeps the indices of the person being infected?否则使用一个列表来保存被感染者的索引?
Doing that you will have to change the way you test if someone near is infected.如果附近有人被感染,那么您将不得不改变测试方式。 For all person near a person if one is infected then I am becoming infected...
对于一个人附近的所有人,如果有人被感染,那么我就会被感染......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.