Skip to content

Instantly share code, notes, and snippets.

@fuale
Created February 12, 2022 23:13
Show Gist options
  • Save fuale/d8ae966e468096954d9fa94162bb0269 to your computer and use it in GitHub Desktop.
Save fuale/d8ae966e468096954d9fa94162bb0269 to your computer and use it in GitHub Desktop.
slide puzzle
interface Position {
x: number;
y: number;
}
interface GridOptions {
elements: {
text: string;
}[];
}
const container = document.querySelector<HTMLDivElement>("#app");
const createGame = (container: HTMLElement, grid: GridOptions) => {
const size = (grid.elements.length + 1) / 4;
Object.assign(container.style, {
display: "grid",
justifyItems: "stretch",
alignItems: "stretch",
width: "70vw",
height: "70vw",
gridTemplateRows: `repeat(${size}, 1fr)`,
gridTemplateColumns: `repeat(${size}, 1fr)`
});
const initied = grid.elements.map((element, index) => {
const initPosition = { x: index % size, y: (index / size) | 0 };
const wrapper = document.createElement("div");
wrapper.textContent = element.text;
Object.assign(wrapper.style, {
fontWeight: "bold",
background: "teal",
display: "flex",
fontSize: "3em",
cursor: "default",
fontFamily: "monospace",
color: "white",
justifyContent: "center",
transition: "transform 177ms ease",
alignItems: "center"
});
return {
ord: index,
init: initPosition,
position: { ...initPosition },
wrapper
};
});
initied.forEach((element, index, elements) => {
element.wrapper.addEventListener("click", () => {
const { x, y } = element.position;
const clamp = (x: number) => Math.min(size - 1, Math.max(x, 0));
const up = { x, y: clamp(y - 1) };
const left = { x: clamp(x - 1), y };
const right = { x: clamp(x + 1), y };
const down = { x, y: clamp(y + 1) };
const use = { up: true, left: true, right: true, down: true };
for (const element of elements) {
if (element.position.x === up.x && element.position.y === up.y) {
use.up = false;
}
if (element.position.x === left.x && element.position.y === left.y) {
use.left = false;
}
if (element.position.x === right.x && element.position.y === right.y) {
use.right = false;
}
if (element.position.x === down.x && element.position.y === down.y) {
use.down = false;
}
}
console.log(
JSON.stringify([elements, use, [up, left, right, down]], null, 2)
);
const t = (p: Position) => `translate(
calc(${p.x - element.init.x} * 70vw / ${size}),
calc(${p.y - element.init.y} * 70vw / ${size})
)`;
if (use.up) {
element.wrapper.style.transform = t(up);
element.position = up;
}
if (use.left) {
element.wrapper.style.transform = t(left);
element.position = left;
}
if (use.right) {
element.wrapper.style.transform = t(right);
element.position = right;
}
if (use.down) {
element.wrapper.style.transform = t(down);
element.position = down;
}
if (
elements.filter(
(item, index) =>
item.position.x === item.init.x && item.position.y === item.init.y
).length === elements.length
) {
setTimeout(() => {
alert("done");
}, 180);
}
});
container.append(element.wrapper);
});
};
if (container) {
createGame(container, {
elements: [
{ text: "a" },
{ text: "b" },
{ text: "c" },
{ text: "d" },
{ text: "e" },
{ text: "f" },
{ text: "g" },
{ text: "h" },
{ text: "i" },
{ text: "j" },
{ text: "k" },
{ text: "l" },
{ text: "m" },
{ text: "n" },
{ text: "o" }
]
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment