You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python Turtle的可控新冠病毒模拟项目技术问题咨询

解决你的Python Turtle新冠模拟控制与切换问题

我来帮你搞定这两个核心问题,咱们一步一步拆解修改:


问题1:分离控制逻辑,用方向键操控指定海龟

原来靠颜色标记控制状态的方式不够灵活,咱们给Person类加个专属属性跟踪控制状态,再绑定方向键事件精准控制目标个体:

  1. 先修改Person类的初始化逻辑,添加控制状态属性:
class Person(Turtle):
    population = []
    controlled_person = None  # 类属性,全局跟踪当前被控制的海龟

    def __init__(self):
        super().__init__(shape='circle')
        self.shapesize(0.4)
        self.penup()
        self.setpos(randint(-250, 250), randint(-250, 250))
        self.is_controlled = False  # 初始未被控制
        self.color('black')  # 明确健康状态为黑色
        Person.population.append(self)
  1. 编写方向键控制函数,只让被控制的海龟响应:
def move_up():
    if Person.controlled_person and not Person.controlled_person.infected():
        Person.controlled_person.setheading(90)
        Person.controlled_person.forward(10)
        # 边界检测,防止海龟跑出屏幕
        if not (-250 < Person.controlled_person.xcor() < 250 and -250 < Person.controlled_person.ycor() < 250):
            Person.controlled_person.undo()

def move_down():
    if Person.controlled_person and not Person.controlled_person.infected():
        Person.controlled_person.setheading(270)
        Person.controlled_person.forward(10)
        if not (-250 < Person.controlled_person.xcor() < 250 and -250 < Person.controlled_person.ycor() < 250):
            Person.controlled_person.undo()

def move_left():
    if Person.controlled_person and not Person.controlled_person.infected():
        Person.controlled_person.setheading(180)
        Person.controlled_person.forward(10)
        if not (-250 < Person.controlled_person.xcor() < 250 and -250 < Person.controlled_person.ycor() < 250):
            Person.controlled_person.undo()

def move_right():
    if Person.controlled_person and not Person.controlled_person.infected():
        Person.controlled_person.setheading(0)
        Person.controlled_person.forward(10)
        if not (-250 < Person.controlled_person.xcor() < 250 and -250 < Person.controlled_person.ycor() < 250):
            Person.controlled_person.undo()
  1. 在屏幕初始化后绑定方向键监听:
screen = Screen()
screen.setup(500,500)
screen.tracer(0)
screen.bgcolor(str(input("Enter desired background color: ")))
# 绑定方向键事件
screen.onkeypress(move_up, "Up")
screen.onkeypress(move_down, "Down")
screen.onkeypress(move_left, "Left")
screen.onkeypress(move_right, "Right")
screen.listen()  # 让屏幕开始监听键盘输入

问题2:被控制海龟感染后自动切换新健康个体

咱们需要在模拟循环中定期检查当前被控制者的状态,一旦感染就从健康人群里挑选新的控制对象:

  1. 修复原代码中的错误(比如重复的all_infected方法,以及posess_random的无效逻辑):
# 修复重复的方法,改为判断被控制个体
@classmethod
def all_possessed(cls):
    return [person for person in cls.population if person.possessed()]

# 重写选被控制者的函数,加入状态重置逻辑
def posess_random():
    # 筛选健康个体:未感染、未被控制
    healthy_people = [p for p in Person.population if not p.infected() and not p.is_controlled]
    if healthy_people:
        # 先重置之前的被控制者状态
        if Person.controlled_person:
            Person.controlled_person.color('black')
            Person.controlled_person.is_controlled = False
        # 选新的被控制者并标记
        person = choice(healthy_people)
        person.posess()
        person.is_controlled = True
        Person.controlled_person = person
  1. 在模拟循环中加入状态检查,触发自动切换:
def simulation():
    amount=int(input("Enter amount of people within the area: " ))
    moves=int(input("Enter the amount of moves these people will do: "))
    print("Entered amount of people: ", amount)
    print("Entered amount of movements: ", moves)
    make_population(amount)
    infect_random()
    posess_random()
    screen.update()
    for _ in range(moves):
        # 检查当前被控制者是否感染,是则切换新个体
        if Person.controlled_person and Person.controlled_person.infected():
            posess_random()
        
        # 遍历所有人执行移动和感染检测(修复原代码的语法错误)
        for person in Person.population:
            # 只有未被控制的人才随机移动
            if not person.is_controlled:
                person.random_move()
            # 健康个体的感染检测
            if not person.infected():
                for infected in Person.all_infected():
                    if person.distance(infected) < 30:
                        person.infect()
        screen.update()
        sleep(0.1)

