#Params are moved, any solution ?

20 messages · Page 1 of 1 (latest)

hard swift
#

please welp

cosmic musk
#

make your functions take params by reference (&)

hard swift
#

solution might be to pass information from system to system with ressources maybe

hard swift
cosmic musk
#

can you post your function declarations?

hard swift
#

!

#
fn spawn_population(mut commands: &Commands, mut meshes: &ResMut<Assets<Mesh>>, mut materials: &ResMut<Assets<ColorMaterial>>, population: &[Genome]) {

    let mut rng = rand::thread_rng();

    for genome in population.iter() {
        let color = genetics::determine_color(&genome);


        let shape = meshes.add(Circle::new(5.0));
        let color = Color::from(color);

        let x = rng.gen_range(- params::WIDTH / 2.0..params::WIDTH / 2.0);
        let y = rng.gen_range(- params::HEIGHT / 2.0..params::HEIGHT / 2.0);

        commands.spawn((
            Bacterium {genome: *genome, ..default()},
            Mesh2d(shape),
            MeshMaterial2d(materials.add(color)),
            Transform::from_xyz(x, y,0.0),
        ));
    }
}
#
fn update_generation(
    mut commands: Commands,
    time: Res<Time>,
    mut generation_timer: ResMut<GenerationTimer>,
    mut generation_count: ResMut<GenerationCount>,
    bacterium : Query<(Entity, &Bacterium)>,
    // food : Query<Entity, With<Food>>,
    meshes: ResMut<Assets<Mesh>>,
    materials: ResMut<Assets<ColorMaterial>>
) {
    generation_timer.0.tick(time.delta());
    if generation_timer.0.finished() {
        println!("Génération {} terminée, évolution en cours..", generation_count.0);
        let mut pop_with_fitness = Vec::new();
        for (e, b) in bacterium.iter() {
            let fit = calculate_fitness(&b.genome);
            pop_with_fitness.push((b.genome, fit, e));
        }

        // On trie par fitness pour information (non obligatoire)
        pop_with_fitness.sort_by(|a,b| b.1.partial_cmp(&a.1).unwrap());

        // Sélection de l’élite + roulette wheel (exemple simplifié)
        let elite_count = (POPULATION_SIZE as f64 * 0.1) as usize;
        let mut new_population = Vec::new();

        // On garde l’élite telle quelle (juste leurs génomes)
        for i in 0..elite_count {
            new_population.push(pop_with_fitness[i].0);
        }

        // On sélectionne le reste par roulette
        let parents = roulette_wheel_selection(&pop_with_fitness.iter().map(|(g,f,_)| (*g, *f)).collect::<Vec<_>>(), POPULATION_SIZE - elite_count);

        // On applique crossover et mutation
        let mut rng = rand::thread_rng();
        let mut parent_pool = parents;
        if parent_pool.len() % 2 != 0 {
            // Si impair, on ajoute un individu random
            parent_pool.push(pop_with_fitness[rng.gen_range(0..pop_with_fitness.len())].0);
        }
        for pair in parent_pool.chunks(2) {
            let p1 = pair[0];
            let p2 = pair[1];
            let (mut c1, mut c2) = random_crossover(&p1, &p2);

            mutate(&mut c1);
            mutate(&mut c2);

            if new_population.len() < POPULATION_SIZE {
                new_population.push(c1);
            }
            if new_population.len() < POPULATION_SIZE {
                new_population.push(c2);
            }
        }

        // On supprime l'ancienne population
        for (_,_,e) in pop_with_fitness {
            commands.entity(e).despawn();
        }

        // for e in food.iter() {
        //     commands.entity(e).despawn();
        // }

        // On spawn la nouvelle population
        spawn_population(&commands, &meshes, &materials, &new_population);
        spawn_food(commands, meshes, materials);

        generation_count.0 += 1;
        println!("Nouvelle génération : {}", generation_count.0);
    }
}
#
pub fn spawn_food(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>
) {
    let mut rng = rand::thread_rng();

    for _ in 0..NUMBER_SPAWNED_FOOD {
        let mesh = meshes.add(Rectangle::new(2.5, 2.5));
        let x = rng.gen_range(-WIDTH/2.0..WIDTH/2.0);
        let y = rng.gen_range(-HEIGHT/2.0..HEIGHT/2.0);

        commands.spawn((
            Food::default(),
            Mesh2d(mesh),
            MeshMaterial2d(materials.add(Color::WHITE)),
            Transform::from_xyz (x, y, 0.0)
        ));
    }
}```
#

i'm in 0.15

cosmic musk
#

Ah yeah, you need to pass a mutable reference for Commands. So mut commands: &mut Commands.

hard swift
#

oh let me try this!

#
fn update_generation(
    mut commands: &mut Commands,
    time: Res<Time>,
    mut generation_timer: ResMut<GenerationTimer>,
    mut generation_count: ResMut<GenerationCount>,
    bacterium : Query<(Entity, &Bacterium)>,
    food : Query<Entity, With<Food>>,
    mut meshes: &mut ResMut<Assets<Mesh>>,
    mut materials: &mut ResMut<Assets<ColorMaterial>>
) {
    generation_timer.0.tick(time.delta());
    if generation_timer.0.finished() {
        println!("Génération {} terminée, évolution en cours..", generation_count.0);
        let mut pop_with_fitness = Vec::new();
        for (e, b) in bacterium.iter() {
            let fit = calculate_fitness(&b.genome);
            pop_with_fitness.push((b.genome, fit, e));
        }

        // On trie par fitness pour information (non obligatoire)
        pop_with_fitness.sort_by(|a,b| b.1.partial_cmp(&a.1).unwrap());

        // Sélection de l’élite + roulette wheel (exemple simplifié)
        let elite_count = (POPULATION_SIZE as f64 * 0.1) as usize;
        let mut new_population = Vec::new();

        // On garde l’élite telle quelle (juste leurs génomes)
        for i in 0..elite_count {
            new_population.push(pop_with_fitness[i].0);
        }

        // On sélectionne le reste par roulette
        let parents = roulette_wheel_selection(&pop_with_fitness.iter().map(|(g,f,_)| (*g, *f)).collect::<Vec<_>>(), POPULATION_SIZE - elite_count);

        // On applique crossover et mutation
        let mut rng = rand::thread_rng();
        let mut parent_pool = parents;
        if parent_pool.len() % 2 != 0 {
            // Si impair, on ajoute un individu random
            parent_pool.push(pop_with_fitness[rng.gen_range(0..pop_with_fitness.len())].0);
        }
        for pair in parent_pool.chunks(2) {
            let p1 = pair[0];
            let p2 = pair[1];
            let (mut c1, mut c2) = random_crossover(&p1, &p2);

            mutate(&mut c1);
            mutate(&mut c2);

            if new_population.len() < POPULATION_SIZE {
                new_population.push(c1);
            }
            if new_population.len() < POPULATION_SIZE {
                new_population.push(c2);
            }
        }

        // On supprime l'ancienne population
        for (_,_,e) in pop_with_fitness {
            commands.entity(e).despawn();
        }

        for e in food.iter() {
            commands.entity(e).despawn();
        }

        // On spawn la nouvelle population
        spawn_population(&mut commands, &mut meshes, &mut materials, &new_population);
        spawn_food(&mut commands, &mut meshes, &mut materials);

        generation_count.0 += 1;
        println!("Nouvelle génération : {}", generation_count.0);
    }
}```
#

