initiative_core/world/npc/species/
half_orc.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 => 1..=7,
24 Age::Adolescent => 8..=14,
25 Age::YoungAdult => 15..=19,
26 Age::Adult => 20..=34,
27 Age::MiddleAged => 35..=54,
28 Age::Elderly => 55..=64,
29 Age::Geriatric => 65..=79,
30 })
31 }
32
33 fn age_from_years(years: u16) -> Age {
34 match years {
35 i if i < 1 => Age::Infant,
36 i if i < 8 => Age::Child,
37 i if i < 15 => Age::Adolescent,
38 i if i < 20 => Age::YoungAdult,
39 i if i < 35 => Age::Adult,
40 i if i < 55 => Age::MiddleAged,
41 i if i < 65 => 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..=8) + rng.gen_range(1..=8);
48 Size::Medium {
49 height: 60 + size,
50 weight: 130 + 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 [35, 35, 78, 36, 71],
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
119 assert_eq!(Age::Child, Species::age_from_years(1));
120 assert_eq!(Age::Child, Species::age_from_years(7));
121
122 assert_eq!(Age::Adolescent, Species::age_from_years(8));
123 assert_eq!(Age::Adolescent, Species::age_from_years(14));
124
125 assert_eq!(Age::YoungAdult, Species::age_from_years(15));
126 assert_eq!(Age::YoungAdult, Species::age_from_years(19));
127
128 assert_eq!(Age::Adult, Species::age_from_years(20));
129 assert_eq!(Age::Adult, Species::age_from_years(34));
130
131 assert_eq!(Age::MiddleAged, Species::age_from_years(35));
132 assert_eq!(Age::MiddleAged, Species::age_from_years(54));
133
134 assert_eq!(Age::Elderly, Species::age_from_years(55));
135 assert_eq!(Age::Elderly, Species::age_from_years(64));
136
137 assert_eq!(Age::Geriatric, Species::age_from_years(65));
138 assert_eq!(Age::Geriatric, Species::age_from_years(u16::MAX));
139 }
140
141 #[test]
142 fn gen_size_test() {
143 let mut rng = SmallRng::seed_from_u64(0);
144 let t = Gender::NonBinaryThey;
145
146 let size = |height, weight| Size::Medium { height, weight };
147
148 assert_eq!(
149 [
150 size(68, 178),
151 size(72, 202),
152 size(76, 226),
153 size(69, 184),
154 size(71, 196),
155 ],
156 [
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 Species::gen_size(&mut rng, 0, &t),
162 ]
163 );
164 }
165}