From dda944efff749a6842530f4c211882b7d5c41952 Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Tue, 3 May 2022 18:37:53 +0200 Subject: [PATCH] check angles --- src/population.rs | 172 ++++++++++++++++++++++++++++------------------ 1 file changed, 105 insertions(+), 67 deletions(-) diff --git a/src/population.rs b/src/population.rs index 9b368c4..f0dec3d 100644 --- a/src/population.rs +++ b/src/population.rs @@ -21,7 +21,6 @@ pub fn human_idx(x: i32, y: i32, width: i32) -> usize { ((y * width) + x) as usize } - impl Population { pub fn new( start_infected_ratio: i32, @@ -105,61 +104,75 @@ impl Population { } } } + println!("{} people to check, death rate {}", people_to_check.len(), self.plague.death_rate); // for pos in &people_to_check { for pos in people_to_check.iter() { //people_to_check.iter().map(|pos|{ //get all the other people next to me and check if i die cure or infect //now we can start to check if people would be infected or not //let idx = human_idx(pos.x as i32, pos.y as i32, self.width as i32); - if pos.x > 0 && pos.x < self.width - 1 && pos.y > 0 && pos.y < self.height - 1 { + if pos.x >= 0 && pos.x <= self.width - 1 && pos.y >= 0 && pos.y <= self.height - 1 { if roll(self.plague.curing_rate) { //checks if the man recovers people_to_cure.push(Point { x: pos.x, y: pos.y }); } else { + if roll(self.plague.death_rate) { //cheks if the man dies - println!("someone should die"); people_to_kill.push(Point { x: pos.x, y: pos.y }); } else { let mut possible_infections: Vec = Vec::with_capacity(8); // Vec::new(); //possible_infections.push(Point{x:pos.x,y:pos.y}); - possible_infections.push(Point { - x: pos.x - 1, - y: pos.y - 1, - }); //Top Left - possible_infections.push(Point { - x: pos.x, - y: pos.y - 1, - }); //Top - possible_infections.push(Point { - x: pos.x + 1, - y: pos.y - 1, - }); //Top Right - - possible_infections.push(Point { - x: pos.x - 1, - y: pos.y, - }); //Left - possible_infections.push(Point { - x: pos.x + 1, - y: pos.y, - }); //Right - - possible_infections.push(Point { - x: pos.x - 1, - y: pos.y + 1, - }); //Bottom Left - possible_infections.push(Point { - x: pos.x, - y: pos.y + 1, - }); //Bottom - possible_infections.push(Point { - x: pos.x + 1, - y: pos.y + 1, - }); //Bottom Right - + if pos.x > 0 && pos.y > 0 { + possible_infections.push(Point { + x: pos.x - 1, + y: pos.y - 1, + }); //Top Left + } + if pos.y > 0 { + possible_infections.push(Point { + x: pos.x, + y: pos.y - 1, + }); //Top + } + if pos.y > 0 && pos.x < self.width - 1 { + possible_infections.push(Point { + x: pos.x + 1, + y: pos.y - 1, + }); //Top Right + } + if pos.x > 0 { + possible_infections.push(Point { + x: pos.x - 1, + y: pos.y, + }); //Left + } + if pos.x < self.width - 1{ + possible_infections.push(Point { + x: pos.x + 1, + y: pos.y, + }); //Right + } + if pos.x > 0 && pos.y < self.height -1 { + possible_infections.push(Point { + x: pos.x - 1, + y: pos.y + 1, + }); //Bottom Left + } + if pos.y < self.height - 1 { + possible_infections.push(Point { + x: pos.x, + y: pos.y + 1, + }); //Bottom + } + if pos.x < self.width - 1 && pos.y < self.height - 1{ + possible_infections.push(Point { + x: pos.x + 1, + y: pos.y + 1, + }); //Bottom Right + } for poss_infected_pos in possible_infections.iter() { //possible_infections.iter().map(|poss_infected_pos|{ let inf_idx = @@ -246,12 +259,13 @@ impl Population { //people_to_kill.iter().map(|dead_position|{ let dead_index = human_idx(dead_position.x, dead_position.y, self.width); if self.humans[dead_index].present_state == State::Dead { - println!("Already dead"); + // println!("Already dead"); } else { self.humans[dead_index].present_state = State::Dead; } //DEBUG } + assert_eq!(stats[0] + stats[1] + stats[2] + stats[3], self.humans.len() as i32); stats } @@ -277,7 +291,7 @@ impl Population { pub fn roll(probability: i32) -> bool { if probability > 0 { let mut rng = rand::thread_rng(); - rng.gen_range(0..CORRECTED_PERCENTAGE) <= probability + rng.gen_range(0 as i32..CORRECTED_PERCENTAGE) <= probability } else { false } @@ -435,10 +449,10 @@ mod tests { #[parameterized(rate = {0, 100}, expected = {false, true})] fn roll_test(rate: i32, expected: bool) { - let tries = 1000; + let tries = 100000; let mut result = 0; println!("Testing roll, rate {}, expected {}", rate, expected); - for _x in 0..1000 { + for _x in 0..tries { if roll(rate) == expected { result += 1; } @@ -446,19 +460,33 @@ mod tests { assert_eq!(result, tries); } - #[parameterized(infection_rate = {0, 100, 0}, death_rate = {0, 0, 100}, infected_expected = {0, 1, 1})] - fn propage_test( - infection_rate: i32, - death_rate: i32, - infected_expected: i32, - ) { + #[test] + fn propagate_simple() { + let disease: Disease = Disease::new(0, 0, 100, String::from("Deadly")); + let mut population: Population = Population::new(100, 0, 0, 10, 10, disease); + let mut stats: Stats; + + stats = humans_stats(&population.humans); + println!("stats after init: {:?}", stats); + assert_eq!(stats.normal, 100); + population.generate(); + stats = humans_stats(&population.humans); + println!("stats after generate: {:?}", stats); + assert_eq!(stats.infected, 100); + } + + #[parameterized(infection_rate = {0, 100, 0}, death_rate = {0, 0, 100}, infected_expected = {0, 1, 0})] + fn propagate_test(infection_rate: i32, death_rate: i32, infected_expected: i32) { let disease: Disease; let mut population: Population; let mut stats: Stats; let (width, height) = (100, 100); let start_infected = 50; - println!("infection rate: {}, death_rate: {}", infection_rate, death_rate); + println!( + "infection rate: {}, death_rate: {}", + infection_rate, death_rate + ); disease = Disease::new(infection_rate, 0, death_rate, String::from("Test")); population = Population::new(start_infected, 0, 0, width, height, disease); @@ -468,28 +496,38 @@ mod tests { println!("Population after generate: {:?}", stats); // total * proba - 20% < infected < total * proba + 20% - let infected_at_start_proba = width * height * start_infected as i32 / 100; + let infected_at_start_proba = width * height * start_infected / 100; let infected_tolerance = ((width * height) as f32 * 0.2) as i32; - assert!(stats.infected < infected_at_start_proba + infected_tolerance); - assert!(stats.infected > infected_at_start_proba - infected_tolerance); + assert!(stats.infected <= infected_at_start_proba + infected_tolerance); + assert!(stats.infected >= infected_at_start_proba - infected_tolerance); assert_eq!(stats.dead, 0); - let infected_at_start = stats.infected; + for _x in 0..100 { + let infected_at_start = stats.infected; + let dead_at_start = stats.dead; - let propa_stats: [i32; 4] = population.propagate(); - if death_rate == 0 { - assert_eq!(propa_stats[3], 0, "no human should have died"); + let propa_stats: [i32; 4] = population.propagate(); + + assert!(propa_stats[3] >= dead_at_start); + + if death_rate == 0 { + assert_eq!(propa_stats[3], 0, "no human should have died"); + } + + stats = humans_stats(&population.humans); + println!("Population after propagate: {:?}", stats); + + assert!(stats.normal <= infected_at_start + width * height * infected_expected); + + let should_be_dead = infected_at_start * death_rate / 100; + let dead_tolerance = (should_be_dead as f32 * 0.20) as i32; + + assert!( + stats.dead <= should_be_dead + dead_tolerance, + "death count should be less or equal than {}", + should_be_dead + dead_tolerance + ); + assert!(stats.dead >= should_be_dead - dead_tolerance); } - - stats = humans_stats(&population.humans); - println!("Population after propagate: {:?}", stats); - - assert!(stats.normal <= infected_at_start + width * height * infected_expected); - - let should_be_dead = infected_at_start * death_rate as i32 / 100; - let dead_tolerance = (should_be_dead as f32 * 0.20) as i32; - - assert!(stats.dead < should_be_dead + dead_tolerance); - assert!(stats.dead > should_be_dead - dead_tolerance); } }