draw = () => {
regen;
ctx.clearRect(0, 0, cwidth, cheight);
ctx.fillStyle = "white";
ctx.fillRect(0, 0, cwidth, cheight);
let columns = cwidth / cell_size;
let rows = cheight / cell_size;
let cstep = cell_size;
let rstep = cell_size;
function getCellIndex(column, row) {
return row * columns + column;
}
function getCellColumnRow(index) {
let column = index % columns;
let row = Math.floor(index / columns);
return [column, row];
}
function expandSquare(cells, covered, index) {
let start = index;
let [scol, srow] = getCellColumnRow(index);
let w = 1;
let h = 1;
function _expand() {
if (w === h) {
let to_expand = [];
let next_column = scol + w;
if (next_column === columns) return [w, h];
for (let i = 0; i < h; i++) {
let eindex = getCellIndex(next_column, srow + i);
let expand_candidate = cells[eindex];
let expand_check =
expand_candidate === null && !covered.includes(eindex);
if (!expand_check) return [w, h];
}
// all expand checks passed
w++;
return _expand();
} else {
let to_expand = [];
let next_row = srow + h;
if (next_row === rows) return [w - 1, h];
for (let i = 0; i < w; i++) {
let eindex = getCellIndex(scol + i, next_row);
let expand_candidate = cells[eindex];
to_expand.push(expand_candidate);
let expand_check =
expand_candidate === null && !covered.includes(eindex);
if (!expand_check) return [w - 1, h];
}
// all expand checks passed
h++;
return _expand();
}
}
return _expand();
}
let cells = [];
for (let r = 0; r < rows; r++) {
for (let c = 0; c < columns; c++) {
cells.push(null);
}
}
let randomly_filled_cells = cells.map(c =>
Math.random() > 0.9 ? "w" : null
);
let expanded = [];
let covered = [];
for (let i = 0; i < cells.length; i++) {
let cell = randomly_filled_cells[i];
if (cell === null && !covered.includes(i)) {
let [col, row] = getCellColumnRow(i);
let [w, h] = expandSquare(randomly_filled_cells, covered, i);
expanded.push([col, row, w, h]);
// add to covered;
for (let r = 0; r < h; r++) {
for (let c = 0; c < w; c++) {
let cindex = getCellIndex(col + c, row + r);
covered.push(cindex);
}
}
}
}
// add obstacles into expanded so we get every cell filled (order does not matter in this case)
// let filled_cells = randomly_filled_cells.filter(c => c === "w").map(c =>;
let filled_converted = [];
for (let i = 0; i < cells.length; i++) {
let cell = randomly_filled_cells[i];
if (cell === "w") {
let [c, r] = getCellColumnRow(i);
filled_converted.push([c, r, 1, 1]);
}
}
let combined = [...expanded, ...filled_converted];
ctx.fillStyle = "black";
for (let cell of combined) {
let [c, r, w, h] = cell;
ctx.beginPath();
ctx.arc(
c * cstep + (w * cstep) / 2,
r * rstep + (h * rstep) / 2,
(w * cstep) / 2- 2,
0,
2 * Math.PI,
false
);
ctx.fill();
}
}