initiative_core/world/
mod.rs1pub mod demographics;
2pub mod npc;
3pub mod place;
4pub mod thing;
5
6pub use command::{ParsedThing, WorldCommand};
7pub use demographics::Demographics;
8pub use field::Field;
9
10mod command;
11mod field;
12mod word;
13
14use rand::Rng;
15
16pub trait Generate: Default {
17 fn generate(rng: &mut impl Rng, demographics: &Demographics) -> Self {
18 let mut result = Self::default();
19 result.regenerate(rng, demographics);
20 result
21 }
22
23 fn regenerate(&mut self, rng: &mut impl Rng, demographics: &Demographics);
24}
25
26fn weighted_index_from_tuple<'a, T>(rng: &mut impl Rng, input: &'a [(T, usize)]) -> &'a T {
27 let total = input.iter().map(|(_, n)| n).sum();
28
29 if total == 0 {
30 panic!("Empty input.");
31 }
32
33 let target = rng.gen_range(0..total);
34 let mut acc = 0;
35
36 for (value, frequency) in input {
37 acc += frequency;
38 if acc > target {
39 return value;
40 }
41 }
42
43 unreachable!();
44}
45
46#[cfg(test)]
47mod test {
48 use super::*;
49 use rand::prelude::*;
50
51 #[test]
52 fn weighted_index_from_tuple_test() {
53 let input = [('a', 1), ('b', 3), ('c', 5)];
54 let mut rng = SmallRng::seed_from_u64(0);
55 assert_eq!(
56 vec!['c', 'c', 'c', 'c', 'c', 'c', 'b', 'c', 'b', 'a'],
57 (0..10)
58 .map(|_| weighted_index_from_tuple(&mut rng, &input[..]))
59 .copied()
60 .collect::<Vec<_>>()
61 );
62 }
63
64 #[test]
65 fn weighted_index_from_tuple_test_one() {
66 let input = [(true, 1)];
67 let mut rng = SmallRng::seed_from_u64(0);
68 assert_eq!(
69 vec![true, true, true],
70 (0..3)
71 .map(|_| weighted_index_from_tuple(&mut rng, &input[..]))
72 .copied()
73 .collect::<Vec<_>>()
74 );
75 }
76
77 #[test]
78 #[should_panic]
79 fn weighted_index_from_tuple_test_empty() {
80 let input: [(bool, usize); 0] = [];
81 weighted_index_from_tuple(&mut SmallRng::seed_from_u64(0), &input[..]);
82 }
83
84 #[test]
85 #[should_panic]
86 fn weighted_index_from_tuple_test_zero() {
87 let input = [(true, 0), (false, 0)];
88 weighted_index_from_tuple(&mut SmallRng::seed_from_u64(0), &input[..]);
89 }
90}