目录
前言
代码
总结
?前言
这次的test采取了与V2.5中test不一样的思路。小人也使用“键盘输入",而不是更改楼层状态。这样逻辑更清晰,同时代码也更少。
代码
1.创造小人和小人出现还是完全一样。
# test
self.people = [] # 小人任务列表, 每个元素第0个为上电梯的楼层,第1个为要去的楼层,第2个为小人按的上下建,第3个为出现的时间,第4个为小人的状态(0为未出现,1为等电梯,2为坐电梯中,3为出电梯)
self.people_count = 10 # 小人数量
self.total_floor = 16
self.test_finish = True
def init_people(self):
for i in range(0, self.people_count):
people_in = random.randint(1, self.total_floor)
people_out = random.randint(1, self.total_floor)
if people_in > people_out:
up_down = 2
else:
up_down = 1
t = random.randint(250, 350)
self.people.append([people_in, people_out, up_down, t, 0])
# 小人出现
def people_start(self):
for i in range(0, self.people_count):
if self.people[i][3] == self.t:
self.people[i][4] = 1
2.小人一出现就按电梯,这次将小人输入的方法为“键盘输入”,将小人的楼层传到键盘输入的列表key_floor。注意这里必须立马input函数(input函数跟之前一模一样哈,忘了可以翻翻),将输入转成任务,清空列表。因为小人不少,很容易有小人同时间按电梯。这个方法虽然比直接转换为任务的方法多转了一道,但其实代码量少,逻辑也更清晰,不容易出bug。
# 输入小人进入电梯的楼层
def people_wait(self):
for i in range(0, self.people_count):
if self.people[i][3] == self.t:
print(i, "号小人从", self.people[i][0], "楼按了电梯")
if self.people[i][2] == 2:
self.way = 2
self.arrive = 1
else:
self.way = 1
self.arrive = 1
if self.people[i][0] >= 10:
self.key_floor.append(1)
self.key_floor.append(self.people[i][0] % 10)
self.input_finish = True
else:
self.key_floor.append(self.people[i][0])
self.input_finish = True
self.input()
3.在电梯里按电梯也还是键盘输入。因为要区分是下客还是上客,所以需多加一个判断,就是get_people,give_people这两个变量了,字面意思就是上人和出人。还有加了一个电梯位置的判断,小人的信息中是楼层,不是楼层的位置y,所以将电梯的位置y对接到楼层。
# 小人在电梯里按楼层
def people_sit(self):
floor = 0
for i in range(1, self.elevator_total + 1):
# 确定哪一部电梯
if self.elevator[i].get_people == 1:
# 确定电梯在几楼
for j in range(1, 17):
if self.elevator[i].y == self.elevator[i].floors[j]:
floor = j
for k in range(0, self.people_count):
if self.people[k][4] == 1 and self.people[k][0] == floor: # 状态 位置
if self.people[k][1] >= 10:
self.key_floor.append(1)
self.key_floor.append(self.people[k][1] % 10)
self.input_finish = True
self.which_elevator = i
else:
self.key_floor.append(self.people[k][1])
self.input_finish = True
self.which_elevator = i
print(k, "号小人进入了", i, "号电梯并按了", self.people[k][1], "楼")
self.people[k][4] = 2
self.input()
在电梯类的arrive函数也就是到达函数中加了两个判断,到底是上人还是下人。
# 电梯到达
def arrive(self):
for i in range(1, 17):
# test
if self.y == self.floors[i] and self.running[i] != 1 and self.running[i] != 0:
self.give_people = 1
# test
if self.y == self.floors[i] and self.running[i] != 2 and self.running[i] != 0:
self.get_people = 1
# 电梯到达下客
if self.y == self.floors[i] and self.running[i] == 2:
self.running[i] = 0
self.time = 0
# 电梯到达上客
# 上升到达
if self.y == self.floors[i] and self.running[i] != 0 and self.running[i] != 2 and self.direction[
i] == 1 and self.inertia == 0:
self.running[i] = 0
self.direction[i] = 0
self.time = 0
if self.y == self.floors[i] and self.running[i] != 0 and self.running[i] != 2 and self.direction[
i] == 3 and self.inertia == 0:
self.direction[i] = 2
self.time = 0
# 下降到达
if self.y == self.floors[i] and self.running[i] != 0 and self.running[i] != 2 and self.direction[
i] == 2 and self.inertia == 1:
self.running[i] = 0
self.time = 0
self.direction[i] = 0
if self.y == self.floors[i] and self.running[i] != 0 and self.running[i] != 2 and self.direction[
i] == 3 and self.inertia == 1:
self.direction[i] = 1
self.time = 0
离开电梯不变。
# 小人离开电梯
def people_out(self):
floor = 0
for k in range(1, self.elevator_total + 1):
if self.elevator[k].give_people == 1:
for j in range(1, 17):
if self.elevator[k].y == self.elevator[k].floors[j]:
floor = j
for i in range(0, self.people_count):
if self.people[i][4] == 2 and self.people[i][1] == floor:
self.people[i][4] = 3
print(i, "号小人离开电梯")
最后完成任务的也是一模一样,简简单单。
# 所有小人完成任务
def people_finish(self):
people = 0
for i in range(0, self.people_count):
if self.people[i][4] == 3:
people = people + 1
if people == self.people_count:
time_end = time.time()
print("所有小人离开电梯,共耗时", time_end-time_start,"秒")
self.test_finish = False
同样运行函数需要注意顺序。
def run(self, t):
self.t = t
if self.create:
self.create = False
self.number()
self.init_people()
self.keyboard_get()
self.input()
self.people_start()
self.people_wait()
if self.test_finish:
self.people_finish()
for i in range(1, self.elevator_total + 1):
self.elevator[i].run()
self.unite()
self.people_sit()
self.people_out()
附上全部代码
import pygame
from pygame.locals import *
from sys import exit
import random
import time
class all:
def __init__(self):
self.elevator = [0] # 电梯对象
self.elevator_total = 12 # 电梯总数
self.key_floor = [] # 输入的楼层
self.way = 1 # 输入的方向
self.direction = [0] # 楼层的方向键
self.which_elevator = 1 # 选择哪一个电梯输入楼层(数字)
self.arrive = 0 # 输入方向的操作确认
self.input_finish = False # 完成输入确认
self.create = True # 终止创造电梯
self.key_which_elevator = [] # 选择哪一个电梯输入楼层(列表)
# test
self.people = [] # 小人任务列表, 每个元素第0个为上电梯的楼层,第1个为要去的楼层,第2个为小人按的上下建,第3个为出现的时间,第4个为小人的状态(0为未出现,1为等电梯,2为坐电梯中,3为出电梯)
self.people_count = 10 # 小人数量
self.total_floor = 16
self.test_finish = True
def init_people(self):
for i in range(0, self.people_count):
people_in = random.randint(1, self.total_floor)
people_out = random.randint(1, self.total_floor)
if people_in > people_out:
up_down = 2
else:
up_down = 1
t = random.randint(250, 350)
self.people.append([people_in, people_out, up_down, t, 0])
# 小人出现
def people_start(self):
for i in range(0, self.people_count):
if self.people[i][3] == self.t:
self.people[i][4] = 1
# 输入小人进入电梯的楼层
def people_wait(self):
for i in range(0, self.people_count):
if self.people[i][3] == self.t:
print(i, "号小人从", self.people[i][0], "楼按了电梯")
if self.people[i][2] == 2:
self.way = 2
self.arrive = 1
else:
self.way = 1
self.arrive = 1
if self.people[i][0] >= 10:
self.key_floor.append(1)
self.key_floor.append(self.people[i][0] % 10)
self.input_finish = True
else:
self.key_floor.append(self.people[i][0])
self.input_finish = True
self.input()
# 小人在电梯里按楼层
def people_sit(self):
floor = 0
for i in range(1, self.elevator_total + 1):
# 确定哪一部电梯
if self.elevator[i].get_people == 1:
# 确定电梯在几楼
for j in range(1, 17):
if self.elevator[i].y == self.elevator[i].floors[j]:
floor = j
for k in range(0, self.people_count):
if self.people[k][4] == 1 and self.people[k][0] == floor: # 状态 位置
if self.people[k][1] >= 10:
self.key_floor.append(1)
self.key_floor.append(self.people[k][1] % 10)
self.input_finish = True
self.which_elevator = i
else:
self.key_floor.append(self.people[k][1])
self.input_finish = True
self.which_elevator = i
print(k, "号小人进入了", i, "号电梯并按了", self.people[k][1], "楼")
self.people[k][4] = 2
self.input()
# 小人离开电梯
def people_out(self):
floor = 0
for k in range(1, self.elevator_total + 1):
if self.elevator[k].give_people == 1:
for j in range(1, 17):
if self.elevator[k].y == self.elevator[k].floors[j]:
floor = j
for i in range(0, self.people_count):
if self.people[i][4] == 2 and self.people[i][1] == floor:
self.people[i][4] = 3
print(i, "号小人离开电梯")
# 所有小人完成任务
def people_finish(self):
people = 0
for i in range(0, self.people_count):
if self.people[i][4] == 3:
people = people + 1
if people == self.people_count:
time_end = time.time()
print("所有小人离开电梯,共耗时", time_end-time_start,"秒")
self.test_finish = False
def run(self, t):
self.t = t
if self.create:
self.create = False
self.number()
self.init_people()
self.keyboard_get()
self.input()
self.people_start()
self.people_wait()
if self.test_finish:
self.people_finish()
for i in range(1, self.elevator_total + 1):
self.elevator[i].run()
self.unite()
self.people_sit()
self.people_out()
# 创造楼层方向键,电梯对象
def number(self):
elevator_initial_location = 482 // self.elevator_total # 电梯默认位置
for i in range(1, self.elevator_total + 1):
self.elevator.append(elevator(110 * i - 20, elevator_initial_location * i, i))
for i in range(1, 17):
self.direction.append(0)
# 键盘事件
def keyboard_get(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == pygame.KEYDOWN:
if event.key == CONTROLLER_BUTTON_DPAD_LEFT:
self.input_finish = True
# 将输入的电梯编号从列表转换为数字
if len(self.key_which_elevator) == 2:
self.which_elevator = 10 + self.key_which_elevator[1]
if len(self.key_which_elevator) == 1:
self.which_elevator = self.key_which_elevator[0]
while True:
if len(self.key_which_elevator) >= 1:
del self.key_which_elevator[0]
else:
break
if K_0 <= event.key <= K_9:
self.key_floor.append(event.key - 48)
if event.key == K_DOWN:
self.way = 2
self.arrive = 1
if event.key == K_UP:
self.way = 1
self.arrive = 1
if K_KP1 <= event.key <= K_KP9:
self.key_which_elevator.append(event.key - 1073741912)
if event.key == K_KP0:
self.key_which_elevator.append(0)
else:
pass
# 将单个电梯传到总控制,再由总控制传回单个电梯
def unite(self):
for j in range(1, self.elevator_total + 1):
for i in range(1, 17):
if self.elevator[j].direction[i] == 0 and self.direction[i] != 0:
self.direction[i] = 0
for e in range(1, self.elevator_total + 1):
self.elevator[e].direction[i] = 0
if self.elevator[e].running[i] == 3:
self.elevator[e].running[i] = 2
if self.elevator[e].running[i] == 1:
self.elevator[e].running[i] = 0
if self.elevator[j].direction[i] != 0 and self.elevator[j].direction[i] != 3 and self.direction[i] == 3:
self.direction[i] = self.elevator[j].direction[i]
for e in range(1, self.elevator_total + 1):
self.elevator[e].direction[i] = self.elevator[j].direction[i]
# 输入
def input(self):
# 显示输入楼层
if len(self.key_floor) == 1:
floor_font = pygame.font.Font(None, 80)
floor_text = floor_font.render(str(self.key_floor[0]), True, (0, 0, 255))
screen.blit(floor_text, (0, 100))
if len(self.key_floor) == 2:
floor_font = pygame.font.Font(None, 80)
floor_text = floor_font.render(str(self.key_floor[0]), True, (0, 0, 255))
screen.blit(floor_text, (0, 100))
floor_font = pygame.font.Font(None, 80)
floor_text = floor_font.render(str(self.key_floor[1]), True, (0, 0, 255))
screen.blit(floor_text, (30, 100))
# 输入上客楼层
if self.arrive == 1:
if self.input_finish:
self.arrive = 0
self.input_finish = False
if len(self.key_floor) == 1:
for i in range(1, 11):
if self.key_floor[0] == i:
if self.direction[i] == 1:
if self.way == 2:
self.direction[i] = 3
for j in range(1, self.elevator_total + 1):
self.elevator[j].direction[i] = 3
if self.direction[i] == 2:
if self.way == 1:
self.direction[i] = 3
for j in range(1, self.elevator_total + 1):
self.elevator[j].direction[i] = 3
if self.direction[i] == 0:
if self.way == 1:
self.direction[i] = 1
for j in range(1, self.elevator_total + 1):
self.elevator[j].direction[i] = 1
if self.way == 2:
self.direction[i] = 2
for j in range(1, self.elevator_total + 1):
self.elevator[j].direction[i] = 2
for j in range(1, self.elevator_total + 1):
if self.elevator[j].running[i] == 0:
self.elevator[j].running[i] = 1
if self.elevator[j].running[i] == 2:
self.elevator[j].running[i] = 3
if len(self.key_floor) == 2:
for i in range(0, 7):
if self.key_floor[1] == i:
if self.direction[i + 10] == 1:
if self.way == 2:
self.direction[i + 10] = 3
for j in range(1, self.elevator_total + 1):
self.elevator[j].direction[i + 10] = 3
if self.direction[i + 10] == 2:
if self.way == 1:
self.direction[i + 10] = 3
for j in range(1, self.elevator_total + 1):
self.elevator[j].direction[i + 10] = 3
if self.direction[i + 10] == 0:
if self.way == 1:
self.direction[i + 10] = 1
for j in range(1, self.elevator_total + 1):
self.elevator[j].direction[i + 10] = 1
if self.way == 2:
self.direction[i + 10] = 2
for j in range(1, self.elevator_total + 1):
self.elevator[j].direction[i + 10] = 2
for j in range(1, self.elevator_total + 1):
if self.elevator[j].running[i + 10] == 0:
self.elevator[j].running[i + 10] = 1
if self.elevator[j].running[i + 10] == 2:
self.elevator[j].running[i + 10] = 3
# 清空输入的楼层
while True:
if len(self.key_floor) >= 1:
del self.key_floor[0]
else:
break
# 输入下客楼层
if self.arrive == 0:
if self.input_finish:
self.input_finish = False
if len(self.key_floor) == 1:
for ii in range(1, 11):
if self.key_floor[0] == ii:
if self.elevator[self.which_elevator].running[ii] == 1:
self.elevator[self.which_elevator].running[ii] = 3
if self.elevator[self.which_elevator].running[ii] == 0:
self.elevator[self.which_elevator].running[ii] = 2
if len(self.key_floor) == 2:
for ii in range(0, 7):
if self.key_floor[1] == ii:
if self.elevator[self.which_elevator].running[ii + 10] == 1:
self.elevator[self.which_elevator].running[ii + 10] = 3
if self.elevator[self.which_elevator].running[ii + 10] == 0:
self.elevator[self.which_elevator].running[ii + 10] = 2
# 清空输入的楼层
while True:
if len(self.key_floor) >= 1:
del self.key_floor[0]
else:
break
class elevator:
def __init__(self, x, elevator_initial_location, elevator_number):
self.x = x # 电梯x坐标
self.y = 482 # 电梯初始y坐标
self.speed = 2 # 电梯速度
self.floors = [0] # 楼层位置
self.running = [0] # 楼层状态
self.inertia = 0 # 电梯状态(惯性)
self.move_up = False # 是否上升
self.time = 100 # 暂停时间
self.direction = [0] # 按电梯的方向键
self.elevator_initial_location = elevator_initial_location # 电梯默认位置,使电梯均匀分布
self.elevator_number = elevator_number # 电梯编号
self.get_people = 0
self.give_people = 0
for j in range(1, 17): # 楼层变色 1为上客状态,二为下客状态,3为上下
self.running.append(0)
self.direction.append(0)
i = 482
floor_running = True
while floor_running:
self.floors.append(i)
i = i - 32
if i == -30:
floor_running = False
def run(self):
self.stop()
self.get_people = 0
self.give_people = 0
self.move()
self.arrive()
self.draw()
# 电梯移动
def move(self):
self.move_up = False
# 电梯回归初始位置
initial = 0
for i in range(1, 17):
if self.running[i] == 1:
initial = 1
elif self.running[i] == 2:
initial = 1
elif self.running[i] == 3:
initial = 1
else:
pass
if self.y <= self.elevator_initial_location and initial == 0:
self.y = self.y + self.speed
if self.y > self.elevator_initial_location and initial == 0:
self.y = self.y - self.speed
self.move_up = True
# 电梯状态检测
priority = 0
if self.inertia == 1:
for i in range(1, 17):
if self.running[i] == 1 and self.y <= self.floors[i]:
self.inertia = 1
break
elif self.running[i] == 2 and self.y <= self.floors[i]:
self.inertia = 1
break
elif self.running[i] == 3 and self.y <= self.floors[i]:
self.inertia = 1
break
else:
self.inertia = 0
if self.inertia == 0:
for i in range(1, 17):
if self.running[i] == 1 and self.y >= self.floors[i]:
self.inertia = 0
break
elif self.running[i] == 2 and self.y >= self.floors[i]:
self.inertia = 0
break
elif self.running[i] == 3 and self.y >= self.floors[i]:
self.inertia = 0
break
else:
self.inertia = 1
# 电梯移动
for i in range(1, 17):
if self.running[i] == 1 and self.y >= self.floors[i] and self.inertia == 0:
self.y = self.y - self.speed
self.move_up = True
priority = 1
break
if self.running[i] == 3 and self.y >= self.floors[i] and self.inertia == 0:
self.y = self.y - self.speed
self.move_up = True
priority = 1
break
if self.running[i] == 1 and self.y <= self.floors[i] and self.inertia == 1:
self.y = self.y + self.speed
priority = 1
break
if self.running[i] == 3 and self.y <= self.floors[i] and self.inertia == 1:
self.y = self.y + self.speed
priority = 1
break
if priority == 0:
for i in range(1, 17):
if self.running[i] == 2 and self.y >= self.floors[i] and self.inertia == 0:
self.y = self.y - self.speed
self.move_up = True
break
if self.running[i] == 2 and self.y <= self.floors[i] and self.inertia == 1:
self.y = self.y + self.speed
break
# 电梯到达
def arrive(self):
for i in range(1, 17):
# test
if self.y == self.floors[i] and self.running[i] != 1 and self.running[i] != 0:
self.give_people = 1
# test
if self.y == self.floors[i] and self.running[i] != 2 and self.running[i] != 0:
self.get_people = 1
# 电梯到达下客
if self.y == self.floors[i] and self.running[i] == 2:
self.running[i] = 0
self.time = 0
# 电梯到达上客
# 上升到达
if self.y == self.floors[i] and self.running[i] != 0 and self.running[i] != 2 and self.direction[
i] == 1 and self.inertia == 0:
self.running[i] = 0
self.direction[i] = 0
self.time = 0
if self.y == self.floors[i] and self.running[i] != 0 and self.running[i] != 2 and self.direction[
i] == 3 and self.inertia == 0:
self.direction[i] = 2
self.time = 0
# 下降到达
if self.y == self.floors[i] and self.running[i] != 0 and self.running[i] != 2 and self.direction[
i] == 2 and self.inertia == 1:
self.running[i] = 0
self.time = 0
self.direction[i] = 0
if self.y == self.floors[i] and self.running[i] != 0 and self.running[i] != 2 and self.direction[
i] == 3 and self.inertia == 1:
self.direction[i] = 1
self.time = 0
# 到达停止
def stop(self):
# 电梯停止
if self.time <= 50: # 电梯停止时间
if self.move_up:
self.y = self.y + self.speed
else:
self.y = self.y - self.speed
self.time = self.time + 1
else:
self.time = 100
self.move_up = False
def draw(self):
# 创造电梯穿梭间
pygame.draw.rect(screen, [250 - self.x / 10, 250 - self.x / 6, self.x / 6], [self.x - 10, 0, 53, 520], 0)
# 创造电梯
screen.blit(pygame.image.load("people.png"), (self.x, self.y))
floor_font = pygame.font.Font(None, 50) # 变得不卡
# 创造电梯编号
floor_text = floor_font.render(str(self.elevator_number), True,
(250 - self.x / 10, 250 - self.x / 6, self.x / 6))
screen.blit(floor_text, (self.x + 5, 525))
# 画楼层
for floor in range(1, 17):
if self.running[floor] == 1:
floor_text = floor_font.render(str(floor), True, (255, 0, 0))
screen.blit(floor_text, (self.x + 50, self.floors[floor]))
elif self.running[floor] == 2:
floor_text = floor_font.render(str(floor), True, (0, 255, 0))
screen.blit(floor_text, (self.x + 50, self.floors[floor]))
elif self.running[floor] == 3:
floor_text = floor_font.render(str(floor), True, (0, 0, 255))
screen.blit(floor_text, (self.x + 50, self.floors[floor]))
else:
floor_text = floor_font.render(str(floor), True, (250 - self.x / 10, 250 - self.x / 6, self.x / 6))
screen.blit(floor_text, (self.x + 50, self.floors[floor]))
# 方向键
if self.direction[floor] == 1:
screen.blit(up, (0, self.floors[floor]))
if self.direction[floor] == 2:
screen.blit(down, (45, self.floors[floor]))
if self.direction[floor] == 3:
screen.blit(up, (0, self.floors[floor]))
screen.blit(down, (45, self.floors[floor]))
# 初始化pygame
pygame.init()
# 设置窗口名称
pygame.display.set_caption("电梯")
# 颜色值(255, 0, 0)表示红色,(0, 255, 0)表示绿色,而(0, 0, 255)表示蓝色
# 图片
up = pygame.image.load("up.png")
down = pygame.image.load("down.png")
# 定义画面帧率
FPS = 40
clock = pygame.time.Clock()
t = 0
# 创造对象
all = all()
# 获取对显示系统的访问,并创建一个窗口,分别率位(600x500)screen:屏幕
screen = pygame.display.set_mode((all.elevator_total * 140, 560))
#
time_start = time.time()
# 主程序
while True:
pygame.display.update() # 刷新显示
clock.tick(FPS) # 最大帧率控制
# 背景颜色
screen.fill([255, 255, 255])
all.run(t)
t = t + 1
总结
好了完成了,就这么简单。这就是面向对象的好处,想加东西直接在原来的基础上加,不用怎么修改原来的代码。这次就只在电梯类的到达函数加了两个判断。而且用函数分的每一块很清楚,写起来也逻辑很清晰,基本不会卡壳。同时每一块写完后都可以测试,知道哪里出的bug,将bug的范围极大缩小。
|