From 4e850668cda9eccf4e93f49ff95e25e58ced9bb2 Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Mon, 29 Apr 2024 22:44:03 +0200 Subject: [PATCH] sand!! --- Cargo.lock | 39 +++++++++ petri/Cargo.toml | 1 + petri/src/lib.rs | 206 +++++++++++++++++++++++++++++++++++++++++++-- uscope/src/main.rs | 37 +++++++- 4 files changed, 273 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2705818..bf36c49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2671,6 +2671,9 @@ dependencies = [ [[package]] name = "petri" version = "0.1.0" +dependencies = [ + "rand", +] [[package]] name = "pin-project-lite" @@ -2732,6 +2735,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "presser" version = "0.3.1" @@ -2777,6 +2786,36 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17fd96390ed3feda12e1dfe2645ed587e0bea749e319333f104a33ff62f77a0b" +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "range-alloc" version = "0.1.3" diff --git a/petri/Cargo.toml b/petri/Cargo.toml index a026f35..b027842 100644 --- a/petri/Cargo.toml +++ b/petri/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +rand = "0.8.5" diff --git a/petri/src/lib.rs b/petri/src/lib.rs index 06d268d..478f486 100644 --- a/petri/src/lib.rs +++ b/petri/src/lib.rs @@ -1,14 +1,202 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right +use rand::prelude::*; + +pub const CHUNK_SIZE: usize = 32; + +#[derive(Debug, Default, PartialEq, Clone)] +pub struct Cell(u8, u8, u8); + +#[derive(Debug)] +pub struct Pos2(i8, i8); + +#[derive(Debug)] +pub struct Dish { + pub chunk: Chunk, + pub rules: Vec, } -#[cfg(test)] -mod tests { - use super::*; +#[derive(Debug)] +pub struct Chunk { + pub contents: Box<[[Cell; CHUNK_SIZE]; CHUNK_SIZE]>, +} - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); +#[derive(Debug)] +pub struct Rule { + pub from: RulePattern, + pub to: RulePattern, + // probability + // flip + // rotate +} + +impl Chunk { + fn new() -> Self { + Self { + contents: vec![[Cell::EMPTY; CHUNK_SIZE]; CHUNK_SIZE] + .into_boxed_slice() + .try_into() + .unwrap(), + } + } + + fn fill_random(mut self) -> Self { + for col in self.contents.iter_mut() { + for cell in col.iter_mut() { + if random::() % 4 == 0 { + *cell = Cell::WHITE; + } + } + } + self + } + + fn get_cell(&self, x: usize, y: usize) -> Cell { + self.contents[x][y].clone() + } + + fn set_cell(&mut self, x: usize, y: usize, cell: Cell) { + self.contents[x][y] = cell + } +} + +impl Dish { + pub fn new() -> Self { + Self { + chunk: Chunk::new().fill_random(), + rules: vec![ + Rule { + from: RulePattern { + width: 1, + height: 2, + contents: vec![Some(Cell::WHITE), Some(Cell::EMPTY)], + }, + to: RulePattern { + width: 1, + height: 2, + contents: vec![Some(Cell::EMPTY), Some(Cell::WHITE)], + }, + }, + Rule { + from: RulePattern { + width: 2, + height: 2, + contents: vec![ + Some(Cell::WHITE), + Some(Cell::EMPTY), + Some(Cell::WHITE), + Some(Cell::EMPTY), + ], + }, + to: RulePattern { + width: 2, + height: 2, + contents: vec![ + Some(Cell::EMPTY), + Some(Cell::EMPTY), + Some(Cell::WHITE), + Some(Cell::WHITE), + ], + }, + }, + Rule { + from: RulePattern { + width: 2, + height: 2, + contents: vec![ + Some(Cell::EMPTY), + Some(Cell::WHITE), + Some(Cell::EMPTY), + Some(Cell::WHITE), + ], + }, + to: RulePattern { + width: 2, + height: 2, + contents: vec![ + Some(Cell::EMPTY), + Some(Cell::EMPTY), + Some(Cell::WHITE), + Some(Cell::WHITE), + ], + }, + }, + ], + } + } + + pub fn fire_blindly(&mut self) { + assert!(!self.rules.is_empty()); + let x = random::() % CHUNK_SIZE; + let y = random::() % CHUNK_SIZE; + let rule = random::() % self.rules.len(); + // let rule = &self.rules[rule]; + + self.fire_rule(rule, x, y); + } + + fn fire_rule(&mut self, rule_index: usize, x: usize, y: usize) { + let rule = &self.rules[rule_index]; + let width = rule.to.width; + let height = rule.to.height; + // check is match + for dx in 0..width { + for dy in 0..height { + let x = x + dx; + let y = y + dy; + if let Some(rule_cell) = rule.from.get(dx, dy) { + if self.get_cell(x, y) != Some(rule_cell) { + return; + } + } + } + } + for dx in 0..width { + for dy in 0..height { + let x = x + dx; + let y = y + dy; + if let Some(rule_cell) = &self.rules[rule_index].to.get(dx, dy) { + self.set_cell(x, y, rule_cell.clone()); + } + } + } + } + + //todo isize + pub fn get_cell(&self, x: usize, y: usize) -> Option { + if x >= CHUNK_SIZE || y >= CHUNK_SIZE { + None + } else { + Some(self.chunk.get_cell(x, y)) + } + } + + //todo isize + pub fn set_cell(&mut self, x: usize, y: usize, cell: Cell) { + if x >= CHUNK_SIZE || y >= CHUNK_SIZE { + return; + } + self.chunk.set_cell(x, y, cell) + } +} + +impl Cell { + pub const EMPTY: Self = Self(0, 0, 0); + pub const WHITE: Self = Self(255, 255, 255); +} + +#[derive(Debug)] +pub struct RulePattern { + width: usize, + height: usize, + contents: Vec>, +} + +impl RulePattern { + fn get(&self, x: usize, y: usize) -> Option { + if x >= self.width || y >= self.height { + None + } else { + // dbg!(x, y); + self.contents[x + self.width * y].clone() + } } } diff --git a/uscope/src/main.rs b/uscope/src/main.rs index a30eb95..cd8bee1 100644 --- a/uscope/src/main.rs +++ b/uscope/src/main.rs @@ -1,3 +1,38 @@ +use petri::{Cell, Dish, CHUNK_SIZE}; + fn main() { - println!("Hello, world!"); + let mut dish = Dish::new(); + loop { + for _ in 0..1000 { + dish.fire_blindly(); + } + print_dish(&dish); + wait_for_input() + } +} + +fn print_dish(dish: &Dish) { + for y in 0..(CHUNK_SIZE / 2) { + for x in 0..CHUNK_SIZE { + render_pixel_pair(dish, x, y); + } + println!(); + } + println!(); +} + +fn render_pixel_pair(dish: &Dish, x: usize, y: usize) { + let a = dish.get_cell(x, y * 2) != Some(Cell::EMPTY); + let b = dish.get_cell(x, y * 2 + 1) != Some(Cell::EMPTY); + let char = match (a, b) { + (false, false) => " ", + (false, true) => "▄", + (true, false) => "▀", + (true, true) => "█", + }; + print!("{}", char); +} + +pub fn wait_for_input() { + std::io::stdin().read_line(&mut String::new()).unwrap(); }