|
|
|
@ -1,9 +1,12 @@
|
|
|
|
|
mod utils;
|
|
|
|
|
|
|
|
|
|
extern crate js_sys;
|
|
|
|
|
extern crate fixedbitset;
|
|
|
|
|
|
|
|
|
|
use std::fmt;
|
|
|
|
|
use wasm_bindgen::prelude::*;
|
|
|
|
|
use fixedbitset::FixedBitSet;
|
|
|
|
|
|
|
|
|
|
extern crate js_sys;
|
|
|
|
|
|
|
|
|
|
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
|
|
|
|
// allocator.
|
|
|
|
@ -21,19 +24,11 @@ pub fn greet(name: &str) {
|
|
|
|
|
alert(&format!("Hello, {name}!", name=name))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[wasm_bindgen]
|
|
|
|
|
#[repr(u8)]
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
|
|
|
pub enum Cell {
|
|
|
|
|
Dead = 0,
|
|
|
|
|
Alive = 1,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[wasm_bindgen]
|
|
|
|
|
pub struct Universe {
|
|
|
|
|
width: u32,
|
|
|
|
|
height: u32,
|
|
|
|
|
cells: Vec<Cell>,
|
|
|
|
|
cells: FixedBitSet,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Universe{
|
|
|
|
@ -69,14 +64,13 @@ impl Universe {
|
|
|
|
|
let i = self.get_index(row, col);
|
|
|
|
|
let cell = self.cells[i];
|
|
|
|
|
let live_neighbor = self.live_neighbor_count(row, col);
|
|
|
|
|
let next_cell = match (cell, live_neighbor){
|
|
|
|
|
(Cell::Alive, x) if x < 2 => Cell::Dead,
|
|
|
|
|
(Cell::Alive, 2) | (Cell::Alive, 3) => Cell::Alive,
|
|
|
|
|
(Cell::Alive, x) if x > 3 => Cell::Dead,
|
|
|
|
|
(Cell::Dead, 3) => Cell::Alive,
|
|
|
|
|
next.set(i, match (cell, live_neighbor){
|
|
|
|
|
(true, x) if x < 2 => false,
|
|
|
|
|
(true, 2) | (true, 3) => true,
|
|
|
|
|
(true, x) if x > 3 => false,
|
|
|
|
|
(false, 3) => true,
|
|
|
|
|
(other, _) => other,
|
|
|
|
|
};
|
|
|
|
|
next[i] = next_cell;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
self.cells = next;
|
|
|
|
@ -85,16 +79,13 @@ impl Universe {
|
|
|
|
|
pub fn new() -> Universe {
|
|
|
|
|
let width = 64;
|
|
|
|
|
let height = 64;
|
|
|
|
|
let size = (width * height) as usize;
|
|
|
|
|
|
|
|
|
|
let cells = (0..width * height)
|
|
|
|
|
.map(|i| {
|
|
|
|
|
if i % 2 == 0 || i % 7 == 0 {
|
|
|
|
|
Cell::Alive
|
|
|
|
|
} else {
|
|
|
|
|
Cell::Dead
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.collect();
|
|
|
|
|
let mut cells = FixedBitSet::with_capacity(size);
|
|
|
|
|
|
|
|
|
|
for i in 0..size {
|
|
|
|
|
cells.set(i, i % 2 == 0 || i % 7 == 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Universe {
|
|
|
|
|
width,
|
|
|
|
@ -106,16 +97,13 @@ impl Universe {
|
|
|
|
|
pub fn new_random() -> Universe {
|
|
|
|
|
let width = 64;
|
|
|
|
|
let height = 64;
|
|
|
|
|
let size = (width * height) as usize;
|
|
|
|
|
|
|
|
|
|
let cells = (0..width * height)
|
|
|
|
|
.map(|_i| {
|
|
|
|
|
if js_sys::Math::random() < 0.5 {
|
|
|
|
|
Cell::Alive
|
|
|
|
|
} else {
|
|
|
|
|
Cell::Dead
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.collect();
|
|
|
|
|
let mut cells = FixedBitSet::with_capacity(size);
|
|
|
|
|
|
|
|
|
|
for i in 0..size {
|
|
|
|
|
cells.set(i, js_sys::Math::random() < 0.5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Universe {
|
|
|
|
|
width,
|
|
|
|
@ -127,16 +115,19 @@ impl Universe {
|
|
|
|
|
pub fn new_space_ship() -> Universe {
|
|
|
|
|
let width : u32 = 64;
|
|
|
|
|
let height : u32 = 64;
|
|
|
|
|
let size = (width * height) as usize;
|
|
|
|
|
|
|
|
|
|
let mut cells : Vec<Cell> = (0..width * height)
|
|
|
|
|
.map(|_i| { Cell::Dead })
|
|
|
|
|
.collect();
|
|
|
|
|
let mut cells = FixedBitSet::with_capacity(size);
|
|
|
|
|
|
|
|
|
|
for i in 0..size {
|
|
|
|
|
cells.set(i, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let x0 = 32;
|
|
|
|
|
let y0 = 32;
|
|
|
|
|
for (x, y) in [(0, 2), (1, 0), (1, 2), (2, 1), (2, 2)].iter().cloned() {
|
|
|
|
|
let i = ((y0 + y) * width + x0 + x) as usize;
|
|
|
|
|
cells[i] = Cell::Alive;
|
|
|
|
|
cells.set(i, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Universe {
|
|
|
|
@ -158,16 +149,17 @@ impl Universe {
|
|
|
|
|
self.height
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn cells(&self) -> *const Cell {
|
|
|
|
|
self.cells.as_ptr()
|
|
|
|
|
pub fn cells(&self) -> *const u32 {
|
|
|
|
|
self.cells.as_slice().as_ptr()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl fmt::Display for Universe {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
|
for line in self.cells.as_slice().chunks(self.width as usize) {
|
|
|
|
|
for &cell in line {
|
|
|
|
|
let symbole = if cell == Cell::Dead { '◻' } else { '◼' };
|
|
|
|
|
for row in 0..self.height {
|
|
|
|
|
for col in 0..self.width {
|
|
|
|
|
let i = self.get_index(row, col);
|
|
|
|
|
let symbole = if self.cells[i] { '◻' } else { '◼' };
|
|
|
|
|
write!(f, "{}", symbole)?;
|
|
|
|
|
}
|
|
|
|
|
write!(f, "\n")?;
|
|
|
|
|