Skip to content

Commit 4705557

Browse files
committed
.
1 parent cc7b3eb commit 4705557

File tree

8 files changed

+165
-12
lines changed

8 files changed

+165
-12
lines changed

cargo/snk-js/src/lib.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
use js_sys;
2-
use snk_grid::{color::Color, grid_samples::SampleGrid, point::Point, snake::Snake4};
2+
use snk_grid::{
3+
color::Color,
4+
grid_samples::SampleGrid,
5+
point::Point,
6+
snake::{Snake, Snake4},
7+
};
38
use wasm_bindgen::prelude::*;
49

510
#[wasm_bindgen]
@@ -51,11 +56,38 @@ pub fn get_best_tunnel_to_collect_point(grid: &IColorGrid, to: &IPoint) -> Vec<I
5156
let res =
5257
snk_solver::collect_cost::get_best_tunnel_to_collect_point(&grid, &exit_grid, to.into());
5358

54-
log::info!("{:?} {:?} {:?}",res.path,res.in_cost,res.out_cost);
55-
59+
log::info!("{:?} {:?} {:?}", res.path, res.in_cost, res.out_cost);
5660

5761
res.path.into_iter().map(IPoint::from).collect()
5862
}
63+
#[wasm_bindgen]
64+
pub fn get_snake_path_to_outside(grid: &IColorGrid, snake: Vec<IPoint>) -> Vec<IPoint> {
65+
let grid = snk_grid::grid::Grid::from(grid);
66+
let exit_grid = snk_solver::exit_grid::ExitGrid::create_from_grid_color(&grid);
67+
let snake = Snake4::from_points(
68+
snake
69+
.into_iter()
70+
.map(|p| Point::from(p))
71+
.collect::<Vec<_>>()
72+
.try_into()
73+
.expect("snake should be 4 points"),
74+
);
75+
let res = snk_solver::snake_path_to_outside::get_snake_path_to_outside(
76+
|p| exit_grid.is_outside(p),
77+
|p| grid.get_color(p).into(),
78+
&snake,
79+
);
80+
81+
let mut p = snake.get_head();
82+
res.0
83+
.into_iter()
84+
.map(|dir| {
85+
p = p + dir.to_point();
86+
p
87+
})
88+
.map(IPoint::from)
89+
.collect()
90+
}
5991

6092
// #[wasm_bindgen]
6193
// pub fn solve(grid: IColorGrid) -> js_sys::Uint8Array {
@@ -123,6 +155,10 @@ impl IColorGrid {
123155
let o: Vec<u8> = self.cells.iter().map(|u| *u as u8).collect();
124156
js_sys::Uint8Array::from(&o[..])
125157
}
158+
159+
pub fn set(&mut self, x: i8, y: i8, color: u8) {
160+
self.cells[(x as usize) * (self.height as usize) + (y as usize)] = color.into();
161+
}
126162
}
127163

128164
impl From<IColorGrid> for snk_grid::grid::Grid<Color> {

cargo/snk-solver/src/collect_cost.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ _ _
9595
);
9696
assert_eq!(grid.get_color(Point { x: 4, y: 2 }), Color::Color1);
9797

98-
let pto = ExitGrid::create_from_grid_color(&grid);
98+
let exit_grid = ExitGrid::create_from_grid_color(&grid);
9999

100-
let tunnel = get_best_tunnel_to_collect_point(&grid, &pto, Point { x: 4, y: 2 });
100+
let tunnel = get_best_tunnel_to_collect_point(&grid, &exit_grid, Point { x: 4, y: 2 });
101101

102102
assert_eq!(tunnel.in_cost.get_color_count(Color::Color4), 1);
103103
assert_eq!(tunnel.out_cost.get_color_count(Color::Color4), 1);
@@ -123,9 +123,35 @@ _ _
123123

124124
assert_eq!(grid.get_color(Point { x: 5, y: 3 }), Color::Color1);
125125

126+
let exit_grid = ExitGrid::create_from_grid_color(&grid);
127+
128+
let tunnel = get_best_tunnel_to_collect_point(&grid, &exit_grid, Point { x: 5, y: 3 });
129+
assert_eq!(tunnel.in_cost.get_color_count(Color::Color4), 1);
130+
assert_eq!(tunnel.out_cost.get_color_count(Color::Color4), 0);
131+
132+
assert_eq!(tunnel.in_cost.get_color_count(Color::Color1), 1);
133+
assert_eq!(tunnel.out_cost.get_color_count(Color::Color1), 0);
134+
}
135+
136+
#[test]
137+
fn it_should_compute_the_tunnel_for_enclaved_dot_in_large_cave_2() {
138+
let grid = Grid::<_>::from(
139+
r#"
140+
_ _
141+
_ ###### _
142+
_ ## # _
143+
_ ## . # _
144+
_ ###### _
145+
_ _
146+
147+
"#,
148+
);
149+
150+
assert_eq!(grid.get_color(Point { x: 6, y: 3 }), Color::Color1);
151+
126152
let pto = ExitGrid::create_from_grid_color(&grid);
127153

128-
let tunnel = get_best_tunnel_to_collect_point(&grid, &pto, Point { x: 5, y: 3 });
154+
let tunnel = get_best_tunnel_to_collect_point(&grid, &pto, Point { x: 6, y: 3 });
129155
assert_eq!(tunnel.in_cost.get_color_count(Color::Color4), 1);
130156
assert_eq!(tunnel.out_cost.get_color_count(Color::Color4), 0);
131157

cargo/snk-solver/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ mod cost;
55
pub mod exit_grid;
66
mod fitness;
77
pub mod snake_path;
8-
mod snake_path_to_outside;
8+
pub mod snake_path_to_outside;
99
pub mod solver;

cargo/snk-solver/src/snake_path_to_outside.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ _######## _
101101
102102
"#,
103103
);
104-
let pto = ExitGrid::create_from_grid_color(&grid);
104+
let exit_grid = ExitGrid::create_from_grid_color(&grid);
105105
let snake = Snake4::from_points([
106106
Point { x: 2, y: 2 },
107107
Point { x: 3, y: 2 },
@@ -110,13 +110,51 @@ _######## _
110110
]);
111111

