🚀 improve clean layer
This commit is contained in:
59
packages/compute/cleanLayer-monobranch.ts
Normal file
59
packages/compute/cleanLayer-monobranch.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* clean layer is too expensive with solution branching
|
||||
* do not branch for faster result ( at the cost of finding a minimal step number )
|
||||
*/
|
||||
|
||||
import { copyGrid, setColorEmpty } from "@snk/types/grid";
|
||||
import { getHeadX, getHeadY } from "@snk/types/snake";
|
||||
import { getAvailableRoutes } from "./getAvailableRoutes";
|
||||
import type { Snake } from "@snk/types/snake";
|
||||
import type { Grid } from "@snk/types/grid";
|
||||
import type { Point } from "@snk/types/point";
|
||||
|
||||
export const getAvailableWhiteListedRoute = (
|
||||
grid: Grid,
|
||||
snake: Snake,
|
||||
whiteList: Point[]
|
||||
) => {
|
||||
let solution: Snake[] | null;
|
||||
|
||||
getAvailableRoutes(grid, snake, (chain) => {
|
||||
const hx = getHeadX(chain[0]);
|
||||
const hy = getHeadY(chain[0]);
|
||||
|
||||
if (!whiteList.some(({ x, y }) => hx === x && hy === y)) return false;
|
||||
|
||||
solution = chain;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
return solution;
|
||||
};
|
||||
|
||||
export const cleanLayer = (grid0: Grid, snake0: Snake, chunk0: Point[]) => {
|
||||
const chunk = chunk0.slice();
|
||||
const grid = copyGrid(grid0);
|
||||
let snake = snake0;
|
||||
const chain: Snake[] = [];
|
||||
|
||||
while (chunk.length) {
|
||||
const chainN = getAvailableWhiteListedRoute(grid, snake, chunk);
|
||||
|
||||
if (!chainN) throw new Error("some cells are unreachable");
|
||||
|
||||
chain.unshift(...chainN);
|
||||
snake = chain[0];
|
||||
|
||||
const x = getHeadX(snake);
|
||||
const y = getHeadY(snake);
|
||||
|
||||
setColorEmpty(grid, x, y);
|
||||
|
||||
const i = chunk.findIndex((c) => c.x === x && c.y === y);
|
||||
chunk.splice(i, 1);
|
||||
}
|
||||
|
||||
return chain;
|
||||
};
|
||||
@@ -30,28 +30,6 @@ const createGetHeuristic = (grid: Grid, chunk0: Point[]) => {
|
||||
return (chunk: any[]) => chunk.length * k;
|
||||
};
|
||||
|
||||
export const getAvailableWhiteListedRoutes = (
|
||||
grid: Grid,
|
||||
snake: Snake,
|
||||
whiteList: Point[]
|
||||
) => {
|
||||
let solution: Snake[] | null;
|
||||
|
||||
getAvailableRoutes(grid, snake, (chain) => {
|
||||
const hx = getHeadX(chain[0]);
|
||||
const hy = getHeadY(chain[0]);
|
||||
|
||||
if (!whiteList.some(({ x, y }) => hx === x && hy === y)) return false;
|
||||
|
||||
solution = chain;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
return solution;
|
||||
};
|
||||
|
||||
export const cleanLayer = (grid0: Grid, snake0: Snake, chunk0: Point[]) => {
|
||||
const getH = createGetHeuristic(grid0, chunk0);
|
||||
|
||||
@@ -74,9 +52,9 @@ export const cleanLayer = (grid0: Grid, snake0: Snake, chunk0: Point[]) => {
|
||||
|
||||
if (o.chunk.length === 0) return unwrap(o).slice(0, -1);
|
||||
|
||||
const chain = getAvailableWhiteListedRoutes(o.grid, o.snake, o.chunk);
|
||||
const chains = getAvailableWhiteListedRoutes(o.grid, o.snake, o.chunk);
|
||||
|
||||
if (chain) {
|
||||
for (const chain of chains) {
|
||||
const snake = chain[0];
|
||||
const x = getHeadX(snake);
|
||||
const y = getHeadY(snake);
|
||||
@@ -101,32 +79,34 @@ export const cleanLayer = (grid0: Grid, snake0: Snake, chunk0: Point[]) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error("some cells are unreachable");
|
||||
};
|
||||
|
||||
// export const getAvailableWhiteListedRoutes = (
|
||||
// grid: Grid,
|
||||
// snake: Snake,
|
||||
// whiteList0: Point[],
|
||||
// n = 3
|
||||
// ) => {
|
||||
// const whiteList = whiteList0.slice();
|
||||
// const solutions: Snake[][] = [];
|
||||
export const getAvailableWhiteListedRoutes = (
|
||||
grid: Grid,
|
||||
snake: Snake,
|
||||
whiteList0: Point[],
|
||||
n = 3
|
||||
) => {
|
||||
const whiteList = whiteList0.slice();
|
||||
const solutions: Snake[][] = [];
|
||||
|
||||
// getAvailableRoutes(grid, snake, (chain) => {
|
||||
// const hx = getHeadX(chain[0]);
|
||||
// const hy = getHeadY(chain[0]);
|
||||
getAvailableRoutes(grid, snake, (chain) => {
|
||||
const hx = getHeadX(chain[0]);
|
||||
const hy = getHeadY(chain[0]);
|
||||
|
||||
// const i = whiteList.findIndex(({ x, y }) => hx === x && hy === y);
|
||||
const i = whiteList.findIndex(({ x, y }) => hx === x && hy === y);
|
||||
|
||||
// if (i >= 0) {
|
||||
// whiteList.splice(i, 1);
|
||||
// solutions.push(chain);
|
||||
if (i >= 0) {
|
||||
whiteList.splice(i, 1);
|
||||
solutions.push(chain);
|
||||
|
||||
// if (solutions.length >= n || whiteList.length === 0) return true;
|
||||
// }
|
||||
if (solutions.length >= n || whiteList.length === 0) return true;
|
||||
}
|
||||
|
||||
// return false;
|
||||
// });
|
||||
return false;
|
||||
});
|
||||
|
||||
// return solutions;
|
||||
// };
|
||||
return solutions;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { copyGrid, isEmpty } from "@snk/types/grid";
|
||||
import { pruneLayer } from "./pruneLayer";
|
||||
import { cleanLayer } from "./cleanLayer";
|
||||
import { cleanLayer } from "./cleanLayer-monobranch";
|
||||
import type { Snake } from "@snk/types/snake";
|
||||
import type { Color, Grid } from "@snk/types/grid";
|
||||
|
||||
@@ -15,8 +15,7 @@ export const getBestRoute = (grid0: Grid, snake0: Snake) => {
|
||||
const gridN = copyGrid(grid);
|
||||
const chunk = pruneLayer(grid, color, snakeN);
|
||||
const c = cleanLayer(gridN, chain[0], chunk);
|
||||
if (c) chain.unshift(...c);
|
||||
else throw new Error("some cells are unreachable");
|
||||
chain.unshift(...c);
|
||||
}
|
||||
|
||||
return chain.reverse().slice(1);
|
||||
|
||||
Reference in New Issue
Block a user