sand!!
This commit is contained in:
parent
b62f3a016d
commit
4e850668cd
4 changed files with 273 additions and 10 deletions
39
Cargo.lock
generated
39
Cargo.lock
generated
|
@ -2671,6 +2671,9 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "petri"
|
name = "petri"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"rand",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
|
@ -2732,6 +2735,12 @@ dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "presser"
|
name = "presser"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -2777,6 +2786,36 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "17fd96390ed3feda12e1dfe2645ed587e0bea749e319333f104a33ff62f77a0b"
|
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]]
|
[[package]]
|
||||||
name = "range-alloc"
|
name = "range-alloc"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
|
|
@ -6,3 +6,4 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
rand = "0.8.5"
|
||||||
|
|
206
petri/src/lib.rs
206
petri/src/lib.rs
|
@ -1,14 +1,202 @@
|
||||||
pub fn add(left: usize, right: usize) -> usize {
|
use rand::prelude::*;
|
||||||
left + right
|
|
||||||
|
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)]
|
#[derive(Debug)]
|
||||||
mod tests {
|
pub struct Chunk {
|
||||||
use super::*;
|
pub contents: Box<[[Cell; CHUNK_SIZE]; CHUNK_SIZE]>,
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[derive(Debug)]
|
||||||
fn it_works() {
|
pub struct Rule {
|
||||||
let result = add(2, 2);
|
pub from: RulePattern,
|
||||||
assert_eq!(result, 4);
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,38 @@
|
||||||
|
use petri::{Cell, Dish, CHUNK_SIZE};
|
||||||
|
|
||||||
fn main() {
|
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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue