elevate_lib/
floors.rs

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