class Grid { cols; rows; cells; nbMines; nbCells; constructor (cols, rows, nbMines) { this.cols = cols; this.rows = rows; this.nbCells = rows * cols; this.nbMines = nbMines; this.init(); } init () { var remainingMines = this.nbMines; var remainingCells = this.nbCells; this.cells = new Array(this.cols); for (var i = 0; i < this.cols; i++) { this.cells[i] = new Array(this.rows); for (var j = 0; j < this.rows; j++) { var setMine = Math.random() < (remainingMines / remainingCells); this.cells[i][j] = new Cell(i, j, setMine); if (setMine) {remainingMines--;} remainingCells--; } } } cellNeighbors(cell) { if (cell.neighbors != null) return cell.neighbors; var neighbors = []; var x = cell.x; var y = cell.y; if (x > 0 && y > 0) neighbors.push(this.cell(x-1, y-1)); if (x > 0) neighbors.push(this.cell(x-1, y )); if (x > 0 && y < this.rows-1) neighbors.push(this.cell(x-1, y+1)); if (y > 0) neighbors.push(this.cell(x , y-1)); if (y < this.rows-1) neighbors.push(this.cell(x , y+1)); if (x < this.cols-1 && y > 0) neighbors.push(this.cell(x+1, y-1)); if (x < this.cols-1) neighbors.push(this.cell(x+1, y )); if (x < this.cols-1 && y < this.rows-1) neighbors.push(this.cell(x+1, y+1)); cell.neighbors = neighbors; return neighbors; } computeCellWeight (cell) { if (cell.weight >= 0) return cell.weight; var weight = 0; var neighbors = this.cellNeighbors(cell); neighbors.forEach(neighbor => { if (neighbor.hasMine) weight ++; }) cell.weight = weight; return weight; } revealCell (cell) { if (cell.flagged || cell.revealed) return 0; if (cell.hasMine) return -1; var nbRevealed = 1 cell.weight = this.computeCellWeight(cell); cell.reveal(); if (cell.weight == 0) { var neighbors = this.cellNeighbors(cell); neighbors.forEach(neighbor => { nbRevealed += this.revealCell(neighbor); }); } return nbRevealed; } cell (x, y) { return this.cells[x][y]; } fullReveal () { for (var i = 0; i < this.cols; i++) { for (var j = 0; j < this.rows; j++) { var cell = this.cell(i, j); grid.computeCellWeight(cell); cell.flagged = false; cell.reveal(); } } } inbounds(x, y) { return x >= 0 && x < this.cols && y >= 0 && y < this.rows; } }