check angles

This commit is contained in:
2022-05-03 18:37:53 +02:00
parent e6e67da8c1
commit dda944efff
+105 -67
View File
@@ -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<Point> = 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);
}
}