aboutsummaryrefslogtreecommitdiffstats
path: root/src/map.ts
blob: 44a970c5c9223d0c474859c97c6821cd6cd2e0bd (plain) (blame)
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
import Ball from "./Ball";
import { MAP_HEIGHT, MAP_WIDTH } from "./consts";
import { Graph } from "./pathfinder/Graph";

export type Map = (Ball | null)[][];
export function genMap(balls: Array<Ball>): Map {
  const map = <Map>[];
  for (let i = 0; i < MAP_HEIGHT; i++) {
    map.push([]);
    for (let j = 0; j < MAP_WIDTH; j++) {
      map[i].push(null);
    }
  }
  for (const b of balls) {
    map[b.x][b.y] = b
  }
  return map;
}

type Coord = { x: number; y: number };
export function genGraph(map: Map, start: Coord, goal: Coord): Graph {
  const graph: Graph = [];
  map.forEach((row, i) => {
    row.forEach((b, j) => {
      graph.push({
        start: i === start.x && j === start.y,
        goal: i === goal.x && j === goal.y,
        walkable: b === null,
        uuid: uuidv4(),
        graph,
        x: i,
        y: j,
        edges: [],
      });
    });
  });
  map.forEach((row, i) => {
    row.forEach((_, j) => {
      const vertex = graph.find(v => v.x === i && v.y === j);
      if (!vertex) return;
      const n1 = graph.find(v => v.x === i - 1 && v.y === j);
      const n2 = graph.find(v => v.x === i + 1 && v.y === j);
      const n3 = graph.find(v => v.x === i && v.y === j - 1);
      const n4 = graph.find(v => v.x === i && v.y === j + 1);
      for (const n of [n1, n2, n3, n4]) {
        if (n) {
          vertex.edges.push({
            from: vertex,
            to: n,
            weight: 1,
          });
        }
      }
    });
  });
  return graph;
}

function uuidv4() {
  // @ts-ignore
  return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
    (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
  );
}