112112
let (path, cost) =
113-
get_snake_path_to_outside(|p| pto.is_outside(p), |p| grid.get_color(p).into(), &snake);
113+
get_snake_path_to_outside(|p| exit_grid.is_outside(p), |p| grid.get_color(p).into(), &snake);
114114

115115
println!("{:?} {:?}", path, cost);
116+
116117
assert_eq!(
117118
cost.get_color_count(Color::Color4),
118119
1,
119120
"should have taken the smallest path"
120121
);
121122
}
123+
124+
#[test]
125+
fn it_should_get_snake_path_to_outside_2() {
126+
let mut grid = Grid::<_>::from(
127+
r#"
128+
_ _
129+
_ ##### _
130+
_ # # _
131+
_ # # _
132+
_ ##### _
133+
_ _
134+
135+
"#,
136+
);
137+
138+
assert_eq!(grid.get_color(Point { x: 5, y: 4 }),Color::Color4);
139+
140+
let exit_grid = ExitGrid::create_from_grid_color(&grid);
141+
let snake = Snake4::from_points([
142+
Point { x: 5, y: 4 },
143+
Point { x: 5, y: 5 },
144+
Point { x: 5, y: 6 },
145+
Point { x: 5, y: 7 },
146+
]);
147+
148+
grid.set(Point { x: 5, y: 4 }, Color::Empty);
149+
150+
let (path, cost) =
151+
get_snake_path_to_outside(|p| exit_grid.is_outside(p), |p| grid.get_color(p).into(), &snake);
152+
153+
println!("{:?} {:?}", path, cost);
154+
assert_eq!(
155+
cost.get_color_count(Color::Color4),
156+
0,
157+
"should have taken the smallest path"
158+
);
159+
}
122160
}

packages/demo3/dev.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import { serve } from "bun";
22
import * as childProcess from "child_process";
33
import * as fs from "fs";
44
import * as path from "path";
5-
5+
import snake_exit_page from "./snake_exit/index.html";
66
import tunnel_page from "./tunnel/index.html";
77

88
const server = serve({
99
routes: {
1010
"/": tunnel_page,
1111
"/tunnel": tunnel_page,
12+
"/snake_exit": snake_exit_page,
1213
},
1314

1415
// Enable development mode for:
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<script type="module" src="./index.ts"></script>
7+
</head>
8+
</html>

packages/demo3/snake_exit/index.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import init, {
2+
get_best_tunnel_to_collect_point,
3+
get_grid_sample,
4+
get_snake_path_to_outside,
5+
IPoint,
6+
init_log,
7+
init_panic_hook,
8+
} from "snk-js";
9+
import wasmUrl from "snk-js/snk_js_bg.wasm";
10+
import { createCanvas } from "../utils/canvas";
11+
12+
await init(wasmUrl);
13+
init_panic_hook();
14+
init_log();
15+
16+
const grid = get_grid_sample("caves");
17+
grid.set(29, 4, 0);
18+
19+
const snake = [
20+
{ x: 29, y: 4 },
21+
{ x: 29, y: 5 },
22+
{ x: 29, y: 6 },
23+
{ x: 29, y: 7 },
24+
];
25+
26+
const path = get_snake_path_to_outside(
27+
grid,
28+
snake.map(({ x, y }) => IPoint.create(x, y)),
29+
);
30+
31+
console.log(path);
32+
33+
const { canvas, draw, getPointedCell, highlightCell } = createCanvas(grid);
34+
document.body.appendChild(canvas);
35+
draw(
36+
{ width: grid.width, height: grid.height, data: grid.cells },
37+
snake.flatMap(({ x, y }) => [x + 2, y + 2]) as any,
38+
[],
39+
);
40+
41+
for (const { x, y } of path) highlightCell(x, y);

packages/demo3/tunnel/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ init_panic_hook();
1313
init_log();
1414

1515
const grid = get_grid_sample("caves");
16-
const g = { width: grid.width, height: grid.height, data: grid.cells };
1716
const { canvas, draw, getPointedCell, highlightCell } = createCanvas(grid);
1817
document.body.appendChild(canvas);
1918

2019
const drawBestTunnel = ({ x, y }: { x: number; y: number }) => {
21-
draw(g, [] as any, []);
20+
draw(
21+
{ width: grid.width, height: grid.height, data: grid.cells },
22+
[] as any,
23+
[],
24+
);
2225

2326
const path = get_best_tunnel_to_collect_point(grid, IPoint.create(x, y));
2427

0 commit comments

Comments
 (0)