1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
import Ball from "./Ball";
import { MAP_WIDTH, MAP_HEIGHT, TD_SIZE } from "./consts";
import { genGraph, genMap } from "./map";
import findPath, { Path } from "./pathfinder";
let selectedBall: Ball | null = null;
let currentPath: Path = [];
let turnIsChanging = false;
const setCurrentPath = (p: any) => {
for (const v of currentPath) {
getTd(v.x!, v.y!).style.backgroundColor = "";
}
currentPath = p;
}
export async function nextTurn() {
turnIsChanging = true;
for (const v of currentPath) {
getTd(v.x!, v.y!).style.backgroundColor = "rgba(50, 50, 50, 0.8)";
}
await sleep(2000);
setCurrentPath([]);
window.balls.push(...Ball.generateNewBalls());
render();
turnIsChanging = false;
}
async function sleep(time: number) {
return new Promise(resolve => setTimeout(resolve, time));
}
export function tdOnClick(_e: PointerEvent) {
if (!currentPath.length || turnIsChanging) return;
const std = getTd(currentPath[0].x!, currentPath[0].y!);
(std.firstChild as HTMLDivElement).style.width = "";
(std.firstChild as HTMLDivElement).style.height = "";
const ib = window.balls.findIndex(b => b.x === currentPath[0].x && b.y === currentPath[0].y)!
window.balls[ib].x = currentPath[currentPath.length - 1].x!
window.balls[ib].y = currentPath[currentPath.length - 1].y!
std.innerHTML = "";
selectedBall = null;
render(window.balls);
nextTurn();
}
export function tdOnMouseEnter(_e: PointerEvent, x: number, y: number) {
if (!selectedBall || turnIsChanging) return;
const graph = genGraph(genMap(window.balls), { x: selectedBall.x, y: selectedBall.y }, { x, y });
const path = findPath(graph) ?? [];
setCurrentPath(path);
if (!path.length) return;
for (const v of path) {
getTd(v.x!, v.y!).style.backgroundColor = "rgba(45, 123, 78, 0.6)";
}
}
export function render(balls?: Ball[]) {
balls = balls ? balls : window.balls;
for (const ball of balls) {
const { x, y, color } = ball;
const td = getTd(x, y);
(td.firstChild as HTMLDivElement).style.backgroundColor = color;
td.onclick = () => {
if (turnIsChanging) return;
const circle = td.firstChild as HTMLDivElement;
setCurrentPath([]);
const smallerCircle = () => {
circle.style.width = "";
circle.style.height = "";
}
if (circle.style.width === TD_SIZE) {
smallerCircle();
selectedBall = null;
return;
}
smallerCircle();
circle.style.width = TD_SIZE;
circle.style.height = TD_SIZE;
selectedBall = ball;
};
}
}
export function genGameTable() {
const table = getGameMapEl();
for (let i = 0; i < MAP_HEIGHT; i++) {
const tr = document.createElement("tr")
for (let j = 0; j < MAP_WIDTH; j++) {
const td = document.createElement("td")
// @ts-expect-error
td.onmouseenter = e => tdOnMouseEnter(e, i, j);
// @ts-expect-error
td.onclick = e => tdOnClick(e);
td.appendChild(document.createElement("div"));
tr.appendChild(td)
}
table.appendChild(tr)
}
}
export function getGameMapEl(): HTMLTableElement {
return document.querySelector('table')!
}
export function getTd(x: number, y: number): HTMLTableDataCellElement {
return getGameMapEl().children[x].children[y] as HTMLTableDataCellElement;
}
|