Browse Source

first throw for game of life...

master
Georg Hopp 6 years ago
parent
commit
cac13d027e
Signed by: ghopp GPG Key ID: 4C5D226768784538
  1. 103
      tutorial/wasm-game-of-life/src/lib.rs
  2. 17
      tutorial/wasm-game-of-life/www/index.html
  3. 14
      tutorial/wasm-game-of-life/www/index.js

103
tutorial/wasm-game-of-life/src/lib.rs

@ -1,5 +1,6 @@
mod utils; mod utils;
use std::fmt::{Display, Formatter, Result};
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
@ -9,11 +10,105 @@ use wasm_bindgen::prelude::*;
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen] #[wasm_bindgen]
extern {
fn alert(s: &str);
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Cell {
Dead = 0,
Alive = 1,
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn greet(s :&str) {
alert(&format!("Hello, {}!", s));
pub struct Universe {
width :u32,
height :u32,
cells :Vec<Cell>,
}
#[wasm_bindgen]
impl Universe {
pub fn new() -> Universe {
let width = 64;
let height = 64;
let init_cells = |i :u32| {
if i % 2 == 0 || i % 7 == 0 { Cell::Alive } else { Cell::Dead }
};
let cells = (0..width * height).map(init_cells).collect();
Universe {
width: width,
height: height,
cells: cells,
}
}
pub fn render(&self) -> String {
self.to_string()
}
pub fn tick(&mut self) {
let mut next = self.cells.clone();
for row in 0..self.height {
for col in 0..self.width {
let idx = self.get_index(row, col);
let cell = self.cells[idx];
let live_neighbors = self.live_neighbor_count(row, col);
// Game of life rules....
let next_cell = match (cell, live_neighbors) {
(Cell::Alive, 2) |
(Cell::Alive, 3) => Cell::Alive,
(Cell::Alive, _) => Cell::Dead,
( Cell::Dead, 3) => Cell::Alive,
( otherwise, _) => otherwise,
};
next[idx] = next_cell;
}
}
self.cells = next;
}
fn get_index(&self, row :u32, col :u32) -> usize {
(row * self.width + col) as usize
}
fn live_neighbor_count(&self, row :u32, col :u32) -> u8 {
let mut count = 0;
for delta_row in [self.height - 1, 0, 1].iter().cloned() {
for delta_col in [self.width - 1, 0, 1].iter().cloned() {
if delta_row == 0 && delta_col == 0 {
continue;
}
let neighbor_row = (row + delta_row) % self.height;
let neighbor_col = (col + delta_col) % self.width;
let idx = self.get_index(neighbor_row, neighbor_col);
count += self.cells[idx] as u8;
}
}
count
}
}
impl Display for Universe {
fn fmt(&self, f :&mut Formatter) -> Result {
for line in self.cells.as_slice().chunks(self.width as usize) {
for &cell in line {
let symbol = match cell {
Cell::Dead => ' ',
Cell::Alive => '*',
};
write!(f, "{}", symbol)?;
}
write!(f, "\n")?;
}
Ok(())
}
} }

17
tutorial/wasm-game-of-life/www/index.html

@ -2,10 +2,23 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Hello wasm-pack!</title>
<title>wasm-game-of-life!</title>
<style>
body {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
</style>
</head> </head>
<body> <body>
<noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript>
<pre id="game-of-life-canvas"></pre>
<script src="./bootstrap.js"></script> <script src="./bootstrap.js"></script>
</body> </body>
</html> </html>

14
tutorial/wasm-game-of-life/www/index.js

@ -1,3 +1,13 @@
import * as wasm from "wasm-game-of-life";
import { Universe } from "wasm-game-of-life";
wasm.greet("It's all a game");
const pre = document.getElementById("game-of-life-canvas");
const universe = Universe.new();
const renderLoop = () => {
pre.textContent = universe.render();
universe.tick();
requestAnimationFrame(renderLoop);
};
requestAnimationFrame(renderLoop);
Loading…
Cancel
Save