-
Notifications
You must be signed in to change notification settings - Fork 0
/
Astar.ts
103 lines (82 loc) · 2.99 KB
/
Astar.ts
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
import { Point, tileType } from "./test.component";
export class AstarPathFinder {
private board!: tileType[][];
private snake!: Point[];
private openList!: Point[];
private closedList!: Point[];
private start!: Point;
private end!: Point;
constructor(board: tileType[][], snake: any[]) {
this.board = board;
this.snake = snake;
}
public update(board: tileType[][], snake: any[]) {
this.board = board;
this.snake = snake;
}
private isValidMove(toX: number, toY: number): boolean {
if(this.snake.some(segment => segment.x === toX && segment.y === toY)) return false;
const numRows = this.board.length;
const numCols = this.board[0].length;
if(toX < 0 || toX >= numRows) return false;
if(toY < 0 || toY >= numCols) return false;
return true;
}
private calculateHeuristic(point: { x: number, y: number }): number {
return Math.abs(point.x - this.end.x) + Math.abs(point.y - this.end.y);
}
private getNeighbors(point: Point) {
const {x, y} = point;
const neighbors: Point[] = [
{x: x - 1, y},
{x: x + 1, y},
{x, y: y - 1},
{x, y: y + 1},
]
return neighbors.filter(val => this.isValidMove(val.x, val.y));
}
private findPath(): Point[] {
this.openList.push(this.start);
while(this.openList.length > 0) {
this.openList.sort((a, b) => {
const costA = this.calculateHeuristic(a);
const costB = this.calculateHeuristic(b);
return costA - costB;
});
const current = this.openList.shift()!;
this.closedList.push(current);
if(current.x === this.end.x && current.y === this.end.y) {
return this.reconstructPath(current);
}
const neighbors = this.getNeighbors(current);
for(const neighbor of neighbors) {
if(!this.closedList.some(p => p.x === neighbor.x && p.y === neighbor.y)) {
if (!this.openList.some((point) => point.x === neighbor.x && point.y === neighbor.y)) {
neighbor.parent = current; // Set the current point as the parent of the neighbor
this.openList.push(neighbor);
}
}
}
}
console.log("No path :=");
return [];
}
private reconstructPath(endPoint: Point): Point[] {
const path: Point[] = [];
let current: Point | undefined = endPoint;
while (current) {
path.unshift(current);
current = current.parent;
}
return path;
}
public findBestPath(start: Point, end: Point): Point[] {
this.openList = [];
this.closedList = [];
this.start = start;
this.end = end;
this.start.parent = undefined;
const path = this.findPath();
return path;
}
}