that doesn't work, maybe i wrote it wrong

#
pub fn spawn_population(mut commands: &mut Commands, mut meshes: &mut ResMut<Assets<Mesh>>, mut materials: &mut ResMut<Assets<ColorMaterial>>, population: &[Genome]) {

    let mut rng = rand::thread_rng();

    for genome in population.iter() {
        let color = genetics::determine_color(&genome);


        let shape = meshes.add(Circle::new(5.0));
        let color = Color::from(color);

        let x = rng.gen_range(- params::WIDTH / 2.0..params::WIDTH / 2.0);
        let y = rng.gen_range(- params::HEIGHT / 2.0..params::HEIGHT / 2.0);

        commands.spawn((
            Bacterium {genome: *genome, ..default()},
            Mesh2d(shape),
            MeshMaterial2d(materials.add(color)),
            Transform::from_xyz(x, y,0.0),
        ));
    }
}

pub fn spawn_food(
    mut commands: &mut Commands,
    mut meshes: &mut ResMut<Assets<Mesh>>,
    mut materials: &mut ResMut<Assets<ColorMaterial>>
) {
    let mut rng = rand::thread_rng();

    for _ in 0..NUMBER_SPAWNED_FOOD {
        let mesh = meshes.add(Rectangle::new(2.5, 2.5));
        let x = rng.gen_range(-WIDTH/2.0..WIDTH/2.0);
        let y = rng.gen_range(-HEIGHT/2.0..HEIGHT/2.0);

        commands.spawn((
            Food::default(),
            Mesh2d(mesh),
            MeshMaterial2d(materials.add(Color::WHITE)),
            Transform::from_xyz (x, y, 0.0)
        ));
    }
}```
#

error[E0277]: fn(&mut Commands<'b, 'c>, Res<'d, Time>, ResMut<'e, ...>, ..., ..., ..., ..., ...) {update_generation} does not describe a valid system configuration
--> src/main.rs:134:33
|
134 | app.add_systems(Update, update_generation);
| ----------- ^^^^^^^^^^^^^^^^^ invalid system configuration
| |
| required by a bound introduced by this call
|
= note: the full name for the type has been written to '/Users/teddy/Documents/Coding/bacteria/target/debug/deps/bacteria-b0fa7f04acfe50a3.long-type-9656311926707614494.txt'
= note: consider using --verbose to print the full type name to the console
= help: the trait bevy::prelude::IntoSystem<(), (), _> is not implemented for fn item fn(&mut Commands<'b, 'c>, Res<'d, Time>, ResMut<'e, ...>, ..., ..., ..., ..., ...) {update_generation}, which is required by for<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o> fn(&'a mut bevy::prelude::Commands<'b, 'c>, bevy::prelude::Res<'d, bevy::prelude::Time>, bevy::prelude::ResMut<'e, GenerationTimer>, bevy::prelude::ResMut<'f, GenerationCount>, bevy::prelude::Query<'g, 'h, (bevy::prelude::Entity, &'i Bacterium)>, bevy::prelude::Query<'j, 'k, bevy::prelude::Entity, bevy::prelude::With<Food>>, &'l mut bevy::prelude::ResMut<'m, bevy::prelude::Assets<bevy::prelude::Mesh>>, &'n mut bevy::prelude::ResMut<'o, bevy::prelude::Assets<bevy::prelude::ColorMaterial>>) {update_generation}: IntoSystemConfigs<_>
= help: the following other types implement trait bevy::prelude::IntoSystem<In, Out, Marker>:
IntoAdapterSystem<Func, S> implements bevy::prelude::IntoSystem<<Func as Adapt<<S as bevy::prelude::IntoSystem<I, O, M>>::System>>::In, <Func as Adapt<<S as bevy::prelude::IntoSystem<I, O, M>>::System>>::Out, (IsAdapterSystemMarker, I, O, M)>
IntoPipeSystem<A, B> implements bevy::prelude::IntoSystem<IA, OB, (IsPipeSystemMarker, OA, IB, MA, MB)>
= note: required for fn(&mut Commands<'b, 'c>, Res<'d, Time>, ResMut<'e, ...>, ..., ..., ..., ..., ...) {update_generation} to implement IntoSystemConfigs<_>
note: required by a bound in bevy::prelude::App::add_systems

#

nvm

#

i'm making it too complex

#

i can do 1000x simpler