🚀 refactor demo
This commit is contained in:
@@ -1,33 +1,19 @@
|
||||
import { createCanvas } from "./canvas";
|
||||
import { samples } from "./samples";
|
||||
import { getInterestingAvailableRoutes } from "@snk/compute/getAvailableRoutes";
|
||||
import { createSnake, Snake, snakeToCells } from "@snk/compute/snake";
|
||||
import { Snake, snakeToCells } from "@snk/compute/snake";
|
||||
import { GUI } from "dat.gui";
|
||||
import { Point } from "@snk/compute/point";
|
||||
|
||||
//
|
||||
// init
|
||||
|
||||
const label = new URLSearchParams(window.location.search).get("sample");
|
||||
const { grid: grid0 } = samples.find((s) => s.label === label) || samples[0];
|
||||
import { grid, snake } from "./sample";
|
||||
import { getAvailableInterestingRoutes } from "@snk/compute/getAvailableRoutes";
|
||||
import type { Point } from "@snk/compute/point";
|
||||
|
||||
//
|
||||
// compute
|
||||
|
||||
const snake0 = createSnake([
|
||||
//
|
||||
{ x: -1, y: -1 },
|
||||
{ x: -1, y: 0 },
|
||||
{ x: -1, y: 1 },
|
||||
{ x: -1, y: 2 },
|
||||
{ x: -1, y: 3 },
|
||||
]);
|
||||
const routes: Snake[][] = [];
|
||||
getInterestingAvailableRoutes(
|
||||
grid0,
|
||||
snake0,
|
||||
(snakes) => {
|
||||
routes.push(snakes);
|
||||
getAvailableInterestingRoutes(
|
||||
grid,
|
||||
snake,
|
||||
(chain) => {
|
||||
routes.push(chain);
|
||||
return routes.length > 10;
|
||||
},
|
||||
2
|
||||
@@ -38,10 +24,10 @@ const config = { routeN: 0, routeK: 0 };
|
||||
//
|
||||
// draw
|
||||
|
||||
const { canvas, ctx, draw } = createCanvas(grid0);
|
||||
const { canvas, ctx, draw } = createCanvas(grid);
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
draw(grid0, snake0, []);
|
||||
draw(grid, snake, []);
|
||||
|
||||
let cancel: number;
|
||||
|
||||
@@ -53,9 +39,9 @@ const onChange = () => {
|
||||
cancelAnimationFrame(cancel);
|
||||
cancel = requestAnimationFrame(onChange);
|
||||
|
||||
const chain = routes[config.routeN] || [snake0];
|
||||
const chain = routes[config.routeN] || [snake];
|
||||
|
||||
draw(grid0, chain[mod(-t, chain.length)], []);
|
||||
draw(grid, chain[mod(-t, chain.length)], []);
|
||||
|
||||
const cells: Point[] = [];
|
||||
chain.forEach((s) => cells.push(...snakeToCells(s)));
|
||||
|
||||
@@ -1,48 +1,45 @@
|
||||
import { copyGrid } from "@snk/compute/grid";
|
||||
import { copySnake } from "@snk/compute/snake";
|
||||
import { createCanvas } from "./canvas";
|
||||
import { getBestRoute } from "../compute/getBestRoute";
|
||||
import { Color, copyGrid } from "../compute/grid";
|
||||
import { grid, snake } from "./sample";
|
||||
import { step } from "@snk/compute/step";
|
||||
import { getBestRoute } from "@snk/compute/getBestRoute";
|
||||
import { samples } from "./samples";
|
||||
|
||||
//
|
||||
// init
|
||||
|
||||
const label = new URLSearchParams(window.location.search).get("sample");
|
||||
const { grid: grid0, snake: snake0, gameOptions } =
|
||||
samples.find((s) => s.label === label) || samples[0];
|
||||
|
||||
//
|
||||
// compute
|
||||
|
||||
const s0 = Date.now();
|
||||
const bestRoute = getBestRoute(grid0, snake0, gameOptions);
|
||||
console.log(`computed in ${Date.now() - s0}ms`);
|
||||
const chain = [snake, ...getBestRoute(grid, snake)!];
|
||||
|
||||
//
|
||||
// draw
|
||||
|
||||
const { draw } = createCanvas(grid0);
|
||||
let k = 0;
|
||||
|
||||
//
|
||||
// controls
|
||||
const { canvas, draw } = createCanvas(grid);
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
const inputK: any = document.createElement("input");
|
||||
inputK.type = "range";
|
||||
inputK.style.width = "100%";
|
||||
inputK.min = 0;
|
||||
inputK.max = bestRoute.length;
|
||||
inputK.step = 1;
|
||||
inputK.value = 0;
|
||||
inputK.addEventListener("input", () => {
|
||||
const snake = copySnake(snake0);
|
||||
const grid = copyGrid(grid0);
|
||||
const stack: any[] = [];
|
||||
const onChange = () => {
|
||||
debugger;
|
||||
|
||||
for (let i = 0; i < +inputK.value; i++)
|
||||
step(grid, snake, stack, bestRoute[i], gameOptions);
|
||||
const grid0 = copyGrid(grid);
|
||||
const stack0: Color[] = [];
|
||||
let snake0 = snake;
|
||||
chain.slice(0, k).forEach((s) => {
|
||||
snake0 = s;
|
||||
step(grid0, stack0, snake0);
|
||||
});
|
||||
|
||||
draw(grid, snake, stack);
|
||||
draw(grid0, snake0, stack0);
|
||||
};
|
||||
|
||||
onChange();
|
||||
|
||||
const input = document.createElement("input") as any;
|
||||
input.type = "range";
|
||||
input.value = 0;
|
||||
input.step = 1;
|
||||
input.min = 0;
|
||||
input.max = chain.length;
|
||||
input.style.width = "90%";
|
||||
input.addEventListener("input", () => {
|
||||
k = +input.value;
|
||||
onChange();
|
||||
});
|
||||
document.body.appendChild(inputK);
|
||||
draw(grid0, snake0, []);
|
||||
document.body.append(input);
|
||||
document.body.addEventListener("click", () => input.focus());
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import { copyGrid } from "@snk/compute/grid";
|
||||
import { copySnake } from "@snk/compute/snake";
|
||||
import { createCanvas } from "./canvas";
|
||||
import { step } from "@snk/compute/step";
|
||||
import { getBestRoute } from "@snk/compute/getBestRoute";
|
||||
import { samples } from "./samples";
|
||||
|
||||
//
|
||||
// init
|
||||
|
||||
const label = "realistic";
|
||||
const { grid: grid0, snake: snake0, gameOptions } = samples.find(
|
||||
(s) => s.label === label
|
||||
);
|
||||
|
||||
//
|
||||
// compute
|
||||
|
||||
const s0 = performance.now();
|
||||
const bestRoute = getBestRoute(grid0, snake0, gameOptions, 120);
|
||||
console.log(performance.now() - s0);
|
||||
//
|
||||
// draw
|
||||
|
||||
const { draw } = createCanvas(grid0);
|
||||
|
||||
//
|
||||
// controls
|
||||
|
||||
const inputK: any = document.createElement("input");
|
||||
inputK.type = "range";
|
||||
inputK.style.width = "100%";
|
||||
inputK.min = 0;
|
||||
inputK.max = bestRoute.length;
|
||||
inputK.step = 1;
|
||||
inputK.value = 0;
|
||||
inputK.addEventListener("input", () => {
|
||||
const snake = copySnake(snake0);
|
||||
const grid = copyGrid(grid0);
|
||||
const stack: any[] = [];
|
||||
|
||||
for (let i = 0; i < +inputK.value; i++)
|
||||
step(grid, snake, stack, bestRoute[i], gameOptions);
|
||||
|
||||
draw(grid, snake, stack);
|
||||
});
|
||||
document.body.appendChild(inputK);
|
||||
draw(grid0, snake0, []);
|
||||
14
packages/demo/sample.ts
Normal file
14
packages/demo/sample.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Grid } from "@snk/compute/grid";
|
||||
import { Snake } from "@snk/compute/snake";
|
||||
import * as grids from "@snk/compute/__fixtures__/grid";
|
||||
import * as snakes from "@snk/compute/__fixtures__/snake";
|
||||
|
||||
const sp = new URLSearchParams(window.location.search);
|
||||
|
||||
const gLabel = sp.get("grid") || "simple";
|
||||
const sLabel = sp.get("snake") || "snake3";
|
||||
|
||||
//@ts-ignore
|
||||
export const grid: Grid = grids[gLabel] || grids.simple;
|
||||
//@ts-ignore
|
||||
export const snake: Snake = snakes[sLabel] || snakes.snake3;
|
||||
@@ -1,85 +0,0 @@
|
||||
// @ts-ignore
|
||||
import * as ParkMiller from "park-miller";
|
||||
import { generateRandomGrid } from "@snk/compute/generateGrid";
|
||||
import { createEmptyGrid, setColor } from "@snk/compute/grid";
|
||||
|
||||
export const samples: any[] = [];
|
||||
|
||||
{
|
||||
const gameOptions = {
|
||||
colors: [1, 2, 3],
|
||||
maxSnakeLength: 1,
|
||||
};
|
||||
const snake = [{ x: 0, y: -1 }];
|
||||
const grid = createEmptyGrid(6, 6);
|
||||
samples.push({
|
||||
label: "empty",
|
||||
grid,
|
||||
snake,
|
||||
gameOptions,
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const gameOptions = {
|
||||
colors: [1, 2, 3],
|
||||
maxSnakeLength: 1,
|
||||
};
|
||||
const snake = [{ x: 0, y: -1 }];
|
||||
const grid = createEmptyGrid(6, 6);
|
||||
setColor(grid, 2, 2, 2);
|
||||
samples.push({
|
||||
label: "small",
|
||||
grid,
|
||||
snake,
|
||||
gameOptions,
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const gameOptions = {
|
||||
colors: [1, 2, 3],
|
||||
maxSnakeLength: 5,
|
||||
};
|
||||
const random = new ParkMiller(10);
|
||||
const rand = (a: number, b: number) => random.integerInRange(a, b - 1);
|
||||
const grid = generateRandomGrid(52, 7, { ...gameOptions, emptyP: 2 }, rand);
|
||||
const snake = [
|
||||
{ x: 4, y: -1 },
|
||||
{ x: 3, y: -1 },
|
||||
{ x: 2, y: -1 },
|
||||
{ x: 1, y: -1 },
|
||||
{ x: 0, y: -1 },
|
||||
];
|
||||
|
||||
samples.push({
|
||||
label: "realistic",
|
||||
grid,
|
||||
snake,
|
||||
gameOptions,
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const gameOptions = {
|
||||
colors: [1, 2, 3],
|
||||
maxSnakeLength: 5,
|
||||
};
|
||||
const random = new ParkMiller(10);
|
||||
const rand = (a: number, b: number) => random.integerInRange(a, b - 1);
|
||||
const grid = generateRandomGrid(20, 7, { ...gameOptions, emptyP: 2 }, rand);
|
||||
const snake = [
|
||||
{ x: 4, y: -1 },
|
||||
{ x: 3, y: -1 },
|
||||
{ x: 2, y: -1 },
|
||||
{ x: 1, y: -1 },
|
||||
{ x: 0, y: -1 },
|
||||
];
|
||||
|
||||
samples.push({
|
||||
label: "realistic-small",
|
||||
grid,
|
||||
snake,
|
||||
gameOptions,
|
||||
});
|
||||
}
|
||||
@@ -13,7 +13,6 @@ const config: Configuration = {
|
||||
entry: {
|
||||
"demo.getAvailableRoutes": "./demo.getAvailableRoutes",
|
||||
"demo.getBestRoute": "./demo.getBestRoute",
|
||||
"demo.index": "./demo.index",
|
||||
},
|
||||
resolve: { extensions: [".ts", ".js"] },
|
||||
output: {
|
||||
@@ -27,14 +26,16 @@ const config: Configuration = {
|
||||
exclude: /node_modules/,
|
||||
test: /\.(js|ts)$/,
|
||||
loader: "ts-loader",
|
||||
options: {
|
||||
compilerOptions: {
|
||||
lib: ["dom", "ES2020"],
|
||||
target: "ES2020",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
filename: "index.html",
|
||||
chunks: ["demo.index"],
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
filename: "demo-getAvailableRoutes.html",
|
||||
chunks: ["demo.getAvailableRoutes"],
|
||||
|
||||
Reference in New Issue
Block a user