🔨 rename package compute -> solver
This commit is contained in:
81
packages/solver/tunnel.ts
Normal file
81
packages/solver/tunnel.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { getColor, isEmpty, isInside } from "@snk/types/grid";
|
||||
import { getHeadX, getHeadY, nextSnake } from "@snk/types/snake";
|
||||
import type { Snake } from "@snk/types/snake";
|
||||
import type { Grid } from "@snk/types/grid";
|
||||
import type { Point } from "@snk/types/point";
|
||||
|
||||
/**
|
||||
* get the sequence of snake to cross the tunnel
|
||||
*/
|
||||
export const getTunnelPath = (snake0: Snake, tunnel: Point[]) => {
|
||||
const chain: Snake[] = [];
|
||||
let snake = snake0;
|
||||
|
||||
for (let i = 1; i < tunnel.length; i++) {
|
||||
const dx = tunnel[i].x - getHeadX(snake);
|
||||
const dy = tunnel[i].y - getHeadY(snake);
|
||||
snake = nextSnake(snake, dx, dy);
|
||||
chain.unshift(snake);
|
||||
}
|
||||
|
||||
return chain;
|
||||
};
|
||||
|
||||
/**
|
||||
* assuming the grid change and the colors got deleted, update the tunnel
|
||||
*/
|
||||
export const updateTunnel = (
|
||||
grid: Grid,
|
||||
tunnel: Point[],
|
||||
toDelete: Point[]
|
||||
) => {
|
||||
while (tunnel.length) {
|
||||
const { x, y } = tunnel[0];
|
||||
if (
|
||||
isEmptySafe(grid, x, y) ||
|
||||
toDelete.some((p) => p.x === x && p.y === y)
|
||||
) {
|
||||
tunnel.shift();
|
||||
} else break;
|
||||
}
|
||||
|
||||
while (tunnel.length) {
|
||||
const { x, y } = tunnel[tunnel.length - 1];
|
||||
if (
|
||||
isEmptySafe(grid, x, y) ||
|
||||
toDelete.some((p) => p.x === x && p.y === y)
|
||||
) {
|
||||
tunnel.pop();
|
||||
} else break;
|
||||
}
|
||||
};
|
||||
|
||||
const isEmptySafe = (grid: Grid, x: number, y: number) =>
|
||||
!isInside(grid, x, y) || isEmpty(getColor(grid, x, y));
|
||||
|
||||
/**
|
||||
* remove empty cell from start
|
||||
*/
|
||||
export const trimTunnelStart = (grid: Grid, tunnel: Point[]) => {
|
||||
while (tunnel.length) {
|
||||
const { x, y } = tunnel[0];
|
||||
if (isEmptySafe(grid, x, y)) tunnel.shift();
|
||||
else break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* remove empty cell from end
|
||||
*/
|
||||
export const trimTunnelEnd = (grid: Grid, tunnel: Point[]) => {
|
||||
while (tunnel.length) {
|
||||
const i = tunnel.length - 1;
|
||||
const { x, y } = tunnel[i];
|
||||
if (
|
||||
isEmptySafe(grid, x, y) ||
|
||||
tunnel.findIndex((p) => p.x === x && p.y === y) < i
|
||||
)
|
||||
tunnel.pop();
|
||||
else break;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user