Python 电梯模拟器

3

我需要帮助编写一个Python电梯模拟器,但我没有太多经验。用户应该输入一定数量的顾客,他们在随机的楼层出发和到达目的地。目前我只编写了简单的策略:电梯先去顶层,然后再回到底层。当我运行我的代码时,程序会无限循环。我不知道原因是什么。此外,我也不确定如何编写建筑物输出方法,我想显示哪些顾客在哪些楼层上下电梯,以及电梯访问了多少个楼层。感谢您的帮助。

import random

class Elevator(object):
    def __init__(self, num_of_floors, register_list, direction = "up", cur_floor=1):
        self.total_floors = num_of_floors
        self.reg_list = register_list
        self.floor = cur_floor
        self.direct = direction
    def move(self):
        """Moves the elevator one floor"""
        if self.total_floors == self.floor:
            self.direct = "down"
        if self.direct == "up":
            self.floor += 1
        else:
            self.floor -= 1
    def register_customer(self, customer):
        self.reg_list.append(customer)
    def cancel_customer(self, customer):
        self.reg_list.remove(customer)

class Building(object):
    def __init__(self, num_of_floors, customer_list, elevator):
        self.total_floors = num_of_floors
        self.customers = customer_list
    def run(self):
        while elevator.floor != 0:
            for customer in self.customers:
                if elevator.floor == customer.on_floor:
                    elevator.reg_list.append(customer)
                    customer.indicator = 1
                elif elevator.floor == customer.going_floor:
                    elevator.reg_list.remove(customer)
                    customer.indicator = 0
                    customer.fin = 1
            elevator.move()
                
    def output(self):
        pass

class Customer(object):
    def __init__(self, ID, num_of_floors, cur_floor=0, dst_floor=0, in_elevator=0, finished=0):
        self.ident = ID
        self.indicator = in_elevator
        self.fin = finished
        cur_floor = random.randint(1, num_of_floors)
        self.on_floor = cur_floor
        dst_floor = random.randint(1, num_of_floors)
        while dst_floor == cur_floor:
            dst_floor = random.randint(1, num_of_floors)
        self.going_floor = dst_floor
    

customer_count = int(input("How many customers are in the building?: "))
floor_count = int(input("How many floors does the building have?: "))
cus_list = []
for i in range(1, customer_count+1):
    cus_list.append(Customer(i, floor_count))
elevator = Elevator(floor_count, cus_list)
building = Building(floor_count, cus_list, elevator)

2
不想坐那个电梯 :P 检查一下你的 while 循环在建造方面看起来有点奇怪... 尝试在循环中将 elevator.floor 变量输出到控制台。 - beiller
那个 while 循环看起来很好 - 它在说顾客要去除了他/她所在的楼层之外的其他楼层。 - Rob Watts
抱歉,我编辑了那个。 - beiller
只要 num_of_floors 足够大 ;) - BartoszKP
1个回答

3
你的问题出在这里:
def run(self):
    while elevator.floor != 0:
        print(elevator.floor)
        for customer in self.customers:
            print(customer)
            if elevator.floor == customer.on_floor:
                elevator.reg_list.append(customer)
                customer.indicator = 1
            elif elevator.floor == customer.going_floor:
                elevator.reg_list.remove(customer)
                customer.indicator = 0
                customer.fin = 1
        elevator.move()

当您使用elevator.reg_list.append(customer)时,您正在重新将客户添加到列表中,增加它的大小(self.customers也是对同一列表的引用),因此“for customer in self.customers”循环永远执行。

让我们跟随“cus_list”:

elevator = Elevator(floor_count, cus_list)
building = Building(floor_count, cus_list, elevator)

class Building(object):
    def __init__(self, num_of_floors, customer_list, elevator):
        self.total_floors = num_of_floors
        self.customers = customer_list

class Elevator(object):
    def __init__(self, num_of_floors, register_list, direction = "up", cur_floor=1):
        self.total_floors = num_of_floors
        self.reg_list = register_list # <-------- THIS IS "cus_list" reference

最后在Building类中:

 elevator.reg_list.append(customer)

电梯在此处是一个全局变量,FYI是在类的作用域之外创建的。
修复方法可能如下:
电梯一开始是空的,对吧?
class Elevator(object):
    def __init__(self, num_of_floors, register_list, direction = "up", cur_floor=1):
        self.total_floors = num_of_floors
        self.reg_list = []

不,它们是对同一列表的两个不同引用。OP可能应该在电梯中使用self.reg_list = [],这样电梯就不会一开始就满载了。 - Rob Watts
是的,这是我在之前回答中提到的同一个列表的引用。抱歉它有点长 :S - beiller
我该如何实际显示电梯的操作呢?例如,显示“电梯在一楼接客人1...电梯移动到二楼并接客人3...电梯移动到三楼,卸下客人1并接客人4...等等”。 - pmal
使用print语句。例如:print("电梯在 " + elevator.floor + " 层接到 " + customer + " 。") 这是Python 3的语法,Python 2可以省略括号。 - beiller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接