完整修改后的代码

把所有修改整合后,就是可以正常运行的版本:

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

class Person(Turtle):
    population = []
    controlled_person = None  # 全局跟踪被控制的海龟

    def __init__(self):
        super().__init__(shape='circle')
        self.shapesize(0.4)
        self.penup()
        self.setpos(randint(-250, 250), randint(-250, 250))
        self.is_controlled = False
        self.color('black')  # 健康状态为黑色
        Person.population.append(self)

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

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

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

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

    def posess(self):
        self.color('yellow')

    def possessed(self):
        return self.pencolor() == 'yellow'

    def random_move(self):
        self.right(randint(-180,180))
        self.forward(randint(0,10))
        if not (-250 < self.xcor() <250 and -250 < self.ycor() < 250):
            self.undo()

def make_population(amount):
    for _ in range(amount):
        Person()

def posess_random():
    healthy_people = [p for p in Person.population if not p.infected() and not p.is_controlled]
    if healthy_people:
        # 重置之前的被控制者
        if Person.controlled_person:
            Person.controlled_person.color('black')
            Person.controlled_person.is_controlled = False
        # 选择新的被控制者
        person = choice(healthy_people)
        person.posess()
        person.is_controlled = True
        Person.controlled_person = person

def infect_random():
    person = choice(Person.population)
    person.infect()

# 方向键控制函数
def move_up():
    if Person.controlled_person and not Person.controlled_person.infected():
        Person.controlled_person.setheading(90)
        Person.controlled_person.forward(10)
        if not (-250 < Person.controlled_person.xcor() < 250 and -250 < Person.controlled_person.ycor() < 250):
            Person.controlled_person.undo()

def move_down():
    if Person.controlled_person and not Person.controlled_person.infected():
        Person.controlled_person.setheading(270)
        Person.controlled_person.forward(10)
        if not (-250 < Person.controlled_person.xcor() < 250 and -250 < Person.controlled_person.ycor() < 250):
            Person.controlled_person.undo()

def move_left():
    if Person.controlled_person and not Person.controlled_person.infected():
        Person.controlled_person.setheading(180)
        Person.controlled_person.forward(10)
        if not (-250 < Person.controlled_person.xcor() < 250 and -250 < Person.controlled_person.ycor() < 250):
            Person.controlled_person.undo()

def move_right():
    if Person.controlled_person and not Person.controlled_person.infected():
        Person.controlled_person.setheading(0)
        Person.controlled_person.forward(10)
        if not (-250 < Person.controlled_person.xcor() < 250 and -250 < Person.controlled_person.ycor() < 250):
            Person.controlled_person.undo()

def simulation():
    amount=int(input("Enter amount of people within the area: " ))
    moves=int(input("Enter the amount of moves these people will do: "))
    print("Entered amount of people: ", amount)
    print("Entered amount of movements: ", moves)
    make_population(amount)
    infect_random()
    posess_random()
    screen.update()
    for _ in range(moves):
        # 检查被控制者是否感染,切换新个体
        if Person.controlled_person and Person.controlled_person.infected():
            posess_random()
        
        for person in Person.population:
            if not person.is_controlled:
                person.random_move()
            if not person.infected():
                for infected in Person.all_infected():
                    if person.distance(infected) < 30:
                        person.infect()
        screen.update()
        sleep(0.1)

screen = Screen()
screen.setup(500,500)
screen.tracer(0)
screen.bgcolor(str(input("Enter desired background color: ")))
# 绑定方向键
screen.onkeypress(move_up, "Up")
screen.onkeypress(move_down, "Down")
screen.onkeypress(move_left, "Left")
screen.onkeypress(move_right, "Right")
screen.listen()

simulation()
screen.exitonclick()

额外优化说明

  • 用类属性controlled_person直接跟踪控制目标,比单独全局变量更整洁
  • 被控制海龟不再随机移动,完全由方向键操控,符合需求
  • 给方向键控制加入边界检测,防止海龟跑出屏幕
  • 修复了原代码中for person.infected in Person.population:的语法错误
  • 修复了posess_random函数中posessed+1的无效代码问题

内容的提问来源于stack exchange,提问作者WhitèBlue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 19:27:53