This commit is contained in:
2024-12-19 00:06:50 +00:00
parent f4e5be11bf
commit 64d12de0f4
2 changed files with 212 additions and 117 deletions

View File

@@ -14,9 +14,7 @@ enum Dir {
Left,
};
const map: Array<Array<string>> = [];
const path: Array<Coord> = [];
const map: Array<Array<string|number>> = [];
const width = 71;
const height = 71;
@@ -35,14 +33,14 @@ for (let i = 0; i < 1024; i++) {
map[y][x] = '#'
}
function get(pos: Coord): string {
function get(pos: Coord): string|number {
if (map[pos.y] && map[pos.y][pos.x]) {
return map[pos.y][pos.x];
}
return '#';
}
function set(pos: Coord, val: string): void {
function set(pos: Coord, val: string|number): void {
map[pos.y][pos.x] = val;
}
@@ -60,26 +58,12 @@ function prevDir(dir: Dir): Dir {
return directions[i];
}
function isBranch(pos: Coord, dir: Dir): boolean {
const leftDir = prevDir(dir);
const rightDir = nextDir(dir);
const next = nextCoord(pos, dir);
const left = nextCoord(pos, leftDir);
const right = nextCoord(pos, rightDir);
const nextChar = get(next);
const leftChar = get(left);
const rightChar = get(right);
return nextChar === '.' && leftChar === '.'
|| nextChar === '.' && rightChar === '.'
|| leftChar === '.' && rightChar === '.';
}
function printMap(path: Array<Coord> = []) {
const mapClone = map.slice().map((row: Array<string>) => row.slice());
const mapClone = map.slice().map((row: Array<string|number>) => row.slice());
path.forEach(({ x, y }) => {
mapClone[y][x] = 'O';
});
console.log(mapClone.map((row: Array<string>) => row.join('')).join("\n"));
console.log(mapClone.map((row: Array<string|number>) => row.map((c) => typeof c === 'number' ? '.' : c).join('')).join("\n"));
console.log("\n");
}
@@ -114,105 +98,53 @@ function fillDeadEnd(pos: Coord): void {
}
printMap();
// for (let y = 0; y < height; y++) {
// for (let x = 0; x < width; x++) {
// const pos = { x, y };
// const char = get(pos);
// if (char !== '.') {
// continue;
// }
// if (isDeadEnd(pos)) {
// fillDeadEnd(pos);
// }
// }
// }
// printMap();
interface Nd {
parent: Nd|null,
pos: Coord,
g: number,
h: number,
f: number,
};
const openList: Array<Nd> = [];
const closedList: Array<Nd> = [];
const startNode: Nd = {
parent: null,
pos: { x: 0, y: 0 },
g: 0,
h: 0,
f: 0,
};
const endNode = {
parent: null,
pos: { x: width - 1, y: height - 1 },
g: 0,
h: 0,
f: 0,
};
openList.push(startNode);
while (openList.length > 0) {
let currentNode = openList[0];
let currentIndex = 0;
openList.forEach((item, index) => {
if (item.f < currentNode.f) {
currentNode = item;
currentIndex = index;
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const pos = { x, y };
const char = get(pos);
if (char !== '.') {
continue;
}
});
openList.splice(currentIndex, 1);
closedList.push(currentNode);
if (currentNode.pos.x === endNode.pos.x && currentNode.pos.y === endNode.pos.y) {
let current: Nd|null = currentNode;
while (current) {
path.push(current.pos);
current = current.parent;
if (isDeadEnd(pos)) {
fillDeadEnd(pos);
}
break;
}
const children: Array<Nd> = [];
[Dir.Up, Dir.Right, Dir.Down, Dir.Left].forEach((dir) => {
const nodePos = nextCoord(currentNode.pos, dir);
if (get(nodePos) === '#') {
return;
}
const newNode: Nd = {
parent: currentNode,
pos: nodePos,
g: 0,
h: 0,
f: 0,
};
if (closedList.find((closedChild) => closedChild.pos.x === newNode.pos.x && closedChild.pos.y === newNode.pos.y)) {
return;
}
newNode.g = currentNode.g + 1;
newNode.h = ((newNode.pos.x - endNode.pos.x) ** 2) + ((newNode.pos.y - endNode.pos.y) ** 2);
newNode.f = newNode.g + newNode.h;
if (openList.find((openNode) => newNode.pos.x === openNode.pos.x && newNode.pos.y === openNode.pos.y && newNode.g > openNode.g)) {
return;
}
openList.push(newNode);
});
}
printMap();
console.log(path, path.length)
let fastest: number|null = null;
const scores: Array<Array<Coord>> = [];
function getScoresAfterPosition(pos: Coord, dir: Dir, path: Array<Coord> = [], lastBranch: [number, Coord]|null = null): void {
if (fastest !== null && path.length >= fastest) {
return;
}
[dir, nextDir(dir), prevDir(dir)].forEach((newDir, i) => {
const next = nextCoord(pos, newDir);
const nextCell = get(next);
if (nextCell !== '#' && (typeof nextCell !== 'number' || nextCell > path.length) && !path.find(({ x, y }) => next.x === x && next.y === y)) {
if (next.x === width - 1 && next.y === height - 1) {
if (fastest === null || path.length < fastest) {
fastest = path.length;
}
scores.push(path);
return;
} else if (next.x >= 0 && next.x < width && next.y >= 0 && next.y < height) {
set(next, path.length);
getScoresAfterPosition(next, newDir, [...path, next], lastBranch);
}
}
});
return;
}
getScoresAfterPosition({ x: 0, y: 0 }, Dir.Up, [{ x: 0, y: 0 }]);
console.log(scores);
const fastestScore = Math.min(...scores.map((p) => p.length));
const fastestPath = scores.find((p) => p.length === fastestScore);
printMap(fastestPath);
console.log(fastestScore);