Allelic crossingover backend

This commit is contained in:
Rendo 2026-04-06 00:47:05 +05:00
commit 84b2053bea
6 changed files with 121 additions and 8 deletions

View file

@ -30,7 +30,7 @@ impl PairGenomeModificator {
generator: StdRng::seed_from_u64(seed)
};
}
pub fn allelic_crossingover(mut self,chance: Option<u8>) -> (Genome, Genome) {
pub fn allelic_crossingover(&mut self,chance: Option<u8>) -> (Genome, Genome) {
let amount: usize = *[self.genome_a.graph.len(),self.genome_b.graph.len()].iter().min().unwrap_or(&0);
for i in 0..amount {
@ -39,9 +39,9 @@ impl PairGenomeModificator {
swap(&mut self.genome_a.graph[i].0, &mut self.genome_b.graph[i].0);
}
(self.genome_a,self.genome_b)
(self.genome_a.clone(),self.genome_b.clone())
}
pub fn categoric_crossingover(mut self, chance: Option<u8>) -> (Genome,Genome) {
pub fn categoric_crossingover(&mut self, chance: Option<u8>) -> (Genome,Genome) {
let threshold = chance.unwrap_or(2).max(2);
let mut categories_a: HashMap<String, Vec<usize>> = HashMap::new();
@ -68,13 +68,13 @@ impl PairGenomeModificator {
self.genome_a.graph[fi].0 = gene_b;
self.genome_b.graph[si].0 = gene_a;
}
(self.genome_a,self.genome_b)
(self.genome_a.clone(),self.genome_b.clone())
}
pub fn combine(mut self) -> (Genome,Genome){
(self.genome_a,self.genome_b)
pub fn combine(&mut self) -> (Genome,Genome){
(self.genome_a.clone(),self.genome_b.clone())
}
pub fn cancel(self) -> (Genome,Genome) {
(self.genome_a,self.genome_b)
pub fn cancel(&self) -> (Genome,Genome) {
(self.genome_a.clone(),self.genome_b.clone())
}
}

View file

@ -44,8 +44,18 @@ impl INode for GodotGenome {
}
#[godot_api]
impl GodotGenome {
#[signal]
pub fn genome_updated();
}
impl GodotGenome {
pub fn get_genome(&self) -> Option<Genome> {
self.genome.clone()
}
pub fn set_genome(&mut self, genome: Genome) {
self.genome = Some(genome);
self.signals().genome_updated().emit();
}
}

View file

@ -1,2 +1,4 @@
pub mod godot_genome;
pub mod plant;
pub mod reference_modifiers;
pub mod copy_modifiers;

View file

@ -16,6 +16,50 @@ impl INode2D for Plant {
fn ready(&mut self) {
let Some(godot_genome) = self.genome.clone() else { return; };
godot_genome.signals().genome_updated().connect_other(&*self, Self::restructure);
let Some(genome)= godot_genome.bind().get_genome() else { return; };
let mut children = {
let mut result = Vec::new();
for i in 0..genome.graph.len() {
result.push((Sprite2D::new_alloc(),&genome.graph[i]));
}
result
};
for i in 0..genome.graph.len() {
children[i].0.set_name(&genome.graph[i].0.place.to_string());
// Setting up genes
if let Some(sprite) = genome.graph[i].0.sprite.clone() {
children[i].0.set_texture(&load::<Texture2D>(&("res://assets/sprites/".to_string() + &sprite)));
}
// Setting up children
for edge in &genome.graph[i].1 {
let mut gene_sprite = children[*edge].0.clone();
gene_sprite.set_position((children[i].1.0.get_child_position)(children[*edge].1.0.place.clone()));
children[i].0.add_child(&gene_sprite);
}
}
self.base_mut().add_child(&children[0].0);
}
}
#[godot_api]
impl Plant {
#[func]
fn restructure(&mut self) {
if let Some(mut child) = self.base().get_child(0) {
child.queue_free();
}
let Some(godot_genome) = self.genome.clone() else { return; };
let Some(genome)= godot_genome.bind().get_genome() else { return; };
let mut children = {

View file

@ -0,0 +1,57 @@
use godot::prelude::*;
use crate::{genetics::manipulations::{PairGenomeModificator,SingleGenomeModificator}, godot_wrapper::godot_genome::GodotGenome};
#[derive(GodotClass)]
#[class(base=Node)]
pub struct ReferencePairModifier {
#[export]
godot_genome_a: Option<Gd<GodotGenome>>,
#[export]
godot_genome_b: Option<Gd<GodotGenome>>,
modifier: Option<PairGenomeModificator>,
base: Base<Node>,
}
#[godot_api]
impl INode for ReferencePairModifier{
fn init(base: Base<Node>) -> Self {
Self {
godot_genome_a: None,
godot_genome_b: None,
modifier: None,
base
}
}
fn ready(&mut self) {
if self.godot_genome_a.is_none() || self.godot_genome_b.is_none() {
godot_warn!("One of the genomes is not specified!");
return;
}
let (genome_a, genome_b) = (self.godot_genome_a.as_ref().unwrap().bind().get_genome(),self.godot_genome_b.as_ref().unwrap().bind().get_genome());
if genome_a.is_none() || genome_b.is_none() {
godot_warn!("One of genomes does not contain a genome!");
return;
}
self.modifier = Some(PairGenomeModificator::new(genome_a.unwrap(),genome_b.unwrap()));
}
}
#[godot_api]
impl ReferencePairModifier {
#[func]
fn allelic_crossingover(&mut self) {
if let Some(pair) = self.modifier.as_mut() {
let (genome_a,genome_b) = pair.allelic_crossingover(None);
self.godot_genome_a.as_mut().unwrap().bind_mut().set_genome(genome_a);
self.godot_genome_b.as_mut().unwrap().bind_mut().set_genome(genome_b);
godot_print!("Kukayan");
}
else {
godot_error!("Modifier is not initialized!");
}
}
}