Compare commits
2 Commits
ef52c604d1
...
09f8c2a49d
| Author | SHA1 | Date |
|---|---|---|
|
|
09f8c2a49d | 2 years ago |
|
|
ef8bbe0c55 | 2 years ago |
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,145 @@
|
|||||||
|
|
||||||
|
use bevy::{
|
||||||
|
prelude::*,
|
||||||
|
diagnostic::{FrameTimeDiagnosticsPlugin, DiagnosticsStore},
|
||||||
|
window::{PresentMode, WindowTheme},
|
||||||
|
sprite::MaterialMesh2dBundle};
|
||||||
|
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
mod neural_net;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
struct Agent;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
struct FpsText;
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
struct SimulationState
|
||||||
|
{
|
||||||
|
generation: i32,
|
||||||
|
generation_step: i32,
|
||||||
|
max_gen_steps: i32,
|
||||||
|
|
||||||
|
last_step_time: f32,
|
||||||
|
last_gen_time: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SimulationState
|
||||||
|
{
|
||||||
|
fn new(steps_per_gen: i32) -> SimulationState
|
||||||
|
{
|
||||||
|
SimulationState { generation: (1), generation_step: (0), max_gen_steps: steps_per_gen, last_step_time: 0.0, last_gen_time: 0.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main()
|
fn main()
|
||||||
{
|
{
|
||||||
println!("Hello, world!");
|
App::new()
|
||||||
|
.add_plugins((
|
||||||
|
DefaultPlugins.set(WindowPlugin {
|
||||||
|
primary_window: Some(Window {
|
||||||
|
title: "Life Sim".into(),
|
||||||
|
resolution: (1280., 720.).into(),
|
||||||
|
present_mode: PresentMode::AutoVsync,
|
||||||
|
// Tells wasm to resize the window according to the available canvas
|
||||||
|
fit_canvas_to_parent: true,
|
||||||
|
// Tells wasm not to override default event handling, like F5, Ctrl+R etc.
|
||||||
|
prevent_default_event_handling: false,
|
||||||
|
window_theme: Some(WindowTheme::Dark),
|
||||||
|
..default()
|
||||||
|
}),
|
||||||
|
..default()
|
||||||
|
}),
|
||||||
|
FrameTimeDiagnosticsPlugin
|
||||||
|
))
|
||||||
|
.insert_resource(SimulationState::new(200))
|
||||||
|
.insert_resource(Time::new(Instant::now()))
|
||||||
|
.add_systems(Startup, setup)
|
||||||
|
.add_systems(Update, (tick_simulation, ui_update))
|
||||||
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<ColorMaterial>>)
|
||||||
|
{
|
||||||
|
// Camera
|
||||||
|
commands.spawn(Camera2dBundle::default());
|
||||||
|
|
||||||
|
// Circle
|
||||||
|
commands.spawn((
|
||||||
|
MaterialMesh2dBundle {
|
||||||
|
mesh: meshes.add(shape::Circle::new(50.).into()).into(),
|
||||||
|
material: materials.add(ColorMaterial::from(Color::PURPLE)),
|
||||||
|
transform: Transform::from_translation(Vec3::new(-150., 0., 0.)),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
Agent
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
// UI
|
||||||
|
// Text with multiple sections
|
||||||
|
commands.spawn((
|
||||||
|
// Create a TextBundle that has a Text with a list of sections.
|
||||||
|
TextBundle::from_sections([
|
||||||
|
TextSection::new(
|
||||||
|
"FPS: ",
|
||||||
|
TextStyle {
|
||||||
|
font_size: 60.0,
|
||||||
|
color: Color::WHITE,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextSection::from_style(TextStyle {
|
||||||
|
font_size: 60.0,
|
||||||
|
color: Color::GOLD,
|
||||||
|
..default()
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
FpsText,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tick_simulation(mut state: ResMut<SimulationState>, delta_time: Res<Time>, mut query: Query<&mut Transform, With<Agent>>)
|
||||||
|
{
|
||||||
|
let now = Instant::now();
|
||||||
|
|
||||||
|
// Update neural net inputs
|
||||||
|
|
||||||
|
// Tick the neural net
|
||||||
|
|
||||||
|
// Process agent actions
|
||||||
|
let mut agent_transform = query.single_mut();
|
||||||
|
|
||||||
|
agent_transform.translation.x += 50.0 * delta_time.delta_seconds();
|
||||||
|
|
||||||
|
let elapsed_time = now.elapsed();
|
||||||
|
state.last_gen_time += state.last_step_time;
|
||||||
|
state.last_step_time = elapsed_time.as_secs_f32();
|
||||||
|
state.generation_step += 1;
|
||||||
|
|
||||||
|
if state.generation_step >= state.max_gen_steps
|
||||||
|
{
|
||||||
|
// Move on to the next generation
|
||||||
|
state.generation += 1;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ui_update(mut state: Res<SimulationState>, diagnostics: Res<DiagnosticsStore>, mut query: Query<&mut Text, With<FpsText>>)
|
||||||
|
{
|
||||||
|
for mut text in &mut query
|
||||||
|
{
|
||||||
|
if let Some(fps) = diagnostics.get(FrameTimeDiagnosticsPlugin::FPS)
|
||||||
|
{
|
||||||
|
if let Some(value) = fps.smoothed()
|
||||||
|
{
|
||||||
|
// Update the value of the second section
|
||||||
|
text.sections[1].value = format!("{value:.2}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
pub enum InputNeuron
|
||||||
|
{
|
||||||
|
Position((i32, i32)), // Position on the world grid
|
||||||
|
Age(i32), // Age is the number of steps since the start of the generation
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue