1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
//Import source modules
use crate::floor::Floor;
use crate::person::Person;
use crate::people::People;
//Import external/standard modules
use rand::Rng;
/// # `Floors` trait
///
/// A `Floors` implementation is representative of a collection of `Floor`s. It is
/// implemented by the `Building` struct.
pub trait Floors {
/// Expected to determine whether there are any people waiting on a given floor.
/// Returns a bool which is true if so, and false if not.
fn are_people_waiting_on_floor(&self, floor_index: usize) -> bool;
/// Expected to determine the nearest floor at which people are waiting with
/// respect to the given floor. Returns a tuple of usizes representing the floor
/// index and the distance to the floor.
fn get_nearest_wait_floor(&self, floor_on: usize) -> (usize, usize);
/// Expected to get the probability that each floor becomes a destination floor in
/// the next time step.
fn get_dest_probabilities(&self) -> Vec<f64>;
/// Expected to randomly generate the people leaving each floor using each `Floor`'s
/// `gen_people_leaving` function, which itself uses each `Person`'s `gen_is_leaving`
/// function.
fn gen_people_leaving(&mut self, rng: &mut impl Rng);
/// Expected to remove anyone who is leaving the first floor.
fn flush_first_floor(&mut self) -> Vec<Person>;
/// Expected to increment the waiting times among people who are waiting/not at their
/// destination floor throughout the collection of floors.
fn increment_wait_times(&mut self);
/// Expected to append a new floor to the collection of floors.
fn append_floor(&mut self, capacity: usize);
/// Expected to update the capacities across each of the floors.
fn update_capacities(&mut self, capacity: usize);
}
//Implement people trait for Vec<Floor>
impl Floors for Vec<Floor> {
/// Determines whether there are any people waiting on a given floor. Returns a bool
/// which is true if so, and false if not.
fn are_people_waiting_on_floor(&self, floor_index: usize) -> bool {
self[floor_index].are_people_waiting()
}
/// Determines the nearest floor at which people are waiting with respect to the given
/// floor. Returns a tuple of usizes representing the floor index and the distance to
/// the floor.
fn get_nearest_wait_floor(&self, floor_on: usize) -> (usize, usize) {
//Initialize variables to track the nearest waiting floor and
//the min distance between here and that floor
let mut nearest_wait_floor: usize = 0_usize;
let mut min_wait_floor_dist: usize = 0_usize;
//Loop through the floors and find the minimum distance floor
//with waiting people
for (i, floor) in self.iter().enumerate() {
//Check if there is anyone waiting on the floor, if not
//then continue
if !floor.are_people_waiting() {
continue;
}
//Calculate the distance between this floor and the waiting
//floor
let wait_floor_dist: usize = if floor_on > i {
floor_on - i
} else {
i - floor_on
};
//Check whether this is less than the current minimum, or
//if no minimum has been assigned yet (in which case it is
//0_usize)
if min_wait_floor_dist == 0_usize || wait_floor_dist < min_wait_floor_dist {
min_wait_floor_dist = wait_floor_dist;
nearest_wait_floor = i;
}
}
//Return the nearest waiting floor
(nearest_wait_floor, min_wait_floor_dist)
}
/// Gets the probability that each floor becomes a destination floor in the next
/// time step.
fn get_dest_probabilities(&self) -> Vec<f64> {
//Initialize a new vec of f64s
let mut dest_probabilities: Vec<f64> = Vec::new();
//Loop through the floors
for floor in self.iter() {
//Push the floor's dest_prob value into the vector
dest_probabilities.push(floor.dest_prob);
}
//Return the vector
dest_probabilities
}
/// Randomly generates the people leaving each floor using each `Floor`'s
/// `gen_people_leaving` function, which itself uses each `Person`'s `gen_is_leaving`
/// function.
fn gen_people_leaving(&mut self, mut rng: &mut impl Rng) {
//Loop through the floors of the building
for floor in self.iter_mut() {
//Generate the people leaving on that floor
floor.gen_people_leaving(&mut rng);
}
}
/// Removes anyone who is leaving the first floor and returns the people who left as
/// a vec of people.
fn flush_first_floor(&mut self) -> Vec<Person> {
self[0].flush_people_leaving_floor()
}
/// Increments the waiting times among people who are waiting/not at their destination
/// floor throughout the collection of floors.
fn increment_wait_times(&mut self) {
for floor in self.iter_mut() {
floor.increment_wait_times();
}
}
/// Appends a new floor to the collection of floors.
fn append_floor(&mut self, capacity: usize) {
self.push(Floor::new(capacity));
}
/// Updates the capacity across each of the floors
fn update_capacities(&mut self, capacity: usize) {
//Ensure that the capacity is not less than the current
//numer of people on any given floor
let can_update_capacities: bool = {
let mut tmp_can_update_capacities: bool = true;
for floor in self.iter() {
if capacity < floor.get_num_people() {
tmp_can_update_capacities = false;
break;
}
}
tmp_can_update_capacities
};
//If the capacity can be updated across all floors, then
//update the capacities
if can_update_capacities {
for floor in self.iter_mut() {
floor.capacity = capacity;
}
}
}
}