.
This commit is contained in:
@@ -5,10 +5,22 @@ import { grid } from "./sample";
|
|||||||
(async () => {
|
(async () => {
|
||||||
const api = await import("@snk/solver-r");
|
const api = await import("@snk/solver-r");
|
||||||
|
|
||||||
const g = api.Grid.create(grid.width, grid.height, grid.data);
|
const g = api.IGrid.create(grid.width, grid.height, grid.data);
|
||||||
|
|
||||||
const { canvas, draw, highlightCell } = createCanvas(g);
|
const freeCells = api.iget_free_cell(g);
|
||||||
document.body.appendChild(canvas);
|
|
||||||
|
|
||||||
draw({ width: g.width, height: g.height, data: g.cells }, [] as any, []);
|
console.log(freeCells);
|
||||||
|
|
||||||
|
{
|
||||||
|
const { canvas, draw, highlightCell } = createCanvas(g);
|
||||||
|
document.body.appendChild(canvas);
|
||||||
|
|
||||||
|
draw({ width: g.width, height: g.height, data: g.data }, [] as any, []);
|
||||||
|
|
||||||
|
for (let i = freeCells.length / 2; i--; ) {
|
||||||
|
const x = freeCells[i * 2 + 0];
|
||||||
|
const y = freeCells[i * 2 + 1];
|
||||||
|
highlightCell(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
63
packages/solver-r/src/grid.rs
Normal file
63
packages/solver-r/src/grid.rs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||||
|
pub struct Point {
|
||||||
|
pub x: u8,
|
||||||
|
pub y: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum Cell {
|
||||||
|
Empty = 0,
|
||||||
|
Color1 = 1,
|
||||||
|
Color2 = 2,
|
||||||
|
Color3 = 3,
|
||||||
|
Color4 = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Grid {
|
||||||
|
pub width: u8,
|
||||||
|
pub height: u8,
|
||||||
|
pub cells: Vec<Cell>,
|
||||||
|
}
|
||||||
|
impl Grid {
|
||||||
|
pub fn create_empty(width: u8, height: u8) -> Grid {
|
||||||
|
let n = (width as usize) * (height as usize);
|
||||||
|
let cells = (0..n).map(|_| Cell::Empty).collect();
|
||||||
|
|
||||||
|
Grid {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
cells,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_index(&self, x: u8, y: u8) -> usize {
|
||||||
|
return (x as usize) * (self.height as usize) + (y as usize);
|
||||||
|
}
|
||||||
|
pub fn get_cell(&self, p: &Point) -> Cell {
|
||||||
|
let i = self.get_index(p.x, p.y);
|
||||||
|
return self.cells[i];
|
||||||
|
}
|
||||||
|
pub fn set_cell(&mut self, p: &Point, value: Cell) -> () {
|
||||||
|
let i = self.get_index(p.x, p.y);
|
||||||
|
self.cells[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_should_grid_create() {
|
||||||
|
let grid = Grid::create_empty(30, 10);
|
||||||
|
|
||||||
|
assert_eq!(grid.width, 30);
|
||||||
|
assert_eq!(grid.height, 10);
|
||||||
|
assert_eq!(grid.get_cell(&Point { x: 2, y: 3 }), Cell::Empty);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn it_should_grid_setter() {
|
||||||
|
let mut grid = Grid::create_empty(20, 10);
|
||||||
|
|
||||||
|
grid.set_cell(&Point { x: 12, y: 3 }, Cell::Color1);
|
||||||
|
|
||||||
|
assert_eq!(grid.get_cell(&Point { x: 12, y: 3 }), Cell::Color1);
|
||||||
|
}
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
|
mod grid;
|
||||||
|
mod solver;
|
||||||
|
|
||||||
|
use grid::{Cell, Grid};
|
||||||
use js_sys;
|
use js_sys;
|
||||||
|
use solver::get_free_cell;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@@ -11,45 +16,17 @@ pub fn greet() {
|
|||||||
alert("Hello, wasm-game-of-life!");
|
alert("Hello, wasm-game-of-life!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct Point {
|
|
||||||
x: i8,
|
|
||||||
y: i8,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
#[repr(u8)]
|
|
||||||
pub enum Cell {
|
|
||||||
Empty = 0,
|
|
||||||
Color1 = 1,
|
|
||||||
Color2 = 2,
|
|
||||||
Color3 = 3,
|
|
||||||
Color4 = 4,
|
|
||||||
Color5 = 5,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Grid {
|
pub struct IGrid {
|
||||||
pub width: i8,
|
pub width: u8,
|
||||||
pub height: i8,
|
pub height: u8,
|
||||||
cells: Vec<Cell>,
|
cells: Vec<Cell>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
impl Grid {
|
impl IGrid {
|
||||||
pub fn create_empty(width: i8, height: i8) -> Grid {
|
pub fn create(width: u8, height: u8, data: js_sys::Uint8Array) -> IGrid {
|
||||||
let n = (width as usize) * (height as usize);
|
|
||||||
let cells = (0..n).map(|_| Cell::Empty).collect();
|
|
||||||
|
|
||||||
Grid {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
cells,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn create(width: i8, height: i8, data: js_sys::Uint8Array) -> Grid {
|
|
||||||
let cells = data
|
let cells = data
|
||||||
.to_vec()
|
.to_vec()
|
||||||
.iter()
|
.iter()
|
||||||
@@ -59,12 +36,11 @@ impl Grid {
|
|||||||
2 => Cell::Color2,
|
2 => Cell::Color2,
|
||||||
3 => Cell::Color3,
|
3 => Cell::Color3,
|
||||||
4 => Cell::Color4,
|
4 => Cell::Color4,
|
||||||
5 => Cell::Color5,
|
|
||||||
_ => panic!("unknown cell"),
|
_ => panic!("unknown cell"),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Grid {
|
IGrid {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
cells,
|
cells,
|
||||||
@@ -72,40 +48,29 @@ impl Grid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen(getter)]
|
#[wasm_bindgen(getter)]
|
||||||
pub fn cells(&self) -> js_sys::Uint8Array {
|
pub fn data(&self) -> js_sys::Uint8Array {
|
||||||
let o: Vec<u8> = self.cells.iter().map(|u| *u as u8).collect();
|
let o: Vec<u8> = self.cells.iter().map(|u| *u as u8).collect();
|
||||||
js_sys::Uint8Array::from(&o[..])
|
js_sys::Uint8Array::from(&o[..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Snake = [Point; 5];
|
impl From<IGrid> for Grid {
|
||||||
|
fn from(value: IGrid) -> Self {
|
||||||
pub fn get_index(grid: &Grid, x: i8, y: i8) -> usize {
|
Self {
|
||||||
return (x as usize) * (grid.height as usize) + (y as usize);
|
width: value.width,
|
||||||
|
height: value.height,
|
||||||
|
cells: value.cells,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cell(grid: &Grid, p: &Point) -> Cell {
|
#[wasm_bindgen]
|
||||||
let i = get_index(grid, p.x, p.y);
|
pub fn iget_free_cell(grid: &IGrid) -> js_sys::Uint8Array {
|
||||||
return grid.cells[i];
|
let g = Grid::from(grid.clone());
|
||||||
}
|
|
||||||
pub fn set_cell(grid: &mut Grid, p: &Point, value: Cell) -> () {
|
|
||||||
let i = get_index(&grid, p.x, p.y);
|
|
||||||
grid.cells[i] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
let out = get_free_cell(&g, Cell::Color1);
|
||||||
fn grid_create() {
|
|
||||||
let grid = Grid::create_empty(30, 10);
|
|
||||||
|
|
||||||
assert_eq!(grid.width, 30);
|
let o: Vec<u8> = out.iter().flat_map(|p| [p.x, p.y]).collect();
|
||||||
assert_eq!(grid.height, 10);
|
|
||||||
assert_eq!(get_cell(&grid, &Point { x: 2, y: 3 }), Cell::Empty);
|
js_sys::Uint8Array::from(&o[..])
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn grid_setter() {
|
|
||||||
let mut grid = Grid::create_empty(20, 10);
|
|
||||||
|
|
||||||
set_cell(&mut grid, &Point { x: 12, y: 3 }, Cell::Color1);
|
|
||||||
|
|
||||||
assert_eq!(get_cell(&grid, &Point { x: 12, y: 3 }), Cell::Color1);
|
|
||||||
}
|
}
|
||||||
|
|||||||
34
packages/solver-r/src/solver.rs
Normal file
34
packages/solver-r/src/solver.rs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use crate::grid::{Cell, Grid, Point};
|
||||||
|
|
||||||
|
pub fn get_free_cell(grid: &Grid, walkable: Cell) -> HashSet<Point> {
|
||||||
|
let mut free: HashSet<Point> = HashSet::new();
|
||||||
|
let mut open_list: HashSet<Point> = HashSet::new();
|
||||||
|
let mut changed = true;
|
||||||
|
|
||||||
|
open_list.insert(Point { x: 0, y: 0 });
|
||||||
|
|
||||||
|
while changed {
|
||||||
|
changed = false
|
||||||
|
}
|
||||||
|
|
||||||
|
open_list
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_should_collect_free_cell() {
|
||||||
|
let mut grid = Grid::create_empty(2, 2);
|
||||||
|
|
||||||
|
grid.set_cell(&Point { x: 1, y: 1 }, Cell::Color2);
|
||||||
|
|
||||||
|
let free_cells = get_free_cell(&grid, Cell::Color1);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
free_cells,
|
||||||
|
HashSet::from([
|
||||||
|
//
|
||||||
|
Point { x: 0, y: 0 }
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user