⬆️ update prettier
This commit is contained in:
4
bun.lock
4
bun.lock
@@ -5,7 +5,7 @@
|
|||||||
"name": "snk",
|
"name": "snk",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "1.2.2",
|
"@types/bun": "1.2.2",
|
||||||
"prettier": "2.8.8",
|
"prettier": "3.5.1",
|
||||||
"typescript": "5.7.3",
|
"typescript": "5.7.3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1001,7 +1001,7 @@
|
|||||||
|
|
||||||
"prepend-http": ["prepend-http@1.0.4", "", {}, "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg=="],
|
"prepend-http": ["prepend-http@1.0.4", "", {}, "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg=="],
|
||||||
|
|
||||||
"prettier": ["prettier@2.8.8", "", { "bin": { "prettier": "bin-prettier.js" } }, "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="],
|
"prettier": ["prettier@3.5.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw=="],
|
||||||
|
|
||||||
"pretty-error": ["pretty-error@4.0.0", "", { "dependencies": { "lodash": "^4.17.20", "renderkid": "^3.0.0" } }, "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw=="],
|
"pretty-error": ["pretty-error@4.0.0", "", { "dependencies": { "lodash": "^4.17.20", "renderkid": "^3.0.0" } }, "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw=="],
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"repository": "github:platane/snk",
|
"repository": "github:platane/snk",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "1.2.2",
|
"@types/bun": "1.2.2",
|
||||||
"prettier": "2.8.8",
|
"prettier": "3.5.1",
|
||||||
"typescript": "5.7.3"
|
"typescript": "5.7.3"
|
||||||
},
|
},
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
|
|||||||
@@ -41,5 +41,5 @@ it(
|
|||||||
fs.writeFileSync(outputs[1]!.filename, results[1]!);
|
fs.writeFileSync(outputs[1]!.filename, results[1]!);
|
||||||
fs.writeFileSync(outputs[2]!.filename, results[2]!);
|
fs.writeFileSync(outputs[2]!.filename, results[2]!);
|
||||||
}),
|
}),
|
||||||
{ timeout: 2 * 60 * 1000 }
|
{ timeout: 2 * 60 * 1000 },
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,42 +3,42 @@ import { it, expect } from "bun:test";
|
|||||||
|
|
||||||
it("should parse options as json", () => {
|
it("should parse options as json", () => {
|
||||||
expect(
|
expect(
|
||||||
parseEntry(`/out.svg {"color_snake":"yellow"}`)?.drawOptions
|
parseEntry(`/out.svg {"color_snake":"yellow"}`)?.drawOptions,
|
||||||
).toHaveProperty("colorSnake", "yellow");
|
).toHaveProperty("colorSnake", "yellow");
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
parseEntry(`/out.svg?{"color_snake":"yellow"}`)?.drawOptions
|
parseEntry(`/out.svg?{"color_snake":"yellow"}`)?.drawOptions,
|
||||||
).toHaveProperty("colorSnake", "yellow");
|
).toHaveProperty("colorSnake", "yellow");
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
parseEntry(`/out.svg?{"color_dots":["#000","#111","#222","#333","#444"]}`)
|
parseEntry(`/out.svg?{"color_dots":["#000","#111","#222","#333","#444"]}`)
|
||||||
?.drawOptions.colorDots
|
?.drawOptions.colorDots,
|
||||||
).toEqual(["#000", "#111", "#222", "#333", "#444"]);
|
).toEqual(["#000", "#111", "#222", "#333", "#444"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse options as searchparams", () => {
|
it("should parse options as searchparams", () => {
|
||||||
expect(parseEntry(`/out.svg?color_snake=yellow`)?.drawOptions).toHaveProperty(
|
expect(parseEntry(`/out.svg?color_snake=yellow`)?.drawOptions).toHaveProperty(
|
||||||
"colorSnake",
|
"colorSnake",
|
||||||
"yellow"
|
"yellow",
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
parseEntry(`/out.svg?color_dots=#000,#111,#222,#333,#444`)?.drawOptions
|
parseEntry(`/out.svg?color_dots=#000,#111,#222,#333,#444`)?.drawOptions
|
||||||
.colorDots
|
.colorDots,
|
||||||
).toEqual(["#000", "#111", "#222", "#333", "#444"]);
|
).toEqual(["#000", "#111", "#222", "#333", "#444"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse filename", () => {
|
it("should parse filename", () => {
|
||||||
expect(parseEntry(`/a/b/c.svg?{"color_snake":"yellow"}`)).toHaveProperty(
|
expect(parseEntry(`/a/b/c.svg?{"color_snake":"yellow"}`)).toHaveProperty(
|
||||||
"filename",
|
"filename",
|
||||||
"/a/b/c.svg"
|
"/a/b/c.svg",
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
parseEntry(`/a/b/out.svg?.gif.svg?{"color_snake":"yellow"}`)
|
parseEntry(`/a/b/out.svg?.gif.svg?{"color_snake":"yellow"}`),
|
||||||
).toHaveProperty("filename", "/a/b/out.svg?.gif.svg");
|
).toHaveProperty("filename", "/a/b/out.svg?.gif.svg");
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
parseEntry(`/a/b/{[-1].svg?.gif.svg?{"color_snake":"yellow"}`)
|
parseEntry(`/a/b/{[-1].svg?.gif.svg?{"color_snake":"yellow"}`),
|
||||||
).toHaveProperty("filename", "/a/b/{[-1].svg?.gif.svg");
|
).toHaveProperty("filename", "/a/b/{[-1].svg?.gif.svg");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -57,5 +57,5 @@ it("should parse filename", () => {
|
|||||||
].forEach((entry) =>
|
].forEach((entry) =>
|
||||||
it(`should parse ${entry}`, () => {
|
it(`should parse ${entry}`, () => {
|
||||||
expect(parseEntry(entry)).toMatchSnapshot();
|
expect(parseEntry(entry)).toMatchSnapshot();
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export const generateContributionSnake = async (
|
|||||||
drawOptions: DrawOptions;
|
drawOptions: DrawOptions;
|
||||||
animationOptions: AnimationOptions;
|
animationOptions: AnimationOptions;
|
||||||
} | null)[],
|
} | null)[],
|
||||||
options: { githubToken: string }
|
options: { githubToken: string },
|
||||||
) => {
|
) => {
|
||||||
console.log("🎣 fetching github user contribution");
|
console.log("🎣 fetching github user contribution");
|
||||||
const cells = await getGithubUserContribution(userName, options);
|
const cells = await getGithubUserContribution(userName, options);
|
||||||
@@ -43,10 +43,10 @@ export const generateContributionSnake = async (
|
|||||||
cells,
|
cells,
|
||||||
chain,
|
chain,
|
||||||
drawOptions,
|
drawOptions,
|
||||||
animationOptions
|
animationOptions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { parseOutputsOption } from "./outputsOptions";
|
|||||||
core.getMultilineInput("outputs") ?? [
|
core.getMultilineInput("outputs") ?? [
|
||||||
core.getInput("gif_out_path"),
|
core.getInput("gif_out_path"),
|
||||||
core.getInput("svg_out_path"),
|
core.getInput("svg_out_path"),
|
||||||
]
|
],
|
||||||
);
|
);
|
||||||
const githubToken =
|
const githubToken =
|
||||||
process.env.GITHUB_TOKEN ?? core.getInput("github_token");
|
process.env.GITHUB_TOKEN ?? core.getInput("github_token");
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export const createCanvas = ({
|
|||||||
snake0: Snake,
|
snake0: Snake,
|
||||||
snake1: Snake,
|
snake1: Snake,
|
||||||
stack: Color[],
|
stack: Color[],
|
||||||
k: number
|
k: number,
|
||||||
) => {
|
) => {
|
||||||
ctx.clearRect(0, 0, 9999, 9999);
|
ctx.clearRect(0, 0, 9999, 9999);
|
||||||
drawLerpWorld(ctx, grid, null, snake0, snake1, stack, k, drawOptions);
|
drawLerpWorld(ctx, grid, null, snake0, snake1, stack, k, drawOptions);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const tunnels = ones.map(({ x, y }) => ({
|
|||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
3 as Color,
|
3 as Color,
|
||||||
getSnakeLength(snake)
|
getSnakeLength(snake),
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const { canvas, ctx, draw, highlightCell } = createCanvas(grid);
|
|||||||
canvas.style.pointerEvents = "auto";
|
canvas.style.pointerEvents = "auto";
|
||||||
|
|
||||||
const target = createSnakeFromCells(
|
const target = createSnakeFromCells(
|
||||||
snakeToCells(snake).map((p) => ({ ...p, x: p.x - 1 }))
|
snakeToCells(snake).map((p) => ({ ...p, x: p.x - 1 })),
|
||||||
);
|
);
|
||||||
|
|
||||||
let chain = [snake, ...getPathToPose(snake, target)!];
|
let chain = [snake, ...getPathToPose(snake, target)!];
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ const createViewer = ({
|
|||||||
: "") +
|
: "") +
|
||||||
`<a href="${svgLink.href}" download="github-user-contribution.svg">` +
|
`<a href="${svgLink.href}" download="github-user-contribution.svg">` +
|
||||||
svgString +
|
svgString +
|
||||||
"<a/>"
|
"<a/>",
|
||||||
);
|
);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
@@ -277,7 +277,7 @@ const createViewer = ({
|
|||||||
|
|
||||||
const onSubmit = async (userName: string) => {
|
const onSubmit = async (userName: string) => {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
process.env.GITHUB_USER_CONTRIBUTION_API_ENDPOINT + userName
|
process.env.GITHUB_USER_CONTRIBUTION_API_ENDPOINT + userName,
|
||||||
);
|
);
|
||||||
const cells = (await res.json()) as Res;
|
const cells = (await res.json()) as Res;
|
||||||
|
|
||||||
@@ -294,8 +294,8 @@ const worker = new Worker(
|
|||||||
new URL(
|
new URL(
|
||||||
"./demo.interactive.worker.ts",
|
"./demo.interactive.worker.ts",
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import.meta.url
|
import.meta.url,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { getChain } = createRpcClient<WorkerAPI>(worker);
|
const { getChain } = createRpcClient<WorkerAPI>(worker);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const onChange = () => {
|
|||||||
|
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
config.demo + ".html?" + search,
|
config.demo + ".html?" + search,
|
||||||
window.location.href
|
window.location.href,
|
||||||
).toString();
|
).toString();
|
||||||
|
|
||||||
window.location.href = url;
|
window.location.href = url;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const stepSpringOne = (
|
|||||||
maxVelocity = Infinity,
|
maxVelocity = Infinity,
|
||||||
}: { tension: number; friction: number; maxVelocity?: number },
|
}: { tension: number; friction: number; maxVelocity?: number },
|
||||||
target: number,
|
target: number,
|
||||||
dt = 1 / 60
|
dt = 1 / 60,
|
||||||
) => {
|
) => {
|
||||||
const a = -tension * (s.x - target) - friction * s.v;
|
const a = -tension * (s.x - target) - friction * s.v;
|
||||||
|
|
||||||
@@ -31,13 +31,13 @@ const stepSpringOne = (
|
|||||||
export const isStable = (
|
export const isStable = (
|
||||||
s: { x: number; v: number },
|
s: { x: number; v: number },
|
||||||
target: number,
|
target: number,
|
||||||
dt = 1 / 60
|
dt = 1 / 60,
|
||||||
) => Math.abs(s.x - target) < epsilon && Math.abs(s.v * dt) < epsilon;
|
) => Math.abs(s.x - target) < epsilon && Math.abs(s.v * dt) < epsilon;
|
||||||
|
|
||||||
export const isStableAndBound = (
|
export const isStableAndBound = (
|
||||||
s: { x: number; v: number },
|
s: { x: number; v: number },
|
||||||
target: number,
|
target: number,
|
||||||
dt?: number
|
dt?: number,
|
||||||
) => {
|
) => {
|
||||||
const stable = isStable(s, target, dt);
|
const stable = isStable(s, target, dt);
|
||||||
if (stable) {
|
if (stable) {
|
||||||
@@ -51,7 +51,7 @@ export const stepSpring = (
|
|||||||
s: { x: number; v: number },
|
s: { x: number; v: number },
|
||||||
params: { tension: number; friction: number; maxVelocity?: number },
|
params: { tension: number; friction: number; maxVelocity?: number },
|
||||||
target: number,
|
target: number,
|
||||||
dt = 1 / 60
|
dt = 1 / 60,
|
||||||
) => {
|
) => {
|
||||||
const interval = 1 / 60;
|
const interval = 1 / 60;
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ const webpackDevServerConfiguration: WebpackDevServerConfiguration = {
|
|||||||
...ms,
|
...ms,
|
||||||
(async (req, res, next) => {
|
(async (req, res, next) => {
|
||||||
const userName = req.url.match(
|
const userName = req.url.match(
|
||||||
/\/api\/github-user-contribution\/(\w+)/
|
/\/api\/github-user-contribution\/(\w+)/,
|
||||||
)?.[1];
|
)?.[1];
|
||||||
if (userName)
|
if (userName)
|
||||||
res.send(
|
res.send(
|
||||||
await getGithubUserContribution(userName, {
|
await getGithubUserContribution(userName, {
|
||||||
githubToken: process.env.GITHUB_TOKEN!,
|
githubToken: process.env.GITHUB_TOKEN!,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
else next();
|
else next();
|
||||||
}) as ExpressRequestHandler,
|
}) as ExpressRequestHandler,
|
||||||
@@ -34,7 +34,7 @@ const webpackDevServerConfiguration: WebpackDevServerConfiguration = {
|
|||||||
const webpackConfiguration: WebpackConfiguration = {
|
const webpackConfiguration: WebpackConfiguration = {
|
||||||
mode: "development",
|
mode: "development",
|
||||||
entry: Object.fromEntries(
|
entry: Object.fromEntries(
|
||||||
demos.map((demo: string) => [demo, `./demo.${demo}`])
|
demos.map((demo: string) => [demo, `./demo.${demo}`]),
|
||||||
),
|
),
|
||||||
target: ["web", "es2019"],
|
target: ["web", "es2019"],
|
||||||
resolve: { extensions: [".ts", ".js"] },
|
resolve: { extensions: [".ts", ".js"] },
|
||||||
@@ -65,7 +65,7 @@ const webpackConfiguration: WebpackConfiguration = {
|
|||||||
title: "snk - " + demo,
|
title: "snk - " + demo,
|
||||||
filename: `${demo}.html`,
|
filename: `${demo}.html`,
|
||||||
chunks: [demo],
|
chunks: [demo],
|
||||||
})
|
}),
|
||||||
),
|
),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
title: "snk - " + demos[0],
|
title: "snk - " + demos[0],
|
||||||
|
|||||||
@@ -54,6 +54,6 @@ export const createRpcClient = <API_ extends API>(worker: Worker) => {
|
|||||||
worker.addEventListener("terminate", onTerminate);
|
worker.addEventListener("terminate", onTerminate);
|
||||||
worker.postMessage({ symbol, key, methodName, args });
|
worker.postMessage({ symbol, key, methodName, args });
|
||||||
}),
|
}),
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export const getCircleSize = (n: number) => {
|
|||||||
export const drawCircleStack = (
|
export const drawCircleStack = (
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
stack: Color[],
|
stack: Color[],
|
||||||
o: Options
|
o: Options,
|
||||||
) => {
|
) => {
|
||||||
for (let i = stack.length; i--; ) {
|
for (let i = stack.length; i--; ) {
|
||||||
const { x, y } = cellPath[i];
|
const { x, y } = cellPath[i];
|
||||||
@@ -67,7 +67,7 @@ export const drawCircleStack = (
|
|||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.translate(
|
ctx.translate(
|
||||||
x * o.sizeCell + (o.sizeCell - o.sizeDot) / 2,
|
x * o.sizeCell + (o.sizeCell - o.sizeDot) / 2,
|
||||||
y * o.sizeCell + (o.sizeCell - o.sizeDot) / 2
|
y * o.sizeCell + (o.sizeCell - o.sizeDot) / 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const drawGrid = (
|
|||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
grid: Grid,
|
grid: Grid,
|
||||||
cells: Point[] | null,
|
cells: Point[] | null,
|
||||||
o: Options
|
o: Options,
|
||||||
) => {
|
) => {
|
||||||
for (let x = grid.width; x--; )
|
for (let x = grid.width; x--; )
|
||||||
for (let y = grid.height; y--; ) {
|
for (let y = grid.height; y--; ) {
|
||||||
@@ -27,7 +27,7 @@ export const drawGrid = (
|
|||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.translate(
|
ctx.translate(
|
||||||
x * o.sizeCell + (o.sizeCell - o.sizeDot) / 2,
|
x * o.sizeCell + (o.sizeCell - o.sizeDot) / 2,
|
||||||
y * o.sizeCell + (o.sizeCell - o.sizeDot) / 2
|
y * o.sizeCell + (o.sizeCell - o.sizeDot) / 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
ctx.fillStyle = color;
|
ctx.fillStyle = color;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ type Options = {
|
|||||||
export const drawSnake = (
|
export const drawSnake = (
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
snake: Snake,
|
snake: Snake,
|
||||||
o: Options
|
o: Options,
|
||||||
) => {
|
) => {
|
||||||
const cells = snakeToCells(snake);
|
const cells = snakeToCells(snake);
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ export const drawSnake = (
|
|||||||
ctx,
|
ctx,
|
||||||
o.sizeCell - u * 2,
|
o.sizeCell - u * 2,
|
||||||
o.sizeCell - u * 2,
|
o.sizeCell - u * 2,
|
||||||
(o.sizeCell - u * 2) * 0.25
|
(o.sizeCell - u * 2) * 0.25,
|
||||||
);
|
);
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
@@ -40,7 +40,7 @@ export const drawSnakeLerp = (
|
|||||||
snake0: Snake,
|
snake0: Snake,
|
||||||
snake1: Snake,
|
snake1: Snake,
|
||||||
k: number,
|
k: number,
|
||||||
o: Options
|
o: Options,
|
||||||
) => {
|
) => {
|
||||||
const m = 0.8;
|
const m = 0.8;
|
||||||
const n = snake0.length / 2;
|
const n = snake0.length / 2;
|
||||||
@@ -61,7 +61,7 @@ export const drawSnakeLerp = (
|
|||||||
ctx,
|
ctx,
|
||||||
o.sizeCell - u * 2,
|
o.sizeCell - u * 2,
|
||||||
o.sizeCell - u * 2,
|
o.sizeCell - u * 2,
|
||||||
(o.sizeCell - u * 2) * 0.25
|
(o.sizeCell - u * 2) * 0.25,
|
||||||
);
|
);
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const drawStack = (
|
|||||||
stack: Color[],
|
stack: Color[],
|
||||||
max: number,
|
max: number,
|
||||||
width: number,
|
width: number,
|
||||||
o: { colorDots: Record<Color, string> }
|
o: { colorDots: Record<Color, string> },
|
||||||
) => {
|
) => {
|
||||||
ctx.save();
|
ctx.save();
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ export const drawWorld = (
|
|||||||
cells: Point[] | null,
|
cells: Point[] | null,
|
||||||
snake: Snake,
|
snake: Snake,
|
||||||
stack: Color[],
|
stack: Color[],
|
||||||
o: Options
|
o: Options,
|
||||||
) => {
|
) => {
|
||||||
ctx.save();
|
ctx.save();
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ export const drawLerpWorld = (
|
|||||||
snake1: Snake,
|
snake1: Snake,
|
||||||
stack: Color[],
|
stack: Color[],
|
||||||
k: number,
|
k: number,
|
||||||
o: Options
|
o: Options,
|
||||||
) => {
|
) => {
|
||||||
ctx.save();
|
ctx.save();
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ export const pathRoundedRect = (
|
|||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
borderRadius: number
|
borderRadius: number,
|
||||||
) => {
|
) => {
|
||||||
ctx.moveTo(borderRadius, 0);
|
ctx.moveTo(borderRadius, 0);
|
||||||
ctx.arcTo(width, 0, width, height, borderRadius);
|
ctx.arcTo(width, 0, width, height, borderRadius);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { getPathToPose } from "@snk/solver/getPathToPose";
|
|||||||
import type { Options as DrawOptions } from "@snk/draw/drawWorld";
|
import type { Options as DrawOptions } from "@snk/draw/drawWorld";
|
||||||
|
|
||||||
let snake = createSnakeFromCells(
|
let snake = createSnakeFromCells(
|
||||||
Array.from({ length: 4 }, (_, i) => ({ x: i, y: -1 }))
|
Array.from({ length: 4 }, (_, i) => ({ x: i, y: -1 })),
|
||||||
);
|
);
|
||||||
|
|
||||||
// const chain = [snake];
|
// const chain = [snake];
|
||||||
@@ -55,7 +55,7 @@ const animationOptions: AnimationOptions = { frameDuration: 100, step: 1 };
|
|||||||
null,
|
null,
|
||||||
chainL,
|
chainL,
|
||||||
drawOptions,
|
drawOptions,
|
||||||
animationOptions
|
animationOptions,
|
||||||
);
|
);
|
||||||
stats.push(performance.now() - s);
|
stats.push(performance.now() - s);
|
||||||
}
|
}
|
||||||
@@ -73,12 +73,12 @@ const animationOptions: AnimationOptions = { frameDuration: 100, step: 1 };
|
|||||||
})}ms`,
|
})}ms`,
|
||||||
"",
|
"",
|
||||||
].join("\n"),
|
].join("\n"),
|
||||||
stats
|
stats,
|
||||||
);
|
);
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
`__tests__/__snapshots__/benchmark-output-${length}.gif`,
|
`__tests__/__snapshots__/benchmark-output-${length}.gif`,
|
||||||
buffer!
|
buffer!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -46,14 +46,14 @@ for (const key of [
|
|||||||
null,
|
null,
|
||||||
chain,
|
chain,
|
||||||
drawOptions,
|
drawOptions,
|
||||||
animationOptions
|
animationOptions,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(gif).toBeDefined();
|
expect(gif).toBeDefined();
|
||||||
|
|
||||||
fs.writeFileSync(path.resolve(dir, key + ".gif"), gif);
|
fs.writeFileSync(path.resolve(dir, key + ".gif"), gif);
|
||||||
},
|
},
|
||||||
{ timeout: 20 * 1000 }
|
{ timeout: 20 * 1000 },
|
||||||
);
|
);
|
||||||
|
|
||||||
it(
|
it(
|
||||||
@@ -61,7 +61,7 @@ it(
|
|||||||
async () => {
|
async () => {
|
||||||
const grid = grids.smallFull;
|
const grid = grids.smallFull;
|
||||||
let snk = createSnakeFromCells(
|
let snk = createSnakeFromCells(
|
||||||
Array.from({ length: 6 }, (_, i) => ({ x: i, y: -1 }))
|
Array.from({ length: 6 }, (_, i) => ({ x: i, y: -1 })),
|
||||||
);
|
);
|
||||||
|
|
||||||
const chain = [snk];
|
const chain = [snk];
|
||||||
@@ -80,12 +80,12 @@ it(
|
|||||||
null,
|
null,
|
||||||
chain,
|
chain,
|
||||||
drawOptions,
|
drawOptions,
|
||||||
animationOptions
|
animationOptions,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(gif).toBeDefined();
|
expect(gif).toBeDefined();
|
||||||
|
|
||||||
fs.writeFileSync(path.resolve(dir, "swipper.gif"), gif);
|
fs.writeFileSync(path.resolve(dir, "swipper.gif"), gif);
|
||||||
},
|
},
|
||||||
{ timeout: 20 * 1000 }
|
{ timeout: 20 * 1000 },
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import gifsicle from "gifsicle";
|
|||||||
import GIFEncoder from "gif-encoder-2";
|
import GIFEncoder from "gif-encoder-2";
|
||||||
|
|
||||||
const withTmpDir = async <T>(
|
const withTmpDir = async <T>(
|
||||||
handler: (dir: string) => Promise<T>
|
handler: (dir: string) => Promise<T>,
|
||||||
): Promise<T> => {
|
): Promise<T> => {
|
||||||
const { name: dir, removeCallback: cleanUp } = tmp.dirSync({
|
const { name: dir, removeCallback: cleanUp } = tmp.dirSync({
|
||||||
unsafeCleanup: true,
|
unsafeCleanup: true,
|
||||||
@@ -37,7 +37,7 @@ export const createGif = async (
|
|||||||
cells: Point[] | null,
|
cells: Point[] | null,
|
||||||
chain: Snake[],
|
chain: Snake[],
|
||||||
drawOptions: DrawOptions,
|
drawOptions: DrawOptions,
|
||||||
animationOptions: AnimationOptions
|
animationOptions: AnimationOptions,
|
||||||
) =>
|
) =>
|
||||||
withTmpDir(async (dir) => {
|
withTmpDir(async (dir) => {
|
||||||
const { width, height } = getCanvasWorldSize(grid0, drawOptions);
|
const { width, height } = getCanvasWorldSize(grid0, drawOptions);
|
||||||
@@ -70,7 +70,7 @@ export const createGif = async (
|
|||||||
snake1,
|
snake1,
|
||||||
stack,
|
stack,
|
||||||
k / animationOptions.step,
|
k / animationOptions.step,
|
||||||
drawOptions
|
drawOptions,
|
||||||
);
|
);
|
||||||
|
|
||||||
encoder.addFrame(ctx);
|
encoder.addFrame(ctx);
|
||||||
@@ -92,7 +92,7 @@ export const createGif = async (
|
|||||||
"--colors=18",
|
"--colors=18",
|
||||||
outFileName,
|
outFileName,
|
||||||
["--output", optimizedFileName],
|
["--output", optimizedFileName],
|
||||||
].flat()
|
].flat(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return new Uint8Array(fs.readFileSync(optimizedFileName));
|
return new Uint8Array(fs.readFileSync(optimizedFileName));
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export default async (req: VercelRequest, res: VercelResponse) => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const allowedOrigin = allowedOrigins.find(
|
const allowedOrigin = allowedOrigins.find(
|
||||||
(o) => o === req.headers.origin
|
(o) => o === req.headers.origin,
|
||||||
);
|
);
|
||||||
if (allowedOrigin)
|
if (allowedOrigin)
|
||||||
res.setHeader("Access-Control-Allow-Origin", allowedOrigin);
|
res.setHeader("Access-Control-Allow-Origin", allowedOrigin);
|
||||||
@@ -23,7 +23,7 @@ export default async (req: VercelRequest, res: VercelResponse) => {
|
|||||||
res.json(
|
res.json(
|
||||||
await getGithubUserContribution(userName as string, {
|
await getGithubUserContribution(userName as string, {
|
||||||
githubToken: process.env.GITHUB_TOKEN!,
|
githubToken: process.env.GITHUB_TOKEN!,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
export const getGithubUserContribution = async (
|
export const getGithubUserContribution = async (
|
||||||
userName: string,
|
userName: string,
|
||||||
o: { githubToken: string }
|
o: { githubToken: string },
|
||||||
) => {
|
) => {
|
||||||
const query = /* GraphQL */ `
|
const query = /* GraphQL */ `
|
||||||
query ($login: String!) {
|
query ($login: String!) {
|
||||||
@@ -69,7 +69,7 @@ export const getGithubUserContribution = async (
|
|||||||
(d.contributionLevel === "SECOND_QUARTILE" && 2) ||
|
(d.contributionLevel === "SECOND_QUARTILE" && 2) ||
|
||||||
(d.contributionLevel === "FIRST_QUARTILE" && 1) ||
|
(d.contributionLevel === "FIRST_QUARTILE" && 1) ||
|
||||||
0,
|
0,
|
||||||
}))
|
})),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ for (const { width, height, snake } of [
|
|||||||
{ width: 5, height: 5, snake: snake4 },
|
{ width: 5, height: 5, snake: snake4 },
|
||||||
])
|
])
|
||||||
it(`should find solution for ${n} ${width}x${height} generated grids for ${getSnakeLength(
|
it(`should find solution for ${n} ${width}x${height} generated grids for ${getSnakeLength(
|
||||||
snake
|
snake,
|
||||||
)} length snake`, () => {
|
)} length snake`, () => {
|
||||||
const results = Array.from({ length: n }, (_, seed) => {
|
const results = Array.from({ length: n }, (_, seed) => {
|
||||||
const grid = createFromSeed(seed, width, height);
|
const grid = createFromSeed(seed, width, height);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export const clearCleanColoredLayer = (
|
|||||||
grid: Grid,
|
grid: Grid,
|
||||||
outside: Outside,
|
outside: Outside,
|
||||||
snake0: Snake,
|
snake0: Snake,
|
||||||
color: Color
|
color: Color,
|
||||||
) => {
|
) => {
|
||||||
const snakeN = getSnakeLength(snake0);
|
const snakeN = getSnakeLength(snake0);
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ const getPathToNextPoint = (
|
|||||||
grid: Grid,
|
grid: Grid,
|
||||||
snake0: Snake,
|
snake0: Snake,
|
||||||
color: Color,
|
color: Color,
|
||||||
points: Point[]
|
points: Point[],
|
||||||
) => {
|
) => {
|
||||||
const closeList: Snake[] = [];
|
const closeList: Snake[] = [];
|
||||||
const openList: M[] = [{ snake: snake0 } as any];
|
const openList: M[] = [{ snake: snake0 } as any];
|
||||||
@@ -96,7 +96,7 @@ export const getTunnellablePoints = (
|
|||||||
grid: Grid,
|
grid: Grid,
|
||||||
outside: Outside,
|
outside: Outside,
|
||||||
snakeN: number,
|
snakeN: number,
|
||||||
color: Color
|
color: Color,
|
||||||
) => {
|
) => {
|
||||||
const points: Point[] = [];
|
const points: Point[] = [];
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export const clearResidualColoredLayer = (
|
|||||||
grid: Grid,
|
grid: Grid,
|
||||||
outside: Outside,
|
outside: Outside,
|
||||||
snake0: Snake,
|
snake0: Snake,
|
||||||
color: Color
|
color: Color,
|
||||||
) => {
|
) => {
|
||||||
const snakeN = getSnakeLength(snake0);
|
const snakeN = getSnakeLength(snake0);
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ export const getTunnellablePoints = (
|
|||||||
grid: Grid,
|
grid: Grid,
|
||||||
outside: Outside,
|
outside: Outside,
|
||||||
snakeN: number,
|
snakeN: number,
|
||||||
color: Color
|
color: Color,
|
||||||
) => {
|
) => {
|
||||||
const points: T[] = [];
|
const points: T[] = [];
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export const getBestRoute = (grid0: Grid, snake0: Snake) => {
|
|||||||
for (const color of extractColors(grid)) {
|
for (const color of extractColors(grid)) {
|
||||||
if (color > 1)
|
if (color > 1)
|
||||||
chain.unshift(
|
chain.unshift(
|
||||||
...clearResidualColoredLayer(grid, outside, chain[0], color)
|
...clearResidualColoredLayer(grid, outside, chain[0], color),
|
||||||
);
|
);
|
||||||
chain.unshift(...clearCleanColoredLayer(grid, outside, chain[0], color));
|
chain.unshift(...clearCleanColoredLayer(grid, outside, chain[0], color));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const getSnakeEscapePath = (
|
|||||||
grid: Grid,
|
grid: Grid,
|
||||||
outside: Outside,
|
outside: Outside,
|
||||||
snake0: Snake,
|
snake0: Snake,
|
||||||
color: Color
|
color: Color,
|
||||||
) => {
|
) => {
|
||||||
const openList: M[] = [{ snake: snake0, w: 0 } as any];
|
const openList: M[] = [{ snake: snake0, w: 0 } as any];
|
||||||
const closeList: Snake[] = [];
|
const closeList: Snake[] = [];
|
||||||
@@ -79,7 +79,7 @@ export const getBestTunnel = (
|
|||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
color: Color,
|
color: Color,
|
||||||
snakeN: number
|
snakeN: number,
|
||||||
) => {
|
) => {
|
||||||
const c = { x, y };
|
const c = { x, y };
|
||||||
const snake0 = createSnakeFromCells(Array.from({ length: snakeN }, () => c));
|
const snake0 = createSnakeFromCells(Array.from({ length: snakeN }, () => c));
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export const createOutside = (grid: Grid, color: Color = 0 as Color) => {
|
|||||||
export const fillOutside = (
|
export const fillOutside = (
|
||||||
outside: Outside,
|
outside: Outside,
|
||||||
grid: Grid,
|
grid: Grid,
|
||||||
color: Color = 0 as Color
|
color: Color = 0 as Color,
|
||||||
) => {
|
) => {
|
||||||
let changed = true;
|
let changed = true;
|
||||||
while (changed) {
|
while (changed) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export const getTunnelPath = (snake0: Snake, tunnel: Point[]) => {
|
|||||||
export const updateTunnel = (
|
export const updateTunnel = (
|
||||||
grid: Grid,
|
grid: Grid,
|
||||||
tunnel: Point[],
|
tunnel: Point[],
|
||||||
toDelete: Point[]
|
toDelete: Point[],
|
||||||
) => {
|
) => {
|
||||||
while (tunnel.length) {
|
while (tunnel.length) {
|
||||||
const { x, y } = tunnel[0];
|
const { x, y } = tunnel[0];
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ for (const [key, grid] of Object.entries(grids))
|
|||||||
null,
|
null,
|
||||||
chain,
|
chain,
|
||||||
drawOptions,
|
drawOptions,
|
||||||
animationOptions
|
animationOptions,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(svg).toBeDefined();
|
expect(svg).toBeDefined();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ it("should minify css", () => {
|
|||||||
color : red ;
|
color : red ;
|
||||||
}
|
}
|
||||||
|
|
||||||
`)
|
`),
|
||||||
).toBe(".c{color:red}");
|
).toBe(".c{color:red}");
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
@@ -22,6 +22,6 @@ it("should minify css", () => {
|
|||||||
animation: linear 10;
|
animation: linear 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
`)
|
`),
|
||||||
).toBe(".c{top:0;color:red}#{animation:linear 10}");
|
).toBe(".c{top:0;color:red}#{animation:linear 10}");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const mergeKeyFrames = (keyframes: { t: number; style: string }[]) => {
|
|||||||
*/
|
*/
|
||||||
export const createAnimation = (
|
export const createAnimation = (
|
||||||
name: string,
|
name: string,
|
||||||
keyframes: { t: number; style: string }[]
|
keyframes: { t: number; style: string }[],
|
||||||
) =>
|
) =>
|
||||||
`@keyframes ${name}{` +
|
`@keyframes ${name}{` +
|
||||||
mergeKeyFrames(keyframes)
|
mergeKeyFrames(keyframes)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export type Options = {
|
|||||||
export const createGrid = (
|
export const createGrid = (
|
||||||
cells: (Point & { t: number | null; color: Color | Empty })[],
|
cells: (Point & { t: number | null; color: Color | Empty })[],
|
||||||
{ sizeDotBorderRadius, sizeDot, sizeCell }: Options,
|
{ sizeDotBorderRadius, sizeDot, sizeCell }: Options,
|
||||||
duration: number
|
duration: number,
|
||||||
) => {
|
) => {
|
||||||
const svgElements: string[] = [];
|
const svgElements: string[] = [];
|
||||||
const styles = [
|
const styles = [
|
||||||
@@ -48,7 +48,7 @@ export const createGrid = (
|
|||||||
`.c.${id}{
|
`.c.${id}{
|
||||||
fill: var(--c${color});
|
fill: var(--c${color});
|
||||||
animation-name: ${animationName}
|
animation-name: ${animationName}
|
||||||
}`
|
}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ export const createGrid = (
|
|||||||
y: y * sizeCell + m,
|
y: y * sizeCell + m,
|
||||||
rx: sizeDotBorderRadius,
|
rx: sizeDotBorderRadius,
|
||||||
ry: sizeDotBorderRadius,
|
ry: sizeDotBorderRadius,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ export type DrawOptions = {
|
|||||||
|
|
||||||
const getCellsFromGrid = ({ width, height }: Grid) =>
|
const getCellsFromGrid = ({ width, height }: Grid) =>
|
||||||
Array.from({ length: width }, (_, x) =>
|
Array.from({ length: width }, (_, x) =>
|
||||||
Array.from({ length: height }, (_, y) => ({ x, y }))
|
Array.from({ length: height }, (_, y) => ({ x, y })),
|
||||||
).flat();
|
).flat();
|
||||||
|
|
||||||
const createLivingCells = (
|
const createLivingCells = (
|
||||||
grid0: Grid,
|
grid0: Grid,
|
||||||
chain: Snake[],
|
chain: Snake[],
|
||||||
cells: Point[] | null
|
cells: Point[] | null,
|
||||||
) => {
|
) => {
|
||||||
const livingCells: (Point & {
|
const livingCells: (Point & {
|
||||||
t: number | null;
|
t: number | null;
|
||||||
@@ -73,7 +73,7 @@ export const createSvg = (
|
|||||||
cells: Point[] | null,
|
cells: Point[] | null,
|
||||||
chain: Snake[],
|
chain: Snake[],
|
||||||
drawOptions: DrawOptions,
|
drawOptions: DrawOptions,
|
||||||
animationOptions: Pick<AnimationOptions, "frameDuration">
|
animationOptions: Pick<AnimationOptions, "frameDuration">,
|
||||||
) => {
|
) => {
|
||||||
const width = (grid.width + 2) * drawOptions.sizeCell;
|
const width = (grid.width + 2) * drawOptions.sizeCell;
|
||||||
const height = (grid.height + 5) * drawOptions.sizeCell;
|
const height = (grid.height + 5) * drawOptions.sizeCell;
|
||||||
@@ -89,7 +89,7 @@ export const createSvg = (
|
|||||||
drawOptions,
|
drawOptions,
|
||||||
grid.width * drawOptions.sizeCell,
|
grid.width * drawOptions.sizeCell,
|
||||||
(grid.height + 2) * drawOptions.sizeCell,
|
(grid.height + 2) * drawOptions.sizeCell,
|
||||||
duration
|
duration,
|
||||||
),
|
),
|
||||||
createSnake(chain, drawOptions, duration),
|
createSnake(chain, drawOptions, duration),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const lerp = (k: number, a: number, b: number) => (1 - k) * a + k * b;
|
|||||||
export const createSnake = (
|
export const createSnake = (
|
||||||
chain: Snake[],
|
chain: Snake[],
|
||||||
{ sizeCell, sizeDot }: Options,
|
{ sizeCell, sizeDot }: Options,
|
||||||
duration: number
|
duration: number,
|
||||||
) => {
|
) => {
|
||||||
const snakeN = chain[0] ? getSnakeLength(chain[0]) : 0;
|
const snakeN = chain[0] ? getSnakeLength(chain[0]) : 0;
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ export const createSnake = (
|
|||||||
const animationName = id;
|
const animationName = id;
|
||||||
|
|
||||||
const keyframes = removeInterpolatedPositions(
|
const keyframes = removeInterpolatedPositions(
|
||||||
positions.map((tr, i, { length }) => ({ ...tr, t: i / length }))
|
positions.map((tr, i, { length }) => ({ ...tr, t: i / length })),
|
||||||
).map(({ t, ...p }) => ({ t, style: transform(p) }));
|
).map(({ t, ...p }) => ({ t, style: transform(p) }));
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const createStack = (
|
|||||||
{ sizeDot }: Options,
|
{ sizeDot }: Options,
|
||||||
width: number,
|
width: number,
|
||||||
y: number,
|
y: number,
|
||||||
duration: number
|
duration: number,
|
||||||
) => {
|
) => {
|
||||||
const svgElements: string[] = [];
|
const svgElements: string[] = [];
|
||||||
const styles = [
|
const styles = [
|
||||||
@@ -51,7 +51,7 @@ export const createStack = (
|
|||||||
width: (ts.length * m + 0.6).toFixed(1),
|
width: (ts.length * m + 0.6).toFixed(1),
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
styles.push(
|
styles.push(
|
||||||
@@ -68,7 +68,7 @@ export const createStack = (
|
|||||||
].map(({ scale, t }) => ({
|
].map(({ scale, t }) => ({
|
||||||
t,
|
t,
|
||||||
style: `transform:scale(${scale.toFixed(3)},1)`,
|
style: `transform:scale(${scale.toFixed(3)},1)`,
|
||||||
}))
|
})),
|
||||||
),
|
),
|
||||||
|
|
||||||
`.u.${id} {
|
`.u.${id} {
|
||||||
@@ -76,7 +76,7 @@ export const createStack = (
|
|||||||
animation-name: ${animationName};
|
animation-name: ${animationName};
|
||||||
transform-origin: ${x}px 0
|
transform-origin: ${x}px 0
|
||||||
}
|
}
|
||||||
`
|
`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ it("should return next snake", () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
expect(snakeToCells(nextSnake(createSnakeFromCells(snk0), 1, 0))).toEqual(
|
expect(snakeToCells(nextSnake(createSnakeFromCells(snk0), 1, 0))).toEqual(
|
||||||
snk1
|
snk1,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const setColor = (
|
|||||||
grid: Grid,
|
grid: Grid,
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
color: Color | Empty
|
color: Color | Empty,
|
||||||
) => {
|
) => {
|
||||||
grid.data[getIndex(grid, x, y)] = color || 0;
|
grid.data[getIndex(grid, x, y)] = color || 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const randomlyFillGrid = (
|
|||||||
colors = [1, 2, 3] as Color[],
|
colors = [1, 2, 3] as Color[],
|
||||||
emptyP = 2,
|
emptyP = 2,
|
||||||
}: { colors?: Color[]; emptyP?: number } = {},
|
}: { colors?: Color[]; emptyP?: number } = {},
|
||||||
rand = defaultRand
|
rand = defaultRand,
|
||||||
) => {
|
) => {
|
||||||
for (let x = grid.width; x--; )
|
for (let x = grid.width; x--; )
|
||||||
for (let y = grid.height; y--; ) {
|
for (let y = grid.height; y--; ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user