-
Notifications
You must be signed in to change notification settings - Fork 0
/
knightsTravails.ts
107 lines (85 loc) · 2.83 KB
/
knightsTravails.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
103
104
105
106
107
// import graph class constructor
import { Graph } from "./utils/graphDataStructure";
// finds all immediate knight moves from a starting move
function allMoves(initial: number): number[] {
// extract the x and y coordinates from the two-digit number
const x: number = Math.floor(initial / 10);
const y: number = initial % 10;
const possibleMoves = [];
// define all possible knight move offsets
const moveOffsets = [
[-2, -1],
[-2, 1],
[-1, -2],
[-1, 2],
[1, -2],
[1, 2],
[2, -1],
[2, 1],
];
// check each possible move
for (const [dx, dy] of moveOffsets) {
const newX = x + dx;
const newY = y + dy;
// check if the new position is within the chessboard (0 to 7)
if (newX >= 0 && newX <= 7 && newY >= 0 && newY <= 7) {
// combine the x and y coordinates to form a two-digit number
const newPosition = newX * 10 + newY;
possibleMoves.push(newPosition);
}
}
return possibleMoves;
}
// builds a move as a node with neigbors
function moveToNode(initial: number): void {
// add initial move to node
path.addNode(initial);
// find all immediate moves from the initial move, and make those moves
// neigbors
allMoves(initial).forEach((final) => {
path.addNode(final);
path.addEdge(initial, final);
});
}
// utility function: transforms number to array and vice versa
function transformNumberOrArray(input: number[] | number): number | number[] {
if (typeof input === "number") {
const tens = Math.floor(input / 10);
const ones = input % 10;
return [tens, ones];
} else if (Array.isArray(input)) {
const tens = input[0];
const ones = input[1];
return tens * 10 + ones;
}
return input;
}
// takes initial & final position in array format, and prints shortest path between them
function knightMoves(initial: number[], final: number[]): void {
const initialNumber = transformNumberOrArray(initial) as number;
const finalNumber = transformNumberOrArray(final) as number;
const shortestPathArr = path.shortestPath(initialNumber, finalNumber);
console.log(
`You made it in ${shortestPathArr?.length} moves! Here's your path:`
);
shortestPathArr?.forEach((step) => {
const stepArray = transformNumberOrArray(step);
console.log(stepArray);
});
}
// usage
// choose starting position
const startPosition = 33;
// create path
const path = new Graph<number>();
// create starting node
path.addNode(startPosition);
// navigate the graph, creating each node along the way by calling moveToNode,
// effectively building the whole set of possible trajectories
path.breadthFirstTraversal(startPosition, moveToNode);
// print the graph
path.printGraph();
// find the shortest path
console.log(path.shortestPath(33, 43));
// find shortest path with knightMoves() function as requested in the TOP assignment
knightMoves([3, 3], [4, 3]);