This commit is contained in:
Crispy 2024-04-29 22:44:03 +02:00
parent b62f3a016d
commit 4e850668cd
4 changed files with 273 additions and 10 deletions

39
Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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<Rule>,
}
#[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::<u8>() % 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::<usize>() % CHUNK_SIZE;
let y = random::<usize>() % CHUNK_SIZE;
let rule = random::<usize>() % 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<Cell> {
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<Option<Cell>>,
}
impl RulePattern {
fn get(&self, x: usize, y: usize) -> Option<Cell> {
if x >= self.width || y >= self.height {
None
} else {
// dbg!(x, y);
self.contents[x + self.width * y].clone()
}
}
}

View file

@ -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();
}