use a more compact memory rep
This commit is contained in:
parent
40c026f32a
commit
50f94820a5
3 changed files with 38 additions and 45 deletions
|
@ -11,6 +11,7 @@ crate-type = ["cdylib", "rlib"]
|
|||
default = ["console_error_panic_hook"]
|
||||
|
||||
[dependencies]
|
||||
fixedbitset = "0.4.0"
|
||||
js-sys = "0.3"
|
||||
wasm-bindgen = "0.2.63"
|
||||
|
||||
|
|
76
src/lib.rs
76
src/lib.rs
|
@ -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
|
||||
let mut cells = FixedBitSet::with_capacity(size);
|
||||
|
||||
for i in 0..size {
|
||||
cells.set(i, i % 2 == 0 || i % 7 == 0);
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
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
|
||||
let mut cells = FixedBitSet::with_capacity(size);
|
||||
|
||||
for i in 0..size {
|
||||
cells.set(i, js_sys::Math::random() < 0.5);
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
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")?;
|
||||
|
|
2
www
2
www
|
@ -1 +1 @@
|
|||
Subproject commit b0799ea316d590cd432fee5f53914287e2a328d6
|
||||
Subproject commit f6fa2759a6dce5379554d7294f00487bb1565004
|
Loading…
Reference in a new issue