subplate works
This commit is contained in:
Generated
+40
@@ -2127,6 +2127,25 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.12"
|
||||
@@ -4098,6 +4117,26 @@ version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "read-fonts"
|
||||
version = "0.36.0"
|
||||
@@ -4607,6 +4646,7 @@ dependencies = [
|
||||
"bevy",
|
||||
"rand 0.10.1",
|
||||
"rand_chacha 0.10.0",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -7,3 +7,4 @@ edition = "2024"
|
||||
bevy = { version = "0.18.1", features = ["keyboard"] }
|
||||
rand = "0.10.1"
|
||||
rand_chacha = "0.10.0"
|
||||
rayon = "1.12.0"
|
||||
+36
-2
@@ -30,7 +30,7 @@ impl<T: Clone> Table<T> {
|
||||
&self.data[index]
|
||||
}
|
||||
|
||||
fn get_dim(&mut self, x: usize, y: usize) -> &T {
|
||||
fn get_dim(&self, x: usize, y: usize) -> &T {
|
||||
self.get(x + y * self.side)
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ impl<T: Clone> Table<T> {
|
||||
self.side = new_side;
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &T> {
|
||||
pub fn iter(&self) -> impl Iterator<Item=&T> {
|
||||
self.data.iter()
|
||||
}
|
||||
|
||||
@@ -69,6 +69,23 @@ impl<T: Clone> Table<T> {
|
||||
table.data[i] = f(self[i].clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn around_line(&self, index: usize) -> Vec<&T> {
|
||||
self.around(index % self.side, index / self.side)
|
||||
}
|
||||
|
||||
|
||||
pub fn around(&self, x: usize, y: usize) -> Vec<&T> {
|
||||
let coordinates = vec![
|
||||
(x as isize, y as isize - 1),
|
||||
(x as isize, y as isize + 1),
|
||||
(x as isize + 1, y as isize),
|
||||
(x as isize - 1, y as isize),
|
||||
];
|
||||
coordinates.iter().filter(|(x, y)| {
|
||||
*x >= 0 && *x < self.side as isize && *y >= 0 && *y < self.side as isize
|
||||
}).map(|(x, y)| self.get_dim(*x as usize, *y as usize)).collect::<Vec<_>>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Into<Vec<T>> for Table<T> {
|
||||
@@ -99,6 +116,23 @@ impl IntoImage for Table<bool> {
|
||||
data
|
||||
}
|
||||
}
|
||||
impl IntoImage for Table<Color> {
|
||||
fn get_image_data(&self) -> Vec<u8> {
|
||||
let mut data: Vec<u8> = vec![0; self.side * self.side * 4];
|
||||
self.data
|
||||
.iter()
|
||||
.zip((0..self.data.len()).collect::<Vec<_>>())
|
||||
.for_each(|(color, idx)| {
|
||||
let idx = idx * 4;
|
||||
let color = color.to_linear();
|
||||
data[idx] = (color.red * 255.0) as u8;
|
||||
data[idx + 1] = (color.green * 255.0) as u8;
|
||||
data[idx + 2] = (color.blue * 255.0) as u8;
|
||||
data[idx + 3] = 255;
|
||||
});
|
||||
data
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Index<usize> for Table<T> {
|
||||
type Output = T;
|
||||
|
||||
+63
-29
@@ -1,28 +1,38 @@
|
||||
mod basic;
|
||||
mod seed_automation;
|
||||
mod plate_automation;
|
||||
mod subplate_automation;
|
||||
|
||||
use crate::basic::{IntoImage, Table};
|
||||
use bevy::asset::io::embedded::GetAssetServer;
|
||||
use bevy::input::keyboard::keyboard_input_system;
|
||||
use bevy::prelude::*;
|
||||
use bevy::window::{ExitCondition, WindowResolution};
|
||||
use rand::{Rng, RngExt};
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
use rand_chacha::rand_core::SeedableRng;
|
||||
use seed_automation::SeedAutomation;
|
||||
|
||||
const RECTANGLE_SIDE: f32 = 500.0;
|
||||
const RECTANGLE_SIDE: f32 = 750.0;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||
primary_window: Some(Window {
|
||||
title: "Automations".into(),
|
||||
resolution: WindowResolution::new(RECTANGLE_SIDE as u32, RECTANGLE_SIDE as u32),
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
}))
|
||||
.add_systems(Startup, setup)
|
||||
.insert_resource(Time::<Fixed>::from_hz(1024.0))
|
||||
// .add_systems(Update, automation_keyboard_input_system)
|
||||
.add_systems(Update, seed_automation::update_automation_seed)
|
||||
.add_systems(Update, seed_automation::update_automation_view_seed)
|
||||
.add_systems(Update, plate_automation::update_automation_plate)
|
||||
.add_systems(Update, plate_automation::update_automation_view_plate)
|
||||
.add_systems(Update, seed_automation::update_automation)
|
||||
.add_systems(Update, seed_automation::update_automation_view)
|
||||
.add_systems(Update, plate_automation::update_automation)
|
||||
.add_systems(Update, plate_automation::update_automation_view)
|
||||
.add_systems(Update, subplate_automation::update_automation)
|
||||
.add_systems(Update, subplate_automation::update_automation_view)
|
||||
.run();
|
||||
}
|
||||
|
||||
@@ -44,27 +54,51 @@ fn setup(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
|
||||
commands.insert_resource(SeededRng(seeded_rng));
|
||||
}
|
||||
|
||||
// fn automation_keyboard_input_system(keys: Res<ButtonInput<KeyCode>>, mut commands: Commands) {
|
||||
// if keys.just_pressed(KeyCode::Space) {
|
||||
// commands.spawn((AutomationNext,));
|
||||
// }
|
||||
//
|
||||
// if keys.just_pressed(KeyCode::Tab) {
|
||||
// commands.spawn((AutomationMigrate,));
|
||||
// }
|
||||
//
|
||||
// if keys.just_pressed(KeyCode::AltLeft) {
|
||||
// commands.spawn((AutomationScale,));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// #[derive(Component)]
|
||||
// struct AutomationNext;
|
||||
//
|
||||
// #[derive(Component)]
|
||||
// struct AutomationScale;
|
||||
//
|
||||
// #[derive(Component)]
|
||||
// struct AutomationMigrate;
|
||||
#[derive(Resource)]
|
||||
struct SeededRng(ChaCha8Rng);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::basic::Table;
|
||||
|
||||
#[test]
|
||||
fn around_1(){
|
||||
let mut table = Table::new(false, 16);
|
||||
let around = table.around(0, 0);
|
||||
assert_eq!(around.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn around_2(){
|
||||
let mut table = Table::new(false, 16);
|
||||
let around = table.around(15, 15);
|
||||
assert_eq!(around.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn around_3(){
|
||||
let mut table = Table::new(false, 16);
|
||||
let around = table.around(5, 5);
|
||||
assert_eq!(around.len(), 4);
|
||||
}
|
||||
#[test]
|
||||
fn around_1_line(){
|
||||
let mut table = Table::new(false, 16);
|
||||
let around = table.around_line(0);
|
||||
assert_eq!(around.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn around_2_line(){
|
||||
let mut table = Table::new(false, 16);
|
||||
let around = table.around_line(16 * 16 - 1);
|
||||
assert_eq!(around.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn around_3_line(){
|
||||
let mut table = Table::new(false, 16);
|
||||
let around = table.around_line(24);
|
||||
assert_eq!(around.len(), 4);
|
||||
}
|
||||
}
|
||||
+35
-7
@@ -3,12 +3,14 @@ use crate::basic::{IntoImage, Table};
|
||||
use bevy::asset::{Assets, RenderAssetUsages};
|
||||
use bevy::image::{BevyDefault, Image};
|
||||
use bevy::input::ButtonInput;
|
||||
use bevy::prelude::{Component, KeyCode, Query, Res, ResMut, Sprite};
|
||||
use bevy::prelude::{Color, Commands, Component, Entity, KeyCode, Query, Res, ResMut, Sprite};
|
||||
use bevy::render::render_resource::{Extent3d, TextureDimension, TextureFormat};
|
||||
use rand::RngExt;
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
use crate::seed_automation::SeedAutomation;
|
||||
use crate::subplate_automation::SubPlateAutomation;
|
||||
|
||||
pub fn update_automation_view_plate(
|
||||
pub fn update_automation_view(
|
||||
query: Query<(&Sprite, &PlateAutomation)>,
|
||||
mut images: ResMut<Assets<Image>>,
|
||||
) {
|
||||
@@ -34,17 +36,18 @@ pub fn update_automation_view_plate(
|
||||
images.insert(sprite.image.id(), image).unwrap();
|
||||
}
|
||||
|
||||
pub fn update_automation_plate(
|
||||
mut query: Query<&mut PlateAutomation>,
|
||||
pub fn update_automation(
|
||||
mut query: Query<(&mut PlateAutomation, Entity)>,
|
||||
mut seeded_rng: ResMut<SeededRng>,
|
||||
keys: Res<ButtonInput<KeyCode>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
if query.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut automation = query.iter_mut().next().unwrap();
|
||||
if keys.just_pressed(KeyCode::Space) {
|
||||
let (mut automation, entity) = query.iter_mut().next().unwrap();
|
||||
if keys.just_pressed(KeyCode::Space) || keys.all_pressed([KeyCode::Space, KeyCode::ShiftLeft]) {
|
||||
let random = &mut seeded_rng.0;
|
||||
|
||||
automation.next(random)
|
||||
@@ -53,6 +56,15 @@ pub fn update_automation_plate(
|
||||
if keys.just_pressed(KeyCode::AltLeft) {
|
||||
automation.world.grow()
|
||||
}
|
||||
|
||||
if keys.just_pressed(KeyCode::Tab) {
|
||||
println!("Switching to SubPlateAutomation");
|
||||
let mut new_table = Table::<Color>::new(Color::BLACK, automation.world.side);
|
||||
automation.world.convert_copy(&mut new_table, |value| { if value { Color::WHITE } else { Color::BLACK } });
|
||||
commands.entity(entity).remove::<PlateAutomation>().insert(SubPlateAutomation{
|
||||
world: new_table
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
@@ -62,6 +74,22 @@ pub struct PlateAutomation {
|
||||
|
||||
impl PlateAutomation {
|
||||
fn next(&mut self, rng: &mut ChaCha8Rng) {
|
||||
println!("Next for plate automation");
|
||||
for index in 0..self.world.side * self.world.side {
|
||||
if *self.world.get(index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let around = self.world.around_line(index).iter().filter(|v| ***v).count();
|
||||
|
||||
if around == 0 {
|
||||
continue;
|
||||
}
|
||||
let chance = (around as f32 * 0.2).powi(2);
|
||||
if rng.random::<f32>() > chance {
|
||||
continue;
|
||||
}
|
||||
|
||||
self.world.set(index, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use rand::RngExt;
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
use crate::plate_automation::PlateAutomation;
|
||||
|
||||
pub fn update_automation_view_seed(
|
||||
pub fn update_automation_view(
|
||||
query: Query<(&Sprite, &SeedAutomation)>,
|
||||
mut images: ResMut<Assets<Image>>,
|
||||
) {
|
||||
@@ -36,7 +36,7 @@ pub fn update_automation_view_seed(
|
||||
images.insert(sprite.image.id(), image).unwrap();
|
||||
}
|
||||
|
||||
pub fn update_automation_seed(
|
||||
pub fn update_automation(
|
||||
mut query: Query<(&mut SeedAutomation, Entity)>,
|
||||
mut seeded_rng: ResMut<SeededRng>,
|
||||
keys: Res<ButtonInput<KeyCode>>,
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
use crate::SeededRng;
|
||||
use crate::basic::{IntoImage, Table};
|
||||
use bevy::asset::{Assets, RenderAssetUsages};
|
||||
use bevy::image::{BevyDefault, Image};
|
||||
use bevy::input::ButtonInput;
|
||||
use bevy::prelude::{Color, Commands, Component, Entity, KeyCode, Query, Res, ResMut, Sprite};
|
||||
use bevy::render::render_resource::{Extent3d, TextureDimension, TextureFormat};
|
||||
use rand::{ RngExt};
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
|
||||
pub fn update_automation_view(
|
||||
query: Query<(&Sprite, &SubPlateAutomation)>,
|
||||
mut images: ResMut<Assets<Image>>,
|
||||
) {
|
||||
if query.is_empty() {
|
||||
return;
|
||||
}
|
||||
let (sprite, automation) = query.iter().next().unwrap();
|
||||
let size = automation.world.side as u32;
|
||||
let data = automation.world.get_image_data();
|
||||
let image = Image::new(
|
||||
Extent3d {
|
||||
width: size,
|
||||
height: size,
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
TextureDimension::D2,
|
||||
data,
|
||||
TextureFormat::bevy_default(),
|
||||
RenderAssetUsages::default(),
|
||||
);
|
||||
|
||||
images.remove(sprite.image.id());
|
||||
images.insert(sprite.image.id(), image).unwrap();
|
||||
}
|
||||
|
||||
pub fn update_automation(
|
||||
mut query: Query<(&mut SubPlateAutomation, Entity)>,
|
||||
mut seeded_rng: ResMut<SeededRng>,
|
||||
keys: Res<ButtonInput<KeyCode>>,
|
||||
commands: Commands,
|
||||
|
||||
) {
|
||||
if query.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let (mut automation, entity) = query.iter_mut().next().unwrap();
|
||||
if keys.just_pressed(KeyCode::Space) || keys.all_pressed([KeyCode::Space, KeyCode::ShiftLeft]) {
|
||||
let random = &mut seeded_rng.0;
|
||||
|
||||
automation.next(random)
|
||||
}
|
||||
|
||||
if keys.just_pressed(KeyCode::AltLeft) {
|
||||
let random = &mut seeded_rng.0;
|
||||
|
||||
automation.seed(random);
|
||||
}
|
||||
|
||||
if keys.just_pressed(KeyCode::Tab) {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct SubPlateAutomation {
|
||||
pub(crate) world: Table<Color>,
|
||||
}
|
||||
|
||||
impl SubPlateAutomation {
|
||||
fn next(&mut self, rng: &mut ChaCha8Rng) {
|
||||
for index in 0..self.world.side * self.world.side {
|
||||
let current_color = *self.world.get(index);
|
||||
if current_color == Color::BLACK || current_color != Color::WHITE {
|
||||
continue;
|
||||
}
|
||||
|
||||
if rng.random::<f32>() < 0.7 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let around = self.world.around_line(index).iter().filter(|v| ***v != Color::WHITE && ***v != Color::BLACK).map(|color| (*color).clone()).collect::<Vec<_>>();
|
||||
|
||||
if around.len() == 0 {
|
||||
continue;
|
||||
}
|
||||
let color = around[rng.random_range(0..around.len())];
|
||||
|
||||
|
||||
self.world.set(index, color);
|
||||
}
|
||||
}
|
||||
|
||||
fn seed(&mut self, rng: &mut ChaCha8Rng){
|
||||
let len = (self.world.side * self.world.side) as f32;
|
||||
loop {
|
||||
let index = (rng.random::<f32>() * len) as usize;
|
||||
if *self.world.get(index) == Color::BLACK {
|
||||
continue;
|
||||
}
|
||||
|
||||
self.world.set(index, Color::hsv(rng.random::<f32>() * 360.0, 1.0, 1.0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user