initiative_core/world/npc/species/
elf.rs1use super::{Age, Gender, Generate, Size};
2use rand::prelude::*;
3
4pub struct Species;
5
6impl Generate for Species {
7 fn gen_gender(rng: &mut impl Rng) -> Gender {
8 match rng.gen_range(1..=101) {
9 1..=50 => Gender::Feminine,
10 51..=100 => Gender::Masculine,
11 101 => Gender::NonBinaryThey,
12 _ => unreachable!(),
13 }
14 }
15
16 fn gen_age_years(rng: &mut impl Rng) -> u16 {
17 rng.gen_range(0..=800)
18 }
19
20 fn gen_years_from_age(rng: &mut impl Rng, age: &Age) -> u16 {
21 rng.gen_range(match age {
22 Age::Infant => 0..=1,
23 Age::Child => 2..=9,
24 Age::Adolescent => 10..=99,
25 Age::YoungAdult => 100..=199,
26 Age::Adult => 200..=299,
27 Age::MiddleAged => 300..=499,
28 Age::Elderly => 500..=749,
29 Age::Geriatric => 750..=800,
30 })
31 }
32
33 fn age_from_years(years: u16) -> Age {
34 match years {
35 i if i < 2 => Age::Infant,
36 i if i < 10 => Age::Child,
37 i if i < 100 => Age::Adolescent,
38 i if i < 200 => Age::YoungAdult,
39 i if i < 300 => Age::Adult,
40 i if i < 500 => Age::MiddleAged,
41 i if i < 750 => Age::Elderly,
42 _ => Age::Geriatric,
43 }
44 }
45
46 fn gen_size(rng: &mut impl Rng, _age_years: u16, _gender: &Gender) -> Size {
47 let size = rng.gen_range(1..=12) + rng.gen_range(1..=12);
48 Size::Medium {
49 height: 54 + size,
50 weight: 60 + size * 6,
51 }
52 }
53}
54
55#[cfg(test)]
56mod test_generate_for_species {
57 use super::*;
58 use std::collections::HashMap;
59
60 #[test]
61 fn gen_gender_test() {
62 let mut rng = SmallRng::seed_from_u64(0);
63 let mut genders: HashMap<String, u16> = HashMap::new();
64
65 for _ in 0..500 {
66 let gender = Species::gen_gender(&mut rng);
67 *genders.entry(format!("{}", gender)).or_default() += 1;
68 }
69
70 assert_eq!(3, genders.len());
71 assert_eq!(Some(&3), genders.get("non-binary (they/them)"));
72 assert_eq!(Some(&233), genders.get("feminine (she/her)"));
73 assert_eq!(Some(&264), genders.get("masculine (he/him)"));
74 }
75
76 #[test]
77 fn gen_age_years_test() {
78 let mut rng = SmallRng::seed_from_u64(0);
79
80 assert_eq!(
81 [358, 351, 784, 370, 718],
82 [
83 Species::gen_age_years(&mut rng),
84 Species::gen_age_years(&mut rng),
85 Species::gen_age_years(&mut rng),
86 Species::gen_age_years(&mut rng),
87 Species::gen_age_years(&mut rng),
88 ],
89 );
90 }
91
92 #[test]
93 fn gen_years_from_age_test() {
94 let ages = [
95 Age::Infant,
96 Age::Child,
97 Age::Adolescent,
98 Age::YoungAdult,
99 Age::Adult,
100 Age::MiddleAged,
101 Age::Elderly,
102 Age::Geriatric,
103 ];
104
105 for age in ages {
106 let mut rng = SmallRng::seed_from_u64(0);
107
108 for _ in 0..10 {
109 let age_years = Species::gen_years_from_age(&mut rng, &age);
110 assert_eq!(age, Species::age_from_years(age_years));
111 }
112 }
113 }
114
115 #[test]
116 fn age_from_years_test() {
117 assert_eq!(Age::Infant, Species::age_from_years(0));
118 assert_eq!(Age::Infant, Species::age_from_years(1));
119
120 assert_eq!(Age::Child, Species::age_from_years(2));
121 assert_eq!(Age::Child, Species::age_from_years(9));
122
123 assert_eq!(Age::Adolescent, Species::age_from_years(10));
124 assert_eq!(Age::Adolescent, Species::age_from_years(99));
125
126 assert_eq!(Age::YoungAdult, Species::age_from_years(100));
127 assert_eq!(Age::YoungAdult, Species::age_from_years(199));
128
129 assert_eq!(Age::Adult, Species::age_from_years(200));
130 assert_eq!(Age::Adult, Species::age_from_years(299));
131
132 assert_eq!(Age::MiddleAged, Species::age_from_years(300));
133 assert_eq!(Age::MiddleAged, Species::age_from_years(499));
134
135 assert_eq!(Age::Elderly, Species::age_from_years(500));
136 assert_eq!(Age::Elderly, Species::age_from_years(749));
137
138 assert_eq!(Age::Geriatric, Species::age_from_years(750));
139 assert_eq!(Age::Geriatric, Species::age_from_years(u16::MAX));
140 }
141
142 #[test]
143 fn gen_size_test() {
144 let mut rng = SmallRng::seed_from_u64(0);
145 let t = Gender::NonBinaryThey;
146
147 let size = |height, weight| Size::Medium { height, weight };
148
149 assert_eq!(
150 [
151 size(66, 132),
152 size(72, 168),
153 size(77, 198),
154 size(68, 144),
155 size(69, 150),
156 ],
157 [
158 Species::gen_size(&mut rng, 0, &t),
159 Species::gen_size(&mut rng, 0, &t),
160 Species::gen_size(&mut rng, 0, &t),
161 Species::gen_size(&mut rng, 0, &t),
162 Species::gen_size(&mut rng, 0, &t),
163 ]
164 );
165 }
166}