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];
}
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];
}
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]);
for (let r = 0; r < h; r++) {
for (let c = 0; c < w; c++) {
let cindex = getCellIndex(col + c, row + r);
covered.push(cindex);
}
}
}
}
for (let i = 0; i < cells.length; i++) {
let cell = randomly_filled_cells[i];
let [col, row] = getCellColumnRow(i);
if (cell === "w") {
ctx.fillStyle = "black";
ctx.fillRect(col * cstep, row * rstep, cstep, rstep);
}
}
for (let expand of expanded) {
let [col, row, w, h] = expand;
ctx.strokeRect(col * cstep, row * rstep, w * cstep, h * rstep);
}
}