#Params are moved, any solution ?
20 messages · Page 1 of 1 (latest)
make your functions take params by reference (&)
solution might be to pass information from system to system with ressources maybe
i tried but commands cannot be deferenced
can you post your function declarations?
ofc
!
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
Ah yeah, you need to pass a mutable reference for Commands. So mut commands: &mut Commands.
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