New templates
This commit is contained in:
parent
a9615c07a7
commit
aa27328286
7 changed files with 63 additions and 164 deletions
|
|
@ -8,7 +8,7 @@ Documented generation process is easier to visualize.
|
||||||
### Peashooter example
|
### Peashooter example
|
||||||
1. Create [generator] root
|
1. Create [generator] root
|
||||||
2. Add [transfer] stem
|
2. Add [transfer] stem
|
||||||
3. Add [trigger] head
|
3. Add [transfer] head
|
||||||
4. Add [modifier] leaf
|
4. Add [modifier] leaf
|
||||||
5. Return to head
|
5. Return to head
|
||||||
6. Add [output] face
|
6. Add [output] face
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
use std::cmp::Ordering;
|
|
||||||
use crate::genetics::gene::Gene;
|
|
||||||
|
|
||||||
#[derive(PartialEq,Eq,Clone)]
|
|
||||||
pub struct Edge {
|
|
||||||
pub from: Gene,
|
|
||||||
pub to: Gene
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Edge{
|
|
||||||
pub fn new(from: Gene, to: Gene) -> Self {
|
|
||||||
Self {
|
|
||||||
from,
|
|
||||||
to
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialOrd for Edge {
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
||||||
Some(self.cmp(other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ord for Edge {
|
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
|
||||||
if self.from == other.to {return Ordering::Greater;}
|
|
||||||
else if self.to == other.from {return Ordering::Less;}
|
|
||||||
else {return Ordering::Equal;}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,6 +6,7 @@ pub struct Gene {
|
||||||
|
|
||||||
#[derive(PartialEq,Eq,Clone)]
|
#[derive(PartialEq,Eq,Clone)]
|
||||||
pub enum GeneType {
|
pub enum GeneType {
|
||||||
|
Dummy,
|
||||||
PureProducer {
|
PureProducer {
|
||||||
create_flow: fn()
|
create_flow: fn()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::genetics::{gene::Gene, edge::Edge};
|
use crate::genetics::gene::Gene;
|
||||||
|
|
||||||
pub struct PlantGenome {
|
pub struct PlantGenome {
|
||||||
pub(crate) genes: Vec<Gene>,
|
pub(crate) genes: Vec<Gene>,
|
||||||
pub(crate) edges: Vec<Edge>
|
pub(crate) edges: Vec<(usize,usize)>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlantGenome {
|
impl PlantGenome {
|
||||||
|
|
@ -12,43 +12,30 @@ impl PlantGenome {
|
||||||
edges: Vec::new()
|
edges: Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn insert_gene(&mut self, gene: Gene, parent: Option<Gene>) -> Option<PlantGenomeInsertError> {
|
pub fn from_edges(nodes: Vec<Gene>,edges: Vec<(usize,usize)>) -> Result<Self,PlantCreationError> {
|
||||||
if let None = parent && self.genes.len() > 0 {
|
// Check for nodes amount and edges amount mismatch
|
||||||
return Some(PlantGenomeInsertError::RootExists);
|
if nodes.len() != edges.len() {
|
||||||
}
|
return Err(PlantCreationError::AmountMismatch);
|
||||||
if self.genes.contains(&gene){
|
|
||||||
return Some(PlantGenomeInsertError::GeneExists);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(parent_gene) = parent {
|
if nodes.len() == 0 {
|
||||||
let edge = Edge::new(parent_gene,gene.clone());
|
return Err(PlantCreationError::EmptyNodes);
|
||||||
if self.edges.contains(&edge) {
|
|
||||||
return Some(PlantGenomeInsertError::EdgeExists);
|
|
||||||
}
|
|
||||||
self.edges.push(edge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.genes.push(gene);
|
if edges.len() == 0 {
|
||||||
self.update_graph();
|
return Err(PlantCreationError::EmptyEdges);
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
pub(crate) fn update_graph(&mut self) {
|
|
||||||
// Sort by parent to guarantee root at [0]
|
|
||||||
self.edges.sort();
|
|
||||||
}
|
|
||||||
pub fn crossingover(&mut self, other: &mut Self) {
|
|
||||||
|
|
||||||
self.update_graph();
|
return Ok(Self {
|
||||||
other.update_graph();
|
genes: nodes,
|
||||||
}
|
edges
|
||||||
pub fn mutation(&mut self) {
|
});
|
||||||
self.update_graph();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum PlantGenomeInsertError {
|
pub enum PlantCreationError {
|
||||||
GeneExists,
|
EmptyNodes,
|
||||||
EdgeExists,
|
EmptyEdges,
|
||||||
RootExists,
|
AmountMismatch,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
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<Self,GenomeBuilderError> {
|
|
||||||
// Check for root existance
|
|
||||||
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<Self,GenomeBuilderError> {
|
|
||||||
// Check for gene collision
|
|
||||||
if self.genome.genes.contains(&gene){
|
|
||||||
return Err(GenomeBuilderError::GeneExists);
|
|
||||||
}
|
|
||||||
|
|
||||||
let edge = Edge::new(parent,gene.clone());
|
|
||||||
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<Self,GenomeBuilderError> {
|
|
||||||
// Check for root existance
|
|
||||||
if self.genome.genes.len() == 0 {
|
|
||||||
return Err(GenomeBuilderError::RootDoesntExist);
|
|
||||||
}
|
|
||||||
// Check for gene collision
|
|
||||||
if self.genome.genes.contains(&gene){
|
|
||||||
return Err(GenomeBuilderError::GeneExists);
|
|
||||||
}
|
|
||||||
let edge = Edge::new(self.get_current_gene().clone(),gene.clone());
|
|
||||||
self.genome.edges.push(edge);
|
|
||||||
|
|
||||||
self.current_gene = self.genome.genes.len();
|
|
||||||
self.genome.genes.push(gene);
|
|
||||||
|
|
||||||
Ok(self)
|
|
||||||
|
|
||||||
}
|
|
||||||
pub fn back(mut self, amount: Option<usize>) -> Self {
|
|
||||||
for _ in 0..amount.unwrap_or(0) {
|
|
||||||
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn get_current_gene(&self) -> &Gene {
|
|
||||||
&self.genome.genes[self.current_gene]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn get_current_gene_mut(&mut self) -> &mut Gene {
|
|
||||||
&mut self.genome.genes[self.current_gene]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum GenomeBuilderError {
|
|
||||||
RootExists,
|
|
||||||
RootDoesntExist,
|
|
||||||
GeneExists,
|
|
||||||
EdgeExists,
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
pub mod plant_templates;
|
pub mod plant_templates;
|
||||||
pub mod edge;
|
|
||||||
pub mod gene;
|
pub mod gene;
|
||||||
pub mod genome;
|
pub mod genome;
|
||||||
pub mod genome_builder;
|
|
||||||
pub mod arguments;
|
pub mod arguments;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::genetics::edge::*;
|
|
||||||
pub use crate::genetics::genome::*;
|
pub use crate::genetics::genome::*;
|
||||||
pub use crate::genetics::gene::*;
|
pub use crate::genetics::gene::*;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,45 @@
|
||||||
use crate::genetics::{genome_builder::GenomeBuilder, prelude::*};
|
use crate::genetics::prelude::*;
|
||||||
|
|
||||||
pub fn peashooter_template() -> PlantGenome {
|
pub fn peashooter_template() -> PlantGenome {
|
||||||
GenomeBuilder::new()
|
PlantGenome::from_edges(vec![
|
||||||
.create_root(Gene::new("root", GeneType::pure_producer(||{}))).unwrap()
|
Gene::new("root", GeneType::pure_producer(||{})),
|
||||||
.add_gene(Gene::new("stem", GeneType::fill_all())).unwrap()
|
Gene::new("stem", GeneType::fill_all()),
|
||||||
.add_gene(Gene::new("head",GeneType::random_distribution())).unwrap()
|
Gene::new("head",GeneType::random_distribution()),
|
||||||
.add_gene(Gene::new("leaf",GeneType::modifier(||{}))).unwrap()
|
Gene::new("leaf",GeneType::modifier(||{})),
|
||||||
.back(None)
|
Gene::new("face",GeneType::consumer(||{}))
|
||||||
.add_gene(Gene::new("face",GeneType::consumer(||{}))).unwrap()
|
],vec![
|
||||||
.finish()
|
(0,1),
|
||||||
|
(1,2),
|
||||||
|
(2,3),
|
||||||
|
(2,4)
|
||||||
|
]).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sunflower_template() -> PlantGenome {
|
||||||
|
PlantGenome::from_edges(vec![
|
||||||
|
Gene::new("root", GeneType::Dummy),
|
||||||
|
Gene::new("stem", GeneType::Dummy),
|
||||||
|
Gene::new("head", GeneType::modifier(||{})),
|
||||||
|
Gene::new("face", GeneType::consumer(||{})),
|
||||||
|
], vec![
|
||||||
|
(0,1),
|
||||||
|
(1,2),
|
||||||
|
(2,3),
|
||||||
|
]).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cherry_bomb_template() -> PlantGenome {
|
||||||
|
PlantGenome::from_edges(vec![
|
||||||
|
Gene::new("root", GeneType::modifier(||{})),
|
||||||
|
Gene::new("head", GeneType::consumer(||{})),
|
||||||
|
Gene::new("head", GeneType::consumer(||{})),
|
||||||
|
Gene::new("face", GeneType::Dummy),
|
||||||
|
Gene::new("face", GeneType::Dummy),
|
||||||
|
], vec![
|
||||||
|
(0,1),
|
||||||
|
(0,2),
|
||||||
|
(1,3),
|
||||||
|
(2,4),
|
||||||
|
]).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue