Skip to content

Commit a294909

Browse files
committed
draw stuff
1 parent 9910784 commit a294909

File tree

3 files changed

+163
-83
lines changed

3 files changed

+163
-83
lines changed

Cargo.toml

+15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ default = ["console_error_panic_hook"]
1212

1313
[dependencies]
1414
wasm-bindgen = "0.2.63"
15+
js-sys = "0.3.19"
16+
rand_xoshiro = "0.6.0"
17+
rand = "0.8.3"
1518

1619
# The `console_error_panic_hook` crate provides better debugging of panics by
1720
# logging them with `console.error`. This is great for development, but requires
@@ -32,3 +35,15 @@ wasm-bindgen-test = "0.3.13"
3235
[profile.release]
3336
# Tell `rustc` to optimize for small code size.
3437
opt-level = "s"
38+
39+
40+
[dependencies.getrandom]
41+
features = [
42+
"js",
43+
]
44+
45+
[dependencies.web-sys]
46+
version = "0.3"
47+
features = [
48+
"console",
49+
]

src/lib.rs

+121-83
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,80 @@
1+
extern crate js_sys;
2+
extern crate web_sys;
3+
4+
mod species;
15
mod utils;
26

7+
use rand::{Rng, SeedableRng};
8+
use rand_xoshiro::SplitMix64;
9+
use species::Species;
310
use wasm_bindgen::prelude::*;
411

5-
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
6-
// allocator.
7-
#[cfg(feature = "wee_alloc")]
8-
#[global_allocator]
9-
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
10-
11-
// #[wasm_bindgen]
12-
// extern "C" {
13-
// fn alert(s: &str);
14-
// }
15-
16-
// #[wasm_bindgen]
17-
// pub fn greet(name: &str) {
18-
// alert(&format!("Hello, {}!", name));
19-
// }
12+
// A macro to provide `println!(..)`-style syntax for `console.log` logging.
13+
macro_rules! log {
14+
( $( $t:tt )* ) => {
15+
web_sys::console::log_1(&format!( $( $t )* ).into());
16+
}
17+
}
2018

