forked from Maxluli/RustyPropagation
check angles
This commit is contained in:
+61
-23
@@ -21,7 +21,6 @@ pub fn human_idx(x: i32, y: i32, width: i32) -> usize {
|
|||||||
((y * width) + x) as usize
|
((y * width) + x) as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Population {
|
impl Population {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
start_infected_ratio: i32,
|
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 {
|
||||||
for pos in people_to_check.iter() {
|
for pos in people_to_check.iter() {
|
||||||
//people_to_check.iter().map(|pos|{
|
//people_to_check.iter().map(|pos|{
|
||||||
//get all the other people next to me and check if i die cure or infect
|
//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
|
//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);
|
//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) {
|
if roll(self.plague.curing_rate) {
|
||||||
//checks if the man recovers
|
//checks if the man recovers
|
||||||
people_to_cure.push(Point { x: pos.x, y: pos.y });
|
people_to_cure.push(Point { x: pos.x, y: pos.y });
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if roll(self.plague.death_rate) {
|
if roll(self.plague.death_rate) {
|
||||||
//cheks if the man dies
|
//cheks if the man dies
|
||||||
println!("someone should die");
|
|
||||||
people_to_kill.push(Point { x: pos.x, y: pos.y });
|
people_to_kill.push(Point { x: pos.x, y: pos.y });
|
||||||
} else {
|
} else {
|
||||||
let mut possible_infections: Vec<Point> = Vec::with_capacity(8);
|
let mut possible_infections: Vec<Point> = Vec::with_capacity(8);
|
||||||
// Vec::new();
|
// Vec::new();
|
||||||
//possible_infections.push(Point{x:pos.x,y:pos.y});
|
//possible_infections.push(Point{x:pos.x,y:pos.y});
|
||||||
|
|
||||||
|
if pos.x > 0 && pos.y > 0 {
|
||||||
possible_infections.push(Point {
|
possible_infections.push(Point {
|
||||||
x: pos.x - 1,
|
x: pos.x - 1,
|
||||||
y: pos.y - 1,
|
y: pos.y - 1,
|
||||||
}); //Top Left
|
}); //Top Left
|
||||||
|
}
|
||||||
|
if pos.y > 0 {
|
||||||
possible_infections.push(Point {
|
possible_infections.push(Point {
|
||||||
x: pos.x,
|
x: pos.x,
|
||||||
y: pos.y - 1,
|
y: pos.y - 1,
|
||||||
}); //Top
|
}); //Top
|
||||||
|
}
|
||||||
|
if pos.y > 0 && pos.x < self.width - 1 {
|
||||||
possible_infections.push(Point {
|
possible_infections.push(Point {
|
||||||
x: pos.x + 1,
|
x: pos.x + 1,
|
||||||
y: pos.y - 1,
|
y: pos.y - 1,
|
||||||
}); //Top Right
|
}); //Top Right
|
||||||
|
}
|
||||||
|
if pos.x > 0 {
|
||||||
possible_infections.push(Point {
|
possible_infections.push(Point {
|
||||||
x: pos.x - 1,
|
x: pos.x - 1,
|
||||||
y: pos.y,
|
y: pos.y,
|
||||||
}); //Left
|
}); //Left
|
||||||
|
}
|
||||||
|
if pos.x < self.width - 1{
|
||||||
possible_infections.push(Point {
|
possible_infections.push(Point {
|
||||||
x: pos.x + 1,
|
x: pos.x + 1,
|
||||||
y: pos.y,
|
y: pos.y,
|
||||||
}); //Right
|
}); //Right
|
||||||
|
}
|
||||||
|
if pos.x > 0 && pos.y < self.height -1 {
|
||||||
possible_infections.push(Point {
|
possible_infections.push(Point {
|
||||||
x: pos.x - 1,
|
x: pos.x - 1,
|
||||||
y: pos.y + 1,
|
y: pos.y + 1,
|
||||||
}); //Bottom Left
|
}); //Bottom Left
|
||||||
|
}
|
||||||
|
if pos.y < self.height - 1 {
|
||||||
possible_infections.push(Point {
|
possible_infections.push(Point {
|
||||||
x: pos.x,
|
x: pos.x,
|
||||||
y: pos.y + 1,
|
y: pos.y + 1,
|
||||||
}); //Bottom
|
}); //Bottom
|
||||||
|
}
|
||||||
|
if pos.x < self.width - 1 && pos.y < self.height - 1{
|
||||||
possible_infections.push(Point {
|
possible_infections.push(Point {
|
||||||
x: pos.x + 1,
|
x: pos.x + 1,
|
||||||
y: pos.y + 1,
|
y: pos.y + 1,
|
||||||
}); //Bottom Right
|
}); //Bottom Right
|
||||||
|
}
|
||||||
for poss_infected_pos in possible_infections.iter() {
|
for poss_infected_pos in possible_infections.iter() {
|
||||||
//possible_infections.iter().map(|poss_infected_pos|{
|
//possible_infections.iter().map(|poss_infected_pos|{
|
||||||
let inf_idx =
|
let inf_idx =
|
||||||
@@ -246,12 +259,13 @@ impl Population {
|
|||||||
//people_to_kill.iter().map(|dead_position|{
|
//people_to_kill.iter().map(|dead_position|{
|
||||||
let dead_index = human_idx(dead_position.x, dead_position.y, self.width);
|
let dead_index = human_idx(dead_position.x, dead_position.y, self.width);
|
||||||
if self.humans[dead_index].present_state == State::Dead {
|
if self.humans[dead_index].present_state == State::Dead {
|
||||||
println!("Already dead");
|
// println!("Already dead");
|
||||||
} else {
|
} else {
|
||||||
self.humans[dead_index].present_state = State::Dead;
|
self.humans[dead_index].present_state = State::Dead;
|
||||||
}
|
}
|
||||||
//DEBUG
|
//DEBUG
|
||||||
}
|
}
|
||||||
|
assert_eq!(stats[0] + stats[1] + stats[2] + stats[3], self.humans.len() as i32);
|
||||||
stats
|
stats
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +291,7 @@ impl Population {
|
|||||||
pub fn roll(probability: i32) -> bool {
|
pub fn roll(probability: i32) -> bool {
|
||||||
if probability > 0 {
|
if probability > 0 {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
rng.gen_range(0..CORRECTED_PERCENTAGE) <= probability
|
rng.gen_range(0 as i32..CORRECTED_PERCENTAGE) <= probability
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -435,10 +449,10 @@ mod tests {
|
|||||||
|
|
||||||
#[parameterized(rate = {0, 100}, expected = {false, true})]
|
#[parameterized(rate = {0, 100}, expected = {false, true})]
|
||||||
fn roll_test(rate: i32, expected: bool) {
|
fn roll_test(rate: i32, expected: bool) {
|
||||||
let tries = 1000;
|
let tries = 100000;
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
println!("Testing roll, rate {}, expected {}", rate, expected);
|
println!("Testing roll, rate {}, expected {}", rate, expected);
|
||||||
for _x in 0..1000 {
|
for _x in 0..tries {
|
||||||
if roll(rate) == expected {
|
if roll(rate) == expected {
|
||||||
result += 1;
|
result += 1;
|
||||||
}
|
}
|
||||||
@@ -446,19 +460,33 @@ mod tests {
|
|||||||
assert_eq!(result, tries);
|
assert_eq!(result, tries);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[parameterized(infection_rate = {0, 100, 0}, death_rate = {0, 0, 100}, infected_expected = {0, 1, 1})]
|
#[test]
|
||||||
fn propage_test(
|
fn propagate_simple() {
|
||||||
infection_rate: i32,
|
let disease: Disease = Disease::new(0, 0, 100, String::from("Deadly"));
|
||||||
death_rate: i32,
|
let mut population: Population = Population::new(100, 0, 0, 10, 10, disease);
|
||||||
infected_expected: i32,
|
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 disease: Disease;
|
||||||
let mut population: Population;
|
let mut population: Population;
|
||||||
let mut stats: Stats;
|
let mut stats: Stats;
|
||||||
let (width, height) = (100, 100);
|
let (width, height) = (100, 100);
|
||||||
let start_infected = 50;
|
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"));
|
disease = Disease::new(infection_rate, 0, death_rate, String::from("Test"));
|
||||||
population = Population::new(start_infected, 0, 0, width, height, disease);
|
population = Population::new(start_infected, 0, 0, width, height, disease);
|
||||||
@@ -468,15 +496,20 @@ mod tests {
|
|||||||
println!("Population after generate: {:?}", stats);
|
println!("Population after generate: {:?}", stats);
|
||||||
|
|
||||||
// total * proba - 20% < infected < total * proba + 20%
|
// 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;
|
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);
|
assert_eq!(stats.dead, 0);
|
||||||
|
|
||||||
|
for _x in 0..100 {
|
||||||
let infected_at_start = stats.infected;
|
let infected_at_start = stats.infected;
|
||||||
|
let dead_at_start = stats.dead;
|
||||||
|
|
||||||
let propa_stats: [i32; 4] = population.propagate();
|
let propa_stats: [i32; 4] = population.propagate();
|
||||||
|
|
||||||
|
assert!(propa_stats[3] >= dead_at_start);
|
||||||
|
|
||||||
if death_rate == 0 {
|
if death_rate == 0 {
|
||||||
assert_eq!(propa_stats[3], 0, "no human should have died");
|
assert_eq!(propa_stats[3], 0, "no human should have died");
|
||||||
}
|
}
|
||||||
@@ -486,10 +519,15 @@ mod tests {
|
|||||||
|
|
||||||
assert!(stats.normal <= infected_at_start + width * height * infected_expected);
|
assert!(stats.normal <= infected_at_start + width * height * infected_expected);
|
||||||
|
|
||||||
let should_be_dead = infected_at_start * death_rate as i32 / 100;
|
let should_be_dead = infected_at_start * death_rate / 100;
|
||||||
let dead_tolerance = (should_be_dead as f32 * 0.20) as i32;
|
let dead_tolerance = (should_be_dead as f32 * 0.20) as i32;
|
||||||
|
|
||||||
assert!(stats.dead < should_be_dead + dead_tolerance);
|
assert!(
|
||||||
assert!(stats.dead > should_be_dead - dead_tolerance);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user