// TODO optimization: use '' for empty blocks, undefined as a sentinel export const create = (width, height) => Array(height).fill([]).map(() => Array(width).fill(undefined)) export const clone = grid => [...grid.map(row => [...row])] export const draw = (grid, x: number, y: number, block, rotation: number, color) => { // TODO doesn't need to be pure, clone in caller const bucket1 = clone(grid) block.coords[rotation].forEach(([xx, yy]) => bucket1[y + yy][x + xx] = color) return bucket1 } // check for free, return true if so export const check = (grid, x, y, block, rotation) => { const [width, height] = [grid[0].length, grid.length] const predicate = ([xx, yy]) => x + xx >= 0 && x + xx < width && y + yy >= 0 && y + yy < height && grid[y + yy][x + xx] === undefined return block.coords[rotation].every(predicate) } // clear full lines (non pure) export const sweep = grid => { let linesCleared = 0 const width = grid[0].length for (const [rowIndex, row] of grid.entries()) { const full = row.every(cell => cell !== undefined) if (full) { grid.splice(rowIndex, 1) grid.unshift(new Array(width).fill(undefined)) linesCleared++ } } return linesCleared }