.
This commit is contained in:
@@ -9,8 +9,6 @@ import { grid } from "./sample";
|
||||
|
||||
const freeCells = api.iget_free_cell(g);
|
||||
|
||||
console.log(freeCells);
|
||||
|
||||
{
|
||||
const { canvas, draw, highlightCell } = createCanvas(g);
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
12
packages/solver-r/Cargo.lock
generated
12
packages/solver-r/Cargo.lock
generated
@@ -33,6 +33,16 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console_log"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f"
|
||||
dependencies = [
|
||||
"log",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.77"
|
||||
@@ -109,7 +119,9 @@ name = "snk-solver-rust"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"console_log",
|
||||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
@@ -13,6 +13,8 @@ default = ["console_error_panic_hook"]
|
||||
[dependencies]
|
||||
wasm-bindgen = "0.2.100"
|
||||
js-sys = "0.3.77"
|
||||
console_log = "1.0.0"
|
||||
log = "0.4"
|
||||
|
||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||
# logging them with `console.error`. This is great for development, but requires
|
||||
|
||||
@@ -6,6 +6,9 @@ use js_sys;
|
||||
use solver::get_free_cell;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use log::info;
|
||||
use log::Level;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
fn alert(s: &str);
|
||||
|
||||
@@ -6,13 +6,21 @@ 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();
|
||||
|
||||
for x in -1..((grid.width as i8) + 1) {
|
||||
for x in 0..(grid.width as i8) {
|
||||
open_list.insert(Point { x, y: 0 });
|
||||
open_list.insert(Point {
|
||||
x,
|
||||
y: (grid.height as i8) - 1,
|
||||
});
|
||||
}
|
||||
for y in 0..(grid.height as i8) {
|
||||
open_list.insert(Point { x: 0, y });
|
||||
open_list.insert(Point {
|
||||
x: (grid.width as i8) - 1,
|
||||
y,
|
||||
});
|
||||
}
|
||||
open_list.retain(|p| grid.get_cell(&p) <= walkable);
|
||||
|
||||
let directions = [
|
||||
Point { x: 1, y: 0 },
|
||||
@@ -24,25 +32,9 @@ pub fn get_free_cell(grid: &Grid, walkable: Cell) -> HashSet<Point> {
|
||||
while let Some(p) = open_list.iter().next().cloned() {
|
||||
open_list.remove(&p);
|
||||
|
||||
let exit_count: u8 = directions.iter().fold(0, |sum, dir| {
|
||||
let neighbour = Point {
|
||||
x: p.x + dir.x,
|
||||
y: p.y + dir.y,
|
||||
};
|
||||
|
||||
if !grid.is_inside(&neighbour) {
|
||||
sum + 2
|
||||
} else if free.contains(&neighbour) {
|
||||
sum + 1
|
||||
} else {
|
||||
sum
|
||||
}
|
||||
});
|
||||
|
||||
if exit_count >= 2 {
|
||||
if grid.is_inside(&p) && grid.get_cell(&p) <= walkable {
|
||||
free.insert(p);
|
||||
}
|
||||
let has_enough_free_exits = {
|
||||
let mut exit_count = 0;
|
||||
let mut visited: HashSet<Point> = HashSet::new();
|
||||
|
||||
for dir in directions {
|
||||
let neighbour = Point {
|
||||
@@ -50,9 +42,56 @@ pub fn get_free_cell(grid: &Grid, walkable: Cell) -> HashSet<Point> {
|
||||
y: p.y + dir.y,
|
||||
};
|
||||
|
||||
if grid.is_inside(&neighbour)
|
||||
&& (grid.get_cell(&neighbour) <= walkable)
|
||||
&& !free.contains(&neighbour)
|
||||
if !visited.contains(&neighbour)
|
||||
&& (free.contains(&neighbour) || !grid.is_inside(&neighbour))
|
||||
{
|
||||
visited.insert(neighbour);
|
||||
exit_count += 1;
|
||||
}
|
||||
|
||||
if grid.is_inside(&neighbour) && grid.get_cell(&neighbour) <= walkable {
|
||||
for alt in [-1, 1] {
|
||||
let corner = {
|
||||
if neighbour.x != 0 {
|
||||
Point {
|
||||
x: neighbour.x,
|
||||
y: neighbour.y + alt,
|
||||
}
|
||||
} else {
|
||||
Point {
|
||||
x: neighbour.x + alt,
|
||||
y: neighbour.y,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if !visited.contains(&neighbour)
|
||||
&& !visited.contains(&corner)
|
||||
&& (free.contains(&corner) || !grid.is_inside(&corner))
|
||||
{
|
||||
visited.insert(neighbour);
|
||||
visited.insert(corner);
|
||||
exit_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit_count >= 2
|
||||
};
|
||||
|
||||
if has_enough_free_exits {
|
||||
free.insert(p);
|
||||
|
||||
for dir in directions {
|
||||
let neighbour = Point {
|
||||
x: p.x + dir.x,
|
||||
y: p.y + dir.y,
|
||||
};
|
||||
|
||||
if !free.contains(&neighbour)
|
||||
&& grid.is_inside(&neighbour)
|
||||
&& grid.get_cell(&neighbour) <= walkable
|
||||
{
|
||||
open_list.insert(neighbour);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user