2119
#[wasm_bindgen]
22-
#[repr(u8)]
20+
#[repr(C)]
2321
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24-
pub enum Cell {
25-
Dead = 0,
26-
Alive = 1,
22+
pub struct Cell {
23+
species: Species,
24+
ra: u8,
25+
rb: u8,
26+
clock: u8,
2727
}
2828

2929
#[wasm_bindgen]
3030
pub struct Universe {
31-
width: u32,
32-
height: u32,
31+
width: i32,
32+
height: i32,
3333
cells: Vec<Cell>,
34+
rng: SplitMix64,
35+
generation: u8,
36+
}
37+
38+
// impl Cell {
39+
// fn toggle(&mut self) {
40+
// *self = match *self {
41+
// Cell::Dead => Cell::Alive,
42+
// Cell::Alive => Cell::Dead,
43+
// }
44+
// }
45+
// }
46+
47+
impl Cell {
48+
pub unsafe fn new(species: Species) -> Cell {
49+
Cell {
50+
species: species,
51+
ra: 1,
52+
// ra: 100 + (js_sys::Math::random() * 50.) as u8,
53+
rb: 0,
54+
clock: 0,
55+
}
56+
}
57+
// pub fn update(&self, api: SandApi) {
58+
// self.species.update(*self, api);
59+
// }
3460
}
3561

62+
static EMPTY_CELL: Cell = Cell {
63+
species: Species::Empty,
64+
ra: 0,
65+
rb: 0,
66+
clock: 0,
67+
};
68+
3669
#[wasm_bindgen]
3770
impl Universe {
38-
fn get_index(&self, row: u32, column: u32) -> usize {
71+
fn get_index(&self, row: i32, column: i32) -> usize {
3972
(row * self.width + column) as usize
4073
}
4174

42-
fn live_neighbor_count(&self, row: u32, column: u32) -> u8 {
43-
let mut count = 0;
44-
for delta_row in [self.height - 1, 0, 1].iter().cloned() {
45-
for delta_col in [self.width - 1, 0, 1].iter().cloned() {
46-
if delta_row == 0 && delta_col == 0 {
47-
continue;
48-
}
49-
50-
let neighbor_row = (row + delta_row) % self.height;
51-
let neighbor_col = (column + delta_col) % self.width;
52-
let idx = self.get_index(neighbor_row, neighbor_col);
53-
count += self.cells[idx] as u8;
54-
}
55-
}
56-
count
75+
fn get_cell(&self, x: i32, y: i32) -> Cell {
76+
let i = self.get_index(x, y);
77+
return self.cells[i];
5778
}
5879

5980
pub fn tick(&mut self) {
@@ -62,70 +83,87 @@ impl Universe {
6283
for row in 0..self.height {
6384
for col in 0..self.width {
6485
let idx = self.get_index(row, col);
65-
let cell = self.cells[idx];
66-
let live_neighbors = self.live_neighbor_count(row, col);
67-
68-
let next_cell = match (cell, live_neighbors) {
69-
// Rule 1: Any live cell with fewer than two live neighbours
70-
// dies, as if caused by underpopulation.
71-
(Cell::Alive, x) if x < 2 => Cell::Dead,
72-
// Rule 2: Any live cell with two or three live neighbours
73-
// lives on to the next generation.
74-
(Cell::Alive, 2) | (Cell::Alive, 3) => Cell::Alive,
75-
// Rule 3: Any live cell with more than three live
76-
// neighbours dies, as if by overpopulation.
77-
(Cell::Alive, x) if x > 3 => Cell::Dead,
78-
// Rule 4: Any dead cell with exactly three live neighbours
79-
// becomes a live cell, as if by reproduction.
80-
(Cell::Dead, 3) => Cell::Alive,
81-
// All other cells remain in the same state.
82-
(otherwise, _) => otherwise,
83-
};
84-
85-
next[idx] = next_cell;
86+
let cell = &self.cells[idx];
8687
}
8788
}
8889

8990
self.cells = next;
9091
}
9192

9293
pub fn new() -> Universe {
93-
let width = 64;
94-
let height = 64;
95-
96-
let cells = (0..width * height)
97-
.map(|i| {
98-
if i % 2 == 0 || i % 7 == 0 {
99-
Cell::Alive
100-
} else {
101-
Cell::Dead
102-
}
103-
})
104-
.collect();
94+
let width = 150;
95+
let height = 150;
96+
let cells = (0..width * height).map(|_i| EMPTY_CELL).collect();
97+
let rng: SplitMix64 = SeedableRng::seed_from_u64(0x734f6b89de5f83cc);
10598
Universe {
10699
width,
107100
height,
108101
cells,
102+
rng,
103+
generation: 0,
109104
}
110105
}
111106

112-
pub fn render(&self) -> String {
113-
self.to_string()
107+
pub fn width(&self) -> i32 {
108+
self.width
114109
}
115-
}
116110

117-
use std::fmt;
111+
pub fn height(&self) -> i32 {
112+
self.height
113+
}
118114

119-
impl fmt::Display for Universe {
120-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121-
for line in self.cells.as_slice().chunks(self.width as usize) {
122-
for &cell in line {
123-
let symbol = if cell == Cell::Dead { '◻' } else { '◼' };
124-
write!(f, "{}", symbol)?;
125-
}
126-
write!(f, "\n")?;
115+
pub fn cells(&self) -> *const Cell {
116+
self.cells.as_ptr()
117+
}
118+
119+
pub fn paint(&mut self, x: i32, y: i32, size: i32, species: Species) {
120+
let size = size;
121+
let radius: f64 = (size as f64) / 2.0;
122+
// let radius: f64 = (size as f64);
123+
124+
let floor = (radius + 1.0) as i32;
125+
let ciel = (radius + 1.5) as i32;
126+
127+
unsafe {
128+
log!("x {}: ", x);
129+
log!("y {}: ", y);
130+
log!("size {}: ", size);
131+
log!("floor {}: ", floor);
132+
log!("ciel {}: ", ciel);
133+
log!("species {:?}: ", species);
134+
log!("self.cells {:?}: ", self.cells);
127135
}
128136

129-
Ok(())
137+
for dx in -floor..ciel {
138+
for dy in -floor..ciel {
139+
if (((dx * dx) + (dy * dy)) as f64) > (radius * radius) {
140+
continue;
141+
};
142+
let px = x + dx;
143+
let py = y + dy;
144+
let i = self.get_index(px, py);
145+
146+
if px < 0 || px > self.width - 1 || py < 0 || py > self.height - 1 {
147+
continue;
148+
}
149+
150+
// let test = self.get_cell(px, py).species;
151+
// unsafe {
152+
// log!("test {:?}", test);
153+
// log!("type {:?}", Species::Empty);
154+
// }
155+
if self.get_cell(px, py).species == Species::Empty || species == Species::Empty {
156+
self.cells[i] = Cell {
157+
species: species,
158+
ra: 60
159+
+ (size as u8)
160+
+ (self.rng.gen::<f32>() * 30.) as u8
161+
+ ((self.generation % 127) as i8 - 60).abs() as u8,
162+
rb: 0,
163+
clock: self.generation,
164+
};
165+
}
166+
}
167+
}
130168
}
131169
}

src/species.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use wasm_bindgen::prelude::*;
2+
3+
pub struct Cell {
4+
species: Species,
5+
ra: u8,
6+
rb: u8,
7+
clock: u8,
8+
}
9+
10+
#[wasm_bindgen]
11+
#[repr(u8)]
12+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13+
pub enum Species {
14+
Empty = 0,
15+
Wall = 1,
16+
Sand = 2,
17+
}
18+
19+
impl Species {
20+
pub fn update(&self, cell: Cell) {
21+
match self {
22+
Species::Empty => {}
23+
Species::Wall => {}
24+
Species::Sand => {}
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)