diff --git a/rust-pvz-genetics/src/genetics/gene.rs b/rust-pvz-genetics/src/genetics/gene.rs index 11b73fb..02eff57 100644 --- a/rust-pvz-genetics/src/genetics/gene.rs +++ b/rust-pvz-genetics/src/genetics/gene.rs @@ -11,3 +11,12 @@ pub enum GeneType { Consumer, Modifier, } + +impl Gene { + pub fn new(place_str: impl Into, kind: GeneType) -> Self { + Self { + place: place_str.into(), + kind, + } + } +} diff --git a/rust-pvz-genetics/src/genetics/genome.rs b/rust-pvz-genetics/src/genetics/genome.rs index f95bf40..3264911 100644 --- a/rust-pvz-genetics/src/genetics/genome.rs +++ b/rust-pvz-genetics/src/genetics/genome.rs @@ -1,8 +1,8 @@ use crate::genetics::{gene::Gene, edge::Edge}; pub struct PlantGenome { - genes: Vec, - edges: Vec + pub(crate) genes: Vec, + pub(crate) edges: Vec } impl PlantGenome { @@ -16,13 +16,13 @@ impl PlantGenome { if let None = parent && self.genes.len() > 0 { return Some(PlantGenomeInsertError::RootExists); } - if let Some(_) = self.genes.iter().find(|g| **g == gene){ + if self.genes.contains(&gene){ return Some(PlantGenomeInsertError::GeneExists); } if let Some(parent_gene) = parent { let edge = Edge::new(parent_gene,gene.clone()); - if let Some(_) = self.edges.iter().find(|e| **e == edge) { + if self.edges.contains(&edge) { return Some(PlantGenomeInsertError::EdgeExists); } self.edges.push(edge); @@ -32,7 +32,7 @@ impl PlantGenome { self.update_graph(); return None; } - fn update_graph(&mut self) { + pub(crate) fn update_graph(&mut self) { // Sort by parent to guarantee root at [0] self.edges.sort(); } @@ -46,6 +46,7 @@ impl PlantGenome { } } +#[derive(Debug)] pub enum PlantGenomeInsertError { GeneExists, EdgeExists, diff --git a/rust-pvz-genetics/src/genetics/genome_builder.rs b/rust-pvz-genetics/src/genetics/genome_builder.rs new file mode 100644 index 0000000..d7dbe31 --- /dev/null +++ b/rust-pvz-genetics/src/genetics/genome_builder.rs @@ -0,0 +1,63 @@ +use crate::genetics::prelude::*; + +pub struct GenomeBuilder { + genome: PlantGenome, + current_gene: usize, +} + +impl GenomeBuilder { + + pub fn new() -> Self { + Self { + genome: PlantGenome::new(), + current_gene: 0 + } + } + + pub fn finish(mut self) -> PlantGenome { + self.genome.update_graph(); + return self.genome; + } + + pub fn create_root(mut self, root: Gene) -> Result { + if self.genome.genes.len() > 0 { + return Err(GenomeBuilderError::RootExists); + } + self.genome.genes.push(root); + + return Ok(self); + } + + pub fn insert_gene(mut self, gene: Gene, parent: Gene) -> Result { + if self.genome.genes.contains(&gene){ + return Err(GenomeBuilderError::GeneExists); + } + + let edge = Edge::new(parent,gene.clone()); + if self.genome.edges.contains(&edge) { + return Err(GenomeBuilderError::EdgeExists); + } + + self.genome.edges.push(edge); + + self.current_gene = self.genome.genes.len(); + self.genome.genes.push(gene); + + Ok(self) + } + pub fn add_gene(mut self, gene: Gene) -> Result { + if self.genome.genes.len() == 0 { + return Err(GenomeBuilderError::RootDoesntExist); + } + todo!(); + } + +} + +#[derive(Debug)] +pub enum GenomeBuilderError { + RootExists, + RootDoesntExist, + GeneExists, + EdgeExists, +} diff --git a/rust-pvz-genetics/src/genetics/mod.rs b/rust-pvz-genetics/src/genetics/mod.rs index 62cc2bf..91e1dc0 100644 --- a/rust-pvz-genetics/src/genetics/mod.rs +++ b/rust-pvz-genetics/src/genetics/mod.rs @@ -4,6 +4,7 @@ pub mod plant_templates; pub mod edge; pub mod gene; pub mod genome; +pub mod genome_builder; pub mod prelude { pub use crate::genetics::edge::*; diff --git a/rust-pvz-genetics/src/genetics/plant_templates.rs b/rust-pvz-genetics/src/genetics/plant_templates.rs new file mode 100644 index 0000000..6abc0a8 --- /dev/null +++ b/rust-pvz-genetics/src/genetics/plant_templates.rs @@ -0,0 +1,7 @@ +use crate::genetics::{genome_builder::GenomeBuilder, prelude::*}; + +pub fn peashooter_template() -> PlantGenome { + GenomeBuilder::new() + .create_root(Gene::new("base", GeneType::Producer)).unwrap() + .finish() +}