use rand::Rng;
use crate::person::Person;
use crate::people::People;
#[derive(Clone)]
pub struct Elevator {
pub floor_on: usize,
pub moving_up: bool,
pub stopped: bool,
pub people: Vec<Person>,
pub capacity: usize,
pub energy_up: f64,
pub energy_down: f64,
pub energy_coef: f64
}
impl Elevator {
pub fn from(capacity: usize, energy_up: f64, energy_down: f64, energy_coef: f64) -> Elevator {
Elevator {
floor_on: 0_usize,
moving_up: false,
stopped: true,
people: Vec::new(),
capacity: capacity,
energy_up: energy_up,
energy_down: energy_down,
energy_coef: energy_coef
}
}
pub fn get_energy_spent(&mut self) -> f64 {
let energy_spent = if self.stopped {
0.0_f64
} else if self.moving_up {
self.energy_up + (self.energy_coef * (self.people.len() as f64))
} else {
self.energy_down + (self.energy_coef * (self.people.len() as f64))
};
energy_spent
}
pub fn get_free_capacity(&self) -> usize {
self.capacity - self.people.get_num_people()
}
pub fn update_direction(&mut self, floor_to: usize) {
if floor_to > self.floor_on {
self.stopped = false;
self.moving_up = true;
} else if floor_to < self.floor_on {
self.stopped = false;
self.moving_up = false;
} else {
self.stopped = true;
}
}
pub fn update_floor(&mut self) -> usize {
if self.stopped {
return self.floor_on;
}
self.floor_on = if self.moving_up {
self.floor_on + 1_usize
} else {
self.floor_on - 1_usize
};
for pers in self.people.iter_mut() {
pers.floor_on = self.floor_on;
}
self.floor_on
}
pub fn get_nearest_dest_floor(&self) -> (usize, usize) {
let floor_index: usize = self.floor_on;
let dest_floors: Vec<usize> = self.get_dest_floors();
if dest_floors.len() == 0_usize {
return (0_usize, 0_usize);
}
let mut nearest_dest_floor: usize = 0_usize;
let mut min_dest_floor_dist: usize = 0_usize;
for dest_floor_index in dest_floors.iter() {
let dest_floor_dist: usize = if floor_index > *dest_floor_index {
floor_index - dest_floor_index
} else {
dest_floor_index - floor_index
};
if min_dest_floor_dist == 0_usize || dest_floor_dist < min_dest_floor_dist {
min_dest_floor_dist = dest_floor_dist;
nearest_dest_floor = *dest_floor_index;
}
}
(nearest_dest_floor, min_dest_floor_dist)
}
pub fn flush_people_leaving_elevator(&mut self, free_floor_capacity: usize) -> Vec<Person> {
let mut people_leaving: Vec<Person> = Vec::new();
if !self.stopped {
return people_leaving;
}
let mut removals = 0_usize;
for i in 0..self.people.len() {
if people_leaving.len() == free_floor_capacity {
break;
}
if self.people[i-removals].floor_on != self.people[i-removals].floor_to {
continue;
}
let person_leaving: Person = self.people.remove(i - removals);
people_leaving.push(person_leaving);
removals += 1_usize;
}
people_leaving
}
}
impl Extend<Person> for Elevator {
fn extend<T: IntoIterator<Item=Person>>(&mut self, iter: T) {
for pers in iter {
if self.people.get_num_people() == self.capacity {
break;
}
self.people.push(pers);
}
}
}
impl People for Elevator {
fn gen_num_tips(&self, rng: &mut impl Rng) -> usize {
self.people.gen_num_tips(rng)
}
fn get_dest_floors(&self) -> Vec<usize> {
self.people.get_dest_floors()
}
fn get_num_people(&self) -> usize {
self.people.get_num_people()
}
fn get_num_people_waiting(&self) -> usize {
self.people.get_num_people_waiting()
}
fn get_num_people_going_to_floor(&self, floor_to: usize) -> usize {
self.people.get_num_people_going_to_floor(floor_to)
}
fn get_aggregate_wait_time(&self) -> usize {
self.people.get_aggregate_wait_time()
}
fn are_people_waiting(&self) -> bool {
self.people.are_people_waiting()
}
fn are_people_going_to_floor(&self, floor_index: usize) -> bool {
self.people.are_people_going_to_floor(floor_index)
}
fn increment_wait_times(&mut self) {
self.people.increment_wait_times()
}
fn reset_wait_times(&mut self) {
self.people.reset_wait_times()
}
}