elevate_lib/
people.rs

1//Import standard/imported modules
2use rand::Rng;
3
4//Import source modules
5use crate::person::Person;
6
7/// # `People` trait
8///
9/// A `People` implementation is representative of a collection of `Person`s.  It is
10/// implemented by the `Elevator` and `Floor` structs.  It defines a set of functions
11/// for managing `Person`s in aggregate.
12pub trait People {
13    /// Expected to generate the number of tips to collect from the people
14    fn gen_num_tips(&self, rng: &mut impl Rng) -> usize;
15
16    /// Expected to determine the destination floors for all people and return it as
17    /// a vector.
18    fn get_dest_floors(&self) -> Vec<usize>;
19
20    /// Expected to determine the total number of people and return it as a usize.
21    fn get_num_people(&self) -> usize;
22
23    /// Expected to determine the number of people waiting, that is, not at their
24    /// desired floor.
25    fn get_num_people_waiting(&self) -> usize;
26
27    /// Expected to read the wait times from people waiting/not at their desired floor
28    /// and aggregate the total into a usize.
29    fn get_aggregate_wait_time(&self) -> usize;
30
31    /// Expected to determine whether anyone in the collection of people are going to
32    /// a given floor, returning a bool which is true if so, and false if not.
33    fn are_people_going_to_floor(&self, floor_index: usize) -> bool;
34
35    /// Expected to determine whether anyone in the collection of people is waiting/not
36    /// at their desired floor, returning a bool which is true if so, and false if not.
37    fn are_people_waiting(&self) -> bool;
38
39    /// Expected to increment the wait times (by `1_usize`) among all people waiting/not
40    /// at their desired floor.
41    fn increment_wait_times(&mut self);
42
43    /// Expected to reset the wait times (to `0_usize`) among all people who have a
44    /// nonzero wait time and are on their desired floor.
45    fn reset_wait_times(&mut self);
46}
47
48impl People for Vec<Person> {
49    /// Generates the number of people among the collection of people who will tip.
50    fn gen_num_tips(&self, rng: &mut impl Rng) -> usize {
51        //Initialize a counter for the number of people who will tip
52        let mut num_tips: usize = 0_usize;
53
54        //Loop through the people and generate whether each person will tip
55        for pers in self.iter() {
56            if pers.gen_tip(rng) {
57                num_tips += 1_usize;
58            }
59        }
60
61        //Return the counter
62        num_tips
63    }
64
65    /// Determines the destination floors for all people and returns it as a vector.
66    fn get_dest_floors(&self) -> Vec<usize> {
67        //Initialize a new vector of usizes
68        let mut dest_floors: Vec<usize> = Vec::new();
69
70        //Loop through the vector of persons
71        for pers in self.iter() {
72            //Add the dest floor to the vector
73            let dest_floor = pers.floor_to;
74            dest_floors.push(dest_floor);
75        }
76
77        //Return the destination floors vector
78        dest_floors
79    }
80
81    /// Determines the total number of people and returns it as a usize.
82     fn get_num_people(&self) -> usize {
83        //Return the length of the vector
84        self.len()
85    }
86
87    /// Determines the number of people waiting, that is, not at their desired floor.
88    fn get_num_people_waiting(&self) -> usize {
89        //Initialize a usize counting the numper of people waiting
90        let mut num_waiting: usize = 0_usize;
91
92        //Loop through the vector of persons
93        for pers in self.iter() {
94            //Skip if the person is not waiting
95            if pers.floor_on == pers.floor_to {
96                continue;
97            }
98
99            //If the person is waiting, increment the counter
100            num_waiting += 1_usize;
101        }
102
103        //Return the counter
104        num_waiting
105    }
106
107    /// Reads the wait times from people waiting/not at their desired floor and aggregates
108    /// the total into a usize.
109    fn get_aggregate_wait_time(&self) -> usize {
110        //Initialize a usize for the number of time steps the people spent waiting
111        let mut aggregate_wait_time: usize = 0_usize;
112
113        //Loop through the vector of persons
114        for pers in self.iter() {
115            //Increment the usize with their wait time
116            aggregate_wait_time += pers.wait_time;
117        }
118
119        //Return the usize
120        aggregate_wait_time
121    }
122
123    /// Determines whether anyone in the collection of people are going to a given floor,
124    /// and returns a bool which is true if so, and false if not.
125    fn are_people_going_to_floor(&self, floor_index: usize) -> bool {
126        //Initialize a boolean tracking if people are going to the given floor
127        let mut is_going_to_floor: bool = false;
128
129        //Loop through the people on the elevator and check
130        for pers in self.iter() {
131            //If the person is not going to the given floor then skip
132            if pers.floor_to != floor_index {
133                continue;
134            }
135
136            //Otherwise update the boolean and break
137            is_going_to_floor = true;
138            break;
139        }
140
141        //Return the is_going_to_floor boolean
142        is_going_to_floor
143    }
144
145    /// Determines whether anyone in the collection of people is waiting/not at their
146    /// desired floor, and returns a bool which is true if so, and false if not.
147    fn are_people_waiting(&self) -> bool {
148        //Initialize a boolean tracking if people are waiting
149        let mut is_waiting: bool = false;
150
151        //Loop through the people and check if they are waiting
152        for pers in self.iter() {
153            //If the person is not waiting, then skip
154            if pers.floor_on == pers.floor_to {
155                continue;
156            }
157
158            //Otherwise update the boolean and break
159            is_waiting = true;
160            break;
161        }
162
163        //Return the is_going_to_floor boolean
164        is_waiting
165    }
166
167    /// Increments the wait times (by `1_usize`) among all people waiting/not at
168    /// their desired floor.
169    fn increment_wait_times(&mut self) {
170        //Loop through the people and increment their wait times
171        for pers in self.iter_mut() {
172            pers.increment_wait_time();
173        }
174    }
175
176    /// Resets the wait times (to `0_usize`) among all people who have a nonzero
177    /// wait time and are on their desired floor.
178    fn reset_wait_times(&mut self) {
179        //Loop through the people and reset their wait times
180        for pers in self.iter_mut() {
181            pers.reset_wait_time();
182        }
183    }
184}