Skip to content

Commit 5e31927

Browse files
committed
.
1 parent d3a2a18 commit 5e31927

File tree

3 files changed

+67
-18
lines changed

3 files changed

+67
-18
lines changed

packages/demo/demo.rust.ts

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import { createSnakeFromCells, snakeToCells } from "@snk/types/snake";
12
import { createCanvas } from "./canvas";
23
import "./menu";
3-
import { grid } from "./sample";
4+
import { grid, snake } from "./sample";
45

56
(async () => {
67
const api = await import("@snk/solver-r");
@@ -9,16 +10,43 @@ import { grid } from "./sample";
910

1011
const freeCells = api.iget_free_cells(g);
1112

13+
api.greet();
14+
15+
const path = api.ieat_free_cells(
16+
g,
17+
snakeToCells(snake).map((p) => api.IPoint.create(p.x, p.y)),
18+
);
19+
1220
{
1321
const { canvas, draw, highlightCell } = createCanvas(g);
1422
document.body.appendChild(canvas);
1523

16-
draw({ width: g.width, height: g.height, data: g.data }, [] as any, []);
24+
const snakeLength = snake.length / 2;
25+
26+
const onChange = () => {
27+
const i = +input.value;
28+
const s = createSnakeFromCells(path.slice(i, i + snakeLength).reverse());
29+
30+
draw({ width: g.width, height: g.height, data: g.data }, s, []);
31+
32+
// for (let i = freeCells.length / 2; i--; ) {
33+
// const x = freeCells[i * 2 + 0];
34+
// const y = freeCells[i * 2 + 1];
35+
// highlightCell(x, y);
36+
// }
37+
};
38+
39+
const input = document.createElement("input") as any;
40+
input.type = "range";
41+
input.value = 0;
42+
input.step = 1;
43+
input.min = 0;
44+
input.max = path.length - snakeLength;
45+
input.style.width = "90%";
46+
input.style.padding = "20px 0";
47+
input.addEventListener("input", onChange);
48+
document.body.append(input);
1749

18-
for (let i = freeCells.length / 2; i--; ) {
19-
const x = freeCells[i * 2 + 0];
20-
const y = freeCells[i * 2 + 1];
21-
highlightCell(x, y);
22-
}
50+
onChange();
2351
}
2452
})();

packages/solver-r/src/lib.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,34 @@ mod snake_compact;
66
mod snake_walk;
77
mod solver;
88

9+
use std::collections::HashSet;
10+
911
use astar::get_path;
1012
use astar_snake::get_snake_path;
1113
use grid::{Cell, Grid, Point, WalkableGrid};
1214
use js_sys;
15+
use log::info;
1316
use snake_walk::get_path_to_eat_all;
1417
use solver::get_free_cells;
1518
use wasm_bindgen::prelude::*;
1619

20+
#[wasm_bindgen]
21+
pub fn init_panic_hook() {
22+
console_error_panic_hook::set_once();
23+
}
24+
1725
#[wasm_bindgen]
1826
extern "C" {
1927
fn alert(s: &str);
2028
}
2129

2230
#[wasm_bindgen]
2331
pub fn greet() {
24-
alert("Hello, wasm-game-of-life!");
32+
init_panic_hook();
33+
console_log::init_with_level(log::Level::Debug).unwrap();
34+
35+
info!("It works!");
36+
// alert("Hello, wasm-game-of-life!");
2537
}
2638

2739
#[wasm_bindgen]
@@ -122,7 +134,7 @@ type ISnake = Vec<IPoint>;
122134
pub fn iget_free_cells(grid: &IGrid) -> js_sys::Uint8Array {
123135
let g = Grid::from(grid.clone());
124136

125-
let (_, out) = get_free_cells(&g, Cell::Color1);
137+
let (out, _) = get_free_cells(&g, Cell::Color1);
126138

127139
let o: Vec<u8> = out.iter().flat_map(|p| [p.x as u8, p.y as u8]).collect();
128140

@@ -172,9 +184,14 @@ pub fn ieat_free_cells(grid: &IGrid, snake: ISnake) -> Vec<IPoint> {
172184
let grid = WalkableGrid::create(Grid::from(grid.clone()), Cell::Color1);
173185
let snake: Vec<Point> = snake.iter().map(Point::from).collect();
174186

175-
let (free_cells, out) = get_free_cells(&grid.grid, Cell::Color1);
187+
let (free_cells, _) = get_free_cells(&grid.grid, Cell::Color1);
188+
189+
let mut to_eat: HashSet<Point> = HashSet::new();
190+
to_eat.insert(Point { x: 6, y: 6 });
191+
to_eat.insert(Point { x: 5, y: 0 });
176192

177-
let path = get_path_to_eat_all(&grid, &snake, free_cells);
193+
let path = get_path_to_eat_all(&grid, &snake, &to_eat);
194+
// let path = get_path_to_eat_all(&grid, &snake, &free_cells);
178195

179196
path.iter().map(IPoint::from).collect()
180197
}

packages/solver-r/src/snake_walk.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub fn can_snake_reach_outside(grid: &WalkableGrid, snake: &Snake) -> bool {
5454
pub fn get_path_to_eat_all(
5555
grid: &WalkableGrid,
5656
snake: &[Point],
57-
cells_to_eat: HashSet<Point>,
57+
cells_to_eat: &HashSet<Point>,
5858
) -> Vec<Point> {
5959
let snake_length = snake.len();
6060

@@ -78,12 +78,12 @@ pub fn get_path_to_eat_all(
7878
}
7979

8080
let snake = &path[0..snake_length];
81-
let w = match best_route.as_ref() {
81+
let max_weight = match best_route.as_ref() {
8282
None => usize::MAX,
8383
Some(path) => path.len() - snake_length,
8484
};
8585

86-
let res = get_snake_path(|c| grid.is_cell_walkable(c), snake, p, w);
86+
let res = get_snake_path(|c| grid.is_cell_walkable(c), snake, p, max_weight);
8787

8888
if let Some(sub_path) = res {
8989
if match best_route.as_ref() {
@@ -96,15 +96,19 @@ pub fn get_path_to_eat_all(
9696
}
9797

9898
if let Some(mut sub_path) = best_route {
99-
path.append(&mut sub_path);
99+
let eaten = sub_path[0];
100100

101-
let eaten = sub_path.last().unwrap();
102-
cells_to_eat.retain(|p| p != eaten);
101+
cells_to_eat.retain(|p| **p != eaten);
102+
103+
sub_path.truncate(sub_path.len() - snake_length);
104+
sub_path.append(&mut path);
105+
path = sub_path;
103106
} else {
104-
assert!(false);
107+
panic!("impossible to path to cell to eat");
105108
}
106109
}
107110

111+
path.reverse();
108112
path
109113
}
110114

0 commit comments

Comments
 (0)