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