diff --git a/src/disease.rs b/src/disease.rs index 795196f..ee6eeaa 100644 --- a/src/disease.rs +++ b/src/disease.rs @@ -1,9 +1,10 @@ -use crate::prelude::*; +// use crate::prelude::*; -pub const MUTATION_TRAIT_INCREASE_PROBABILITY:i32 = 50; -pub const MUTATION_TRAIT_CHANGE_AMOUNT:i32 = 20; +// pub const MUTATION_TRAIT_INCREASE_PROBABILITY:i32 = 50; +// pub const MUTATION_TRAIT_CHANGE_AMOUNT:i32 = 20; +#[derive(Debug)] pub struct Disease { pub infection_rate:u32, pub curing_rate:u32, @@ -21,21 +22,21 @@ impl Disease{ traits : vec![infection_r,curing_r,death_r], } } - pub fn mutate(&mut self){ - let mut rng = rand::thread_rng(); - for i in 0..self.traits.len(){ - let mut new_ratio:i32 = self.traits[i] as i32; + // pub fn mutate(&mut self){ + // let mut rng = rand::thread_rng(); + // for i in 0..self.traits.len(){ + // let mut new_ratio:i32 = self.traits[i] as i32; - if rng.gen_range(0..CORRECTED_PERCENTAGE) >= MUTATION_TRAIT_INCREASE_PROBABILITY{ - new_ratio += MUTATION_TRAIT_CHANGE_AMOUNT; - }else{ - new_ratio -= MUTATION_TRAIT_CHANGE_AMOUNT; - } - if new_ratio < 0{ - new_ratio = 0; - } - new_ratio = new_ratio % CORRECTED_PERCENTAGE; - self.traits[i] = new_ratio as u32; - } - } + // if rng.gen_range(0..CORRECTED_PERCENTAGE) >= MUTATION_TRAIT_INCREASE_PROBABILITY{ + // new_ratio += MUTATION_TRAIT_CHANGE_AMOUNT; + // }else{ + // new_ratio -= MUTATION_TRAIT_CHANGE_AMOUNT; + // } + // if new_ratio < 0{ + // new_ratio = 0; + // } + // new_ratio = new_ratio % CORRECTED_PERCENTAGE; + // self.traits[i] = new_ratio as u32; + // } + // } } \ No newline at end of file diff --git a/src/human.rs b/src/human.rs index 76b325c..a6ba1ee 100644 --- a/src/human.rs +++ b/src/human.rs @@ -1,31 +1,32 @@ -use crate::prelude::*; +// use crate::prelude::*; -#[derive(Copy, Clone, PartialEq)] +// #[derive(Copy, Clone, PartialEq)] +#[derive(PartialEq)] pub enum State { Normal, Infected, Dead, Immune, } -#[derive(Clone,Copy)] +// #[derive(Clone)] pub struct Human { pub present_state : State, pub x : i32, pub y : i32, } impl Human{ - pub fn new(state : State, pos_x :i32, pos_y :i32) -> Self{ - Self{ - present_state : state, - x : pos_x, - y : pos_y - } - } - pub fn new_empty() -> Self{ - Self{ - present_state:State::Normal, - x : 0, - y : 0, - } - } + // pub fn new(state : State, pos_x :i32, pos_y :i32) -> Self{ + // Self{ + // present_state : state, + // x : pos_x, + // y : pos_y + // } + // } + // pub fn new_empty() -> Self{ + // Self{ + // present_state:State::Normal, + // x : 0, + // y : 0, + // } + // } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index b6a54dc..c263a5e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,7 +28,8 @@ fn main() { println!("After Filling"); //population.display(); println!("After Propagation"); - let mut stats: [i32;4] = [0,0,0,0]; + let mut stats: [i32;4]; + // = [0,0,0,0]; let mut counter:u32 = 0; loop{ counter += 1; diff --git a/src/population.rs b/src/population.rs index ef1c28f..f4232a1 100644 --- a/src/population.rs +++ b/src/population.rs @@ -1,49 +1,48 @@ use crate::prelude::*; +#[derive(Debug)] pub struct Point{ x:i32, y:i32, } pub struct Population{ - pub start_infected_ratio:i32, - pub start_immune_ratio:i32, - pub start_dead_ratio:i32, + pub start_infected_ratio:u32, + pub start_immune_ratio:u32, + pub start_dead_ratio:u32, pub humans:Vec, pub width:i32, pub height:i32, pub age:i32, pub plague:Disease, } -pub fn human_idx(x: i32, y: i32,width:i32) -> usize { + +pub fn human_idx(x: i32, y: i32, width: i32) -> usize { ((y * width) + x)as usize } + impl Population{ - pub fn new(start_infected_ratio:u32,start_immune_ratio:u32,start_dead_ratio:u32,width:u32,height:u32,plague:Disease)->Self{ - let mut the_humans:Vec; - //we first fill the vector with empty humans to prevent any pointer to null - the_humans = vec![Human::new_empty();(width*height)as usize]; - //this is not sufficient, every Human should know its position so ... + pub fn new(start_infected_ratio:u32,start_immune_ratio:u32,start_dead_ratio:u32,width:i32,height:i32,plague:Disease)->Self{ + let mut the_humans: Vec = Vec::with_capacity((width*height) as usize); for x in 0..width{ for y in 0..height{ - let index = human_idx(x as i32,y as i32,width as i32); - the_humans[index] = Human::new(State::Normal, x as i32, y as i32); + the_humans.push(Human{present_state: State::Normal, x: x, y: y}); } } Self{ - start_infected_ratio:start_infected_ratio as i32, - start_immune_ratio:start_immune_ratio as i32, - start_dead_ratio:start_dead_ratio as i32, - width:width as i32, - height:height as i32, + start_infected_ratio:start_infected_ratio, + start_immune_ratio:start_immune_ratio, + start_dead_ratio:start_dead_ratio, + width:width, + height:height, plague:plague, age:0, humans:the_humans, } } - pub fn change_disease(&mut self, plague:Disease){ - self.plague = plague; - } + // pub fn change_disease(&mut self, plague:Disease){ + // self.plague = plague; + // } pub fn generate(&mut self){ //The ratios will not be exact, for example someone who wants 100% infected 100% immune and 100% dead, he will have 100% dead because they are overwriting each others //Maybe consider limiting the total to not exceed 100 in the view @@ -52,49 +51,47 @@ impl Population{ //In other words I did it that way but it can be changed just its not the right method to have perfect ratios let mut rng = rand::thread_rng(); - for x in 0..self.width{ - for y in 0..self.height{ - let index = human_idx(x as i32,y as i32,self.width as i32); - if rng.gen_range(0..CORRECTED_PERCENTAGE) < self.start_infected_ratio as i32 - { - self.humans[index].present_state = State::Infected; - } - if rng.gen_range(0..CORRECTED_PERCENTAGE) < self.start_immune_ratio as i32 - { - self.humans[index].present_state = State::Immune; - } - if rng.gen_range(0..CORRECTED_PERCENTAGE) < self.start_dead_ratio as i32 - { - self.humans[index].present_state = State::Dead; - } + let mut i: i32 = 0; + for x in self.humans.iter_mut() { + if rng.gen_range(0..CORRECTED_PERCENTAGE) < self.start_infected_ratio as i32 + { + x.present_state = State::Infected; } + if rng.gen_range(0..CORRECTED_PERCENTAGE) < self.start_immune_ratio as i32 + { + x.present_state = State::Immune; + } + if rng.gen_range(0..CORRECTED_PERCENTAGE) < self.start_dead_ratio as i32 + { + x.present_state = State::Dead; + } + i += 1; } + println!("generate for {} humans", i); } pub fn propagate(&mut self)->[i32;4]{ - let mut people_to_check:Vec = Vec::new(); - let mut people_to_infect:Vec = Vec::new(); - let mut people_to_cure:Vec = Vec::new(); - let mut people_to_kill:Vec = Vec::new(); + let mut people_to_check:Vec = Vec::with_capacity((self.width * self.height) as usize); + let mut people_to_infect:Vec = Vec::with_capacity((self.width * self.height) as usize); + let mut people_to_cure:Vec = Vec::with_capacity((self.width * self.height) as usize); + let mut people_to_kill:Vec = Vec::with_capacity((self.width * self.height) as usize); let mut stats: [i32;4] = [0,0,0,0]; // stats[0] Normal stats[1] Infected stats[2] Immune stats[3] Dead - for x in 0..self.width{ - for y in 0..self.height{ - let idx = human_idx(x as i32, y as i32, self.width as i32); - match self.humans[idx].present_state{ - State::Normal => {stats[0] += 1;} - State::Infected => {people_to_check.push(Point{x:x,y:y});stats[1]+=1;} - State::Immune => {stats[2] += 1;} - State::Dead => {stats[3] += 1;} - } + for h in self.humans.iter() { + match h.present_state{ + State::Normal => {stats[0] += 1;} + State::Infected => {people_to_check.push(Point{x:h.x,y:h.y});stats[1]+=1;} + State::Immune => {stats[2] += 1;} + State::Dead => {stats[3] += 1;} } } - for pos in &people_to_check { +// 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 as i32 -1 && pos.y > 0 && pos.y < self.height as i32 -1{ + if pos.x > 0 && pos.x < self.width - 1 && pos.y > 0 && pos.y < self.height -1 { if self.roll(self.plague.curing_rate){ //checks if the man dies people_to_cure.push(Point{x:pos.x,y:pos.y}); @@ -103,7 +100,8 @@ impl Population{ //cheks if the man dies people_to_kill.push(Point{x:pos.x,y:pos.y}); }else{ - let mut possible_infections:Vec = Vec::new(); + 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 @@ -117,9 +115,9 @@ impl Population{ 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 - for poss_infected_pos in &possible_infections{ + for poss_infected_pos in possible_infections.iter() { //possible_infections.iter().map(|poss_infected_pos|{ - let inf_idx = human_idx(poss_infected_pos.x as i32, poss_infected_pos.y as i32, self.width as i32); + let inf_idx = human_idx(poss_infected_pos.x, poss_infected_pos.y, self.width); if self.humans[inf_idx].present_state == State::Normal{ if self.roll(self.plague.infection_rate){ people_to_infect.push(Point{x:poss_infected_pos.x,y:poss_infected_pos.y}); @@ -169,29 +167,33 @@ impl Population{ // ##@ } }; - for infected_position in &people_to_infect{ - //people_to_infect.iter().map(|infected_position|{ - let infected_index = human_idx(infected_position.x as i32, infected_position.y as i32, self.width as i32); - //DEBUG - //println!("x: {} y: {} index: {}",infected_position.x,infected_position.y,infected_index); - self.humans[infected_index].present_state = State::Infected; - //DEBUG - //println!("Infected someone"); - }; - for cured_position in &people_to_cure{ - //people_to_cure.iter().map(|cured_position|{ - let cured_index = human_idx(cured_position.x as i32, cured_position.y as i32, self.width as i32); - self.humans[cured_index].present_state = State::Immune; - //DEBUG - //println!("Cured someone"); - }; - for dead_position in &people_to_kill{ - //people_to_kill.iter().map(|dead_position|{ - let dead_index = human_idx(dead_position.x as i32, dead_position.y as i32, self.width as i32); - self.humans[dead_index].present_state = State::Dead; - //DEBUG - //println!("Killed someone"); - }; + for infected_position in &people_to_infect { + // println!("To infect: {:?}", infected_position); + //people_to_infect.iter().map(|infected_position|{ + let infected_index = human_idx(infected_position.x, infected_position.y, self.width); + // let _ = infected_position.x; + //DEBUG + //println!("x: {} y: {} index: {}",infected_position.x,infected_position.y,infected_index); + self.humans[infected_index].present_state = State::Infected; + //DEBUG + //println!("Infected someone"); + }; + + for cured_position in &people_to_cure { + //people_to_cure.iter().map(|cured_position|{ + let cured_index = human_idx(cured_position.x, cured_position.y, self.width); + self.humans[cured_index].present_state = State::Immune; + //DEBUG + //println!("Cured someone"); + }; + + for dead_position in &people_to_kill { + //people_to_kill.iter().map(|dead_position|{ + let dead_index = human_idx(dead_position.x, dead_position.y, self.width); + self.humans[dead_index].present_state = State::Dead; + //DEBUG + //println!("Killed someone"); + }; stats } pub fn roll(&self,probability:u32)->bool{