Skip to content

Instantly share code, notes, and snippets.

@hyalen
Created February 7, 2023 19:03
Show Gist options
  • Save hyalen/49b489bed5f6aeccebe1d7960da4b972 to your computer and use it in GitHub Desktop.
Save hyalen/49b489bed5f6aeccebe1d7960da4b972 to your computer and use it in GitHub Desktop.
// Constants to define the size of the game board
const ROWS = 8;
const COLS = 8;
const MINES = 10;
// A 2D array to represent the game board
const board = [];
// An array to keep track of the positions of mines on the board
const mines = [];
const visited = [];
// Number of cells left in the board. On every cell discovered, it decreases by 1.
// If it reaches 0 without finding any mines, it means that the user won the game
let cellsLeft = ROWS * COLS - MINES;
// Initialize the board, state, and place mines randomly
for (let row = 0; row < ROWS; row++) {
board[row] = [];
visited[row] = [];
for (let col = 0; col < COLS; col++) {
board[row][col] = 0;
visited[row][col] = { value: "#", visited: false };
}
}
for (let i = 0; i < MINES; i++) {
const row = Math.floor(Math.random() * ROWS);
const col = Math.floor(Math.random() * COLS);
if (board[row][col] !== "*") {
board[row][col] = "*";
mines.push([row, col]);
} else {
i--;
}
}
// Function to count the number of mines around a cell
function countMines(row, col) {
var count = 0;
for (var r = Math.max(0, row - 1); r <= Math.min(row + 1, ROWS - 1); r++) {
for (var c = Math.max(0, col - 1); c <= Math.min(col + 1, COLS - 1); c++) {
if (board[r][c] === "*") {
count++;
}
}
}
return count;
}
// Populate the board with the number of mines around each cell
for (let i = 0; i < mines.length; i++) {
const row = mines[i][0];
const col = mines[i][1];
for (let r = Math.max(0, row - 1); r <= Math.min(row + 1, ROWS - 1); r++) {
for (let c = Math.max(0, col - 1); c <= Math.min(col + 1, COLS - 1); c++) {
if (board[r][c] !== "*") {
board[r][c]++;
}
}
}
}
// Function to display the game board in the console
function displayInitialBoard() {
console.log(" " + [...Array(COLS).keys()].join(" "));
for (let row = 0; row < ROWS; row++) {
console.log(row + " " + board[row].join(" "));
}
}
function displayVisitedBoard() {
console.log(" " + [...Array(COLS).keys()].join(" "));
for (let row = 0; row < ROWS; row++) {
console.log(row + " " + visited[row].map((v) => v.value).join(" "));
}
console.log("---------------------------\n");
}
function revealCell(row, col) {
const rowsLength = board.length;
const columnsLength = board[0].length;
const queue = [[row, col]];
if (row < 0 || row > rowsLength || col < 0 || col > columnsLength) {
throw Error("Grid values not supported.");
}
if (board[row][col] === "*") {
console.log("You lost.");
visited[row][col] = "*";
} else {
while (queue.length > 0) {
const [queueRow, queueCol] = queue.shift();
// if the cell clicked is a number greater than 0, it means that we have a mine adjacent to that cell
// so we need to stop the execution and just updated the visited array with the current board value
if (board[queueRow][queueCol] > 0) {
visited[queueRow][queueCol] = {
value: board[queueRow][queueCol],
visited: true,
};
cellsLeft--;
} else {
visited[queueRow][queueCol] = { value: 0, visited: true };
cellsLeft--;
// looping through all 8 adjacent directions
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
// i and j equals 0 are the user's click coordinates, so we'll skip that
if (i === 0 && j === 0) {
continue;
}
const r = queueRow + i;
const c = queueCol + j;
// if the cell is at the edges, skip the adjacent cells that are out of bounds
if (r < 0 || r >= rowsLength || c < 0 || c >= columnsLength) {
continue;
}
if (!visited[r][c].visited) {
queue.push([r, c]);
visited[r][c] = {
value: 0,
visited: true,
};
}
}
}
}
}
}
if (cellsLeft === 0) {
console.log("You win.");
}
displayVisitedBoard();
}
// initial state of the board (for testing purposes)
displayInitialBoard();
console.log("---------------------------\n");
// some tests here
revealCell(2, 3);
revealCell(4, 4);
revealCell(5, 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment