🚀 improve clean layer

This commit is contained in:
platane
2020-10-24 11:19:49 +02:00
parent 4f9ff10741
commit b9c67baa6a
3 changed files with 86 additions and 48 deletions

View 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;
};

View File

@@ -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;
};

View File

@@ -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);