@@ -4,7 +4,15 @@ use specs_derive;
44use crate :: misc:: time:: Date ;
55use chrono:: Datelike ;
66use crate :: prelude:: * ;
7+ use crate :: pop:: NUM_COHORTS ;
78
9+ const DEATH_RATES : [ f32 ; 17 ] = [
10+ 0.2 , 0.045 , 0.035 , 0.02 , 0.007 , 0.005 , 0.005 , 0.005 ,
11+ 0.01 , 0.015 , 0.02 , 0.03 , 0.04 , 0.06 , 0.1 , 0.3 , 0.8
12+ ] ;
13+ const BIRTH_RATES : [ f32 ; 17 ] = [ 0. , 0. , 0. , 0.01 , 0.02 , 0.55 , 0.45 , 0.25 , 0.1 , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ] ;
14+ const HARVEST_MONTH : u32 = 9 ;
15+ const HEALTH_CHANGE_RATE : f32 = 0.10 ;
816
917pub struct PopUpdate {
1018 pub old_date : Date ,
@@ -13,14 +21,8 @@ pub struct PopUpdate {
1321// Changes Cohort health in response to food scarcity, disease, sanitation etc.
1422pub struct HealthUpdate ;
1523
16- // The
17- pub struct FoodConsumptionUpdate ;
18-
19- const DEATH_RATES : [ f32 ; 17 ] = [
20- 0.2 , 0.045 , 0.035 , 0.02 , 0.007 , 0.005 , 0.005 , 0.005 ,
21- 0.01 , 0.015 , 0.02 , 0.03 , 0.04 , 0.06 , 0.1 , 0.3 , 0.8
22- ] ;
23- const BIRTH_RATES : [ f32 ; 17 ] = [ 0. , 0. , 0. , 0.01 , 0.02 , 0.55 , 0.45 , 0.25 , 0.1 , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ] ;
24+ // Recalculate Monthly Food Consumption
25+ pub struct FoodConsumptionSystem ;
2426
2527impl < ' a > System < ' a > for PopUpdate {
2628 type SystemData = ( ReadStorage < ' a , Health > ,
@@ -34,61 +36,75 @@ impl<'a> System<'a> for PopUpdate {
3436 let dt = ( * date - self . old_date ) . num_days ( ) ;
3537 self . old_date = date. clone ( ) ;
3638
37- // if dt < 30 { return; }
38-
3939
40- let mut b = true ;
4140 for ( p, h) in ( & mut pop, & health) . join ( ) {
42- p. update ( & BIRTH_RATES , & DEATH_RATES , dt as u16 ) ;
43-
44- if b {
45- //dbg!(&p);
46- b = false
47- }
41+ let brs: ArrayVec < [ f32 ; NUM_COHORTS ] > = BIRTH_RATES . iter ( ) . map ( |& br| br * h. health ) . collect ( ) ;
42+ let drs: ArrayVec < [ f32 ; NUM_COHORTS ] > = DEATH_RATES . iter ( ) . map ( |& dr| dr * h. health ) . collect ( ) ;
43+ p. update ( brs. as_slice ( ) , & drs, dt as u16 ) ;
4844 }
4945 }
5046 }
5147}
5248
49+
50+
51+
5352impl < ' a > System < ' a > for HealthUpdate {
5453 type SystemData = ( WriteStorage < ' a , Health > ,
55- WriteStorage < ' a , FoodConsumption > ,
54+ ReadStorage < ' a , FoodConsumption > ,
5655 ReadStorage < ' a , FoodStock > ) ;
5756
58- fn run ( & mut self , ( health, consump, food) : Self :: SystemData ) { }
57+ fn run ( & mut self , ( mut health, consump, food) : Self :: SystemData ) {
58+ for ( health, consump, food) in ( & mut health, & consump, & food) . join ( ) {
59+ let r = consump. ratio_of_norm ;
60+
61+ // later add more interesting interactions with other systems
62+ let target_health = r;
63+
64+
65+ // half-life for health change is .7/rate, so .10 rate
66+ // ==> will get to half the difference in 7 months (periods)
67+ health. health += HEALTH_CHANGE_RATE * ( target_health - health. health ) ;
68+ }
69+ }
5970}
6071
61- impl < ' a > System < ' a > for FoodConsumptionUpdate {
72+ impl < ' a > System < ' a > for FoodConsumptionSystem {
6273 type SystemData = ( WriteStorage < ' a , FoodStock > ,
6374 WriteStorage < ' a , FoodConsumption > ,
6475 ReadStorage < ' a , RegionPop > ,
65- ReadStorage < ' a , Health > ,
6676 ReadExpect < ' a , Date > ) ;
6777
68- fn run ( & mut self , ( mut stock, mut consump, pop, health , date) : Self :: SystemData ) {
78+ fn run ( & mut self , ( mut stock, mut consump, pop, date) : Self :: SystemData ) {
6979 if date. day ( ) != 3 {
7080 return ;
7181 }
7282
73- let months_2_harvest = ( ( 9 - date. month ( ) ) % 12 ) as f32 ;
83+ let months_2_harvest = ( ( HARVEST_MONTH - date. month ( ) ) % 12 ) as f32 ;
7484
75- for ( stock, mut consump, pop, health ) in ( & mut stock, & mut consump, & pop, & health ) . join ( ) {
85+ for ( mut stock, mut consump, pop) in ( & mut stock, & mut consump, & pop) . join ( ) {
7686 let base_grain = grain_for_pop ( pop) ;
7787 let abundance = stock. bushels / ( base_grain * months_2_harvest / 12. ) ;
78- let r = if abundance > 1.3 {
88+ let r = if abundance > 1.4 {
7989 1.2
8090 } else if abundance > 0.8 {
8191 abundance. sqrt ( )
8292 } else if abundance > 0.6 {
8393 abundance
8494 } else {
85- 0.65
95+ 0.6
8696 } ;
8797
8898 consump. consump = base_grain * r / 12. ;
8999 consump. ratio_of_norm = r;
100+
101+ stock. bushels = ( stock. bushels - consump. consump ) . max ( 0. ) ;
90102 }
91103 }
92104}
93105
106+ pub fn logistic ( r : f32 , x : f32 , k : f32 ) -> f32 {
107+ r * x * ( k - x) / k
108+ }
109+
94110
0 commit comments