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;
}
}
}
}