class Maze {
constructor(nRows, nCols) {
this.nRows = nRows;
this.nCols = nCols || nRows;
this.nCells = this.nRows * this.nCols;
this.init();
}
init() {
this.grid = Array.from({ length: this.nRows }, (_, row) =>
Array.from({ length: this.nCols }, (_, col) => new Cell(row, col))
);
for (const c of this.eachCell()) {
c.adjacent.push(this.grid[c.row - 1]?.[c.col]);
c.adjacent.push(this.grid[c.row][c.col + 1]);
c.adjacent.push(this.grid[c.row + 1]?.[c.col]);
c.adjacent.push(this.grid[c.row][c.col - 1]);
}
}
*eachRow() {
for (const row of this.grid) {
yield row;
}
}
*eachCell() {
for (const row of this.eachRow()) {
for (const cell of row) {
yield cell;
}
}
}
randomCell(rGen) {
const row = randInt(this.nRows, rGen);
const col = randInt(this.grid[row].length, rGen);
return this.grid[row][col];
}
link([r1, c1], [r2, c2], bidi = true) {
this.grid[r1][c1].link(this.grid[r2][c2], bidi);
return this;
}
setStartAndEnd([r1, c1], [r2, c2]) {
this.start?.links[0].unlink(this.start);
this.end?.links[0].unlink(this.end);
if (r1 >= 0 || r1 < this.nRows || c1 >= 0 || c1 < this.nCols) {
this.srt = new Cell(r1, c1, "start");
this.srt.link(this.grid[this.clampR(r1)][this.clampC(c1)]);
}
if (r2 >= 0 || r2 < this.nRows || c2 >= 0 || c2 < this.nCols) {
this.end = new Cell(r2, c2, "end");
this.grid[this.clampR(r2)][this.clampC(c2)].link(this.end);
}
return this;
}
getStart(row, col) {
if (row != undefined && col != undefined) {
return this.grid[this.clampR(row)][this.clampC(col)];
}
return this.srt?.links[0] ? this.srt.links[0] : this.grid[0][0];
}
clampR(row) {
return Math.max(0, Math.min(row, this.nRows - 1));
}
clampC(col) {
return Math.max(0, Math.min(col, this.nCols - 1));
}
}