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}