1use rand::Rng;
2use rand_xorshift::XorShiftRng;
3
4use geom::{Duration, Time};
5
6use crate::{Activity, CensusPerson, Config, PersonType, Schedule};
7
8impl CensusPerson {
9 pub fn generate_schedule(&self, _config: &Config, rng: &mut XorShiftRng) -> Schedule {
10 let person_type = if rng.gen_bool(0.5) {
12 PersonType::Student
13 } else {
14 PersonType::Worker
15 };
16
17 let mut plan = Vec::new();
20 let start_time;
21
22 match person_type {
23 PersonType::Student => {
24 start_time = rand_time(rng, hours(8), hours(11));
26 if rng.gen_bool(0.95) {
27 plan.push((Activity::Breakfast, minutes(30)));
28 }
29 plan.push((Activity::School, rand_duration(rng, hours(3), hours(6))));
30 if rng.gen_bool(0.3) {
31 plan.push((
32 Activity::Lunch,
33 rand_duration(rng, minutes(20), minutes(40)),
34 ));
35 }
36 plan.push((Activity::School, rand_duration(rng, hours(2), hours(4))));
37 if rng.gen_bool(0.6) {
38 plan.push((Activity::Entertainment, hours(2)));
39 } else {
40 plan.push((Activity::Errands, rand_duration(rng, minutes(15), hours(1))));
41 }
42 plan.push((Activity::Home, hours(8)));
44 }
45 PersonType::Worker => {
46 start_time = rand_time(rng, hours(6), hours(9));
47 if rng.gen_bool(0.8) {
48 plan.push((Activity::Breakfast, minutes(15)));
49 }
50 plan.push((Activity::Work, rand_duration(rng, hours(4), hours(5))));
51 plan.push((
52 Activity::Lunch,
53 rand_duration(rng, minutes(20), minutes(40)),
54 ));
55 plan.push((Activity::Work, hours(4)));
56 if rng.gen_bool(0.8) {
57 plan.push((Activity::Errands, rand_duration(rng, minutes(15), hours(1))));
58 }
59 plan.push((Activity::Home, hours(8)));
61 }
62 }
63
64 let mut schedule = Vec::new();
65 let mut now = start_time;
66 for (activity, duration) in plan {
67 schedule.push((now, activity));
68 now += rand_duration(rng, Duration::minutes(30), Duration::hours(1));
71 now += duration;
72 }
73 Schedule {
74 activities: schedule,
75 }
76 }
77}
78
79fn rand_duration(rng: &mut XorShiftRng, low: Duration, high: Duration) -> Duration {
80 assert!(high > low);
81 Duration::seconds(rng.gen_range(low.inner_seconds()..high.inner_seconds()))
82}
83
84fn rand_time(rng: &mut XorShiftRng, low: Duration, high: Duration) -> Time {
85 Time::START_OF_DAY + rand_duration(rng, low, high)
86}
87
88fn minutes(x: usize) -> Duration {
90 Duration::minutes(x)
91}
92fn hours(x: usize) -> Duration {
93 Duration::hours(x)
94}