JMineSweeper - rFronteddu/general_wiki GitHub Wiki

Minesweeper

Minesweeper is a classic puzzle game played on a 2D grid. Each cell can contain a mine or an empty space (which might have mines around it).

The goal is to reveal cells safely β€” if you click on a mine, you lose; if you click on an empty cell, the game reveals either:

  • a number (showing how many mines are adjacent to that cell), or
  • a blank area that recursively reveals more cells (if no mines are nearby).

Given a 2D board with:

  • 'M' = unrevealed mine square
  • 'E' = unrevealed empty square
  • 'B' = revealed blank (no adjacent mines)
  • '1'–'8' = number of adjacent mines

Implement char[][] updateBoard(char[][] board, int[] click)

When the user clicks a cell:

  • If it’s a mine, change to 'X'.
  • Else, reveal recursively:
    • If no adjacent mines, mark 'B' and reveal neighbors.
    • If adjacent mines, show the count.

The recursion (or BFS) stops when there are no more blank areas to reveal.

class Main {
    public static class Minesweeper {
        private static final int[][] DIRS = {
            {-1, -1}, {-1, 0}, {-1, 1},
            {0, -1},           {0, 1},
            {1, -1}, {1, 0},   {1, 1},
        };
        
        public char[][] updateBoard(char[][] board, int[] click) {
            int row = click[0]; int col = click[1];
            if(board[row][col] == 'M') {
                board[row][col] = 'X';
                return board;
            }
            dfs(board, row, col);
            return board;
        }
        
        private void dfs(char[][] board, int row, int col) {
            if(row < 0 || col < 0 || row >= board.length || col >= board[0].length || board[row][col] != 'E') return;
            int mines = countAdjMines(board, row, col);
            if(mines > 0) {
                board[row][col] = (char)('0' + mines);
                return;
            }
            
            board[row][col] = 'B'; // blank
            for(int[] d : DIRS) {
                dfs(board, row + d[0], col + d[1]);
            }
        }
        
        private int countAdjMines(char[][] board, int x, int y) {
            int count = 0;
            for(int[] d : DIRS) {
                int nx = x + d[0];
                int ny = y + d[1];
                if(nx >= 0 && ny >= 0 && nx < board.length && ny < board[0].length && board[nx][ny] == 'M') count++;
            }
            return count;
        }
    }

    public static void main(String[] args) {
        char[][] board = {
            {'E', 'E', 'E', 'E', 'E'},
            {'E', 'E', 'M', 'M', 'E'},
            {'E', 'E', 'E', 'E', 'E'},
            {'E', 'E', 'E', 'E', 'E'}
        };
        
        int[] click = {1, 1};
        
        Minesweeper ms = new Minesweeper();
        char[][] updated = ms.updateBoard(board, click);
        
        for (char[] row : updated) {
            System.out.println(java.util.Arrays.toString(row));
        }
    }
}

Random board generation

import java.util.*;

/**
* Generates a new Minesweeper board with randomly placed mines.
*
* <p>The board is initialized with all cells as unrevealed empty squares ('E'),
* and then {@code mineCount} mines ('M') are placed at random unique positions.
* The placement is uniform and does not guarantee a "safe first click" β€” that
* logic can be added separately if desired.</p>
*
* @param rows       the number of rows in the board
* @param cols       the number of columns in the board
* @param mineCount  the total number of mines to randomly place
* @return a 2D character array representing the initial game board,
*         where each cell is either 'E' (empty) or 'M' (mine)
* @throws IllegalArgumentException if {@code mineCount} exceeds the total number of cells
*/
static char[][] generateBoard(int rows, int cols, int mineCount) {
    char[][] board = new char[rows][cols];
    for (char[] row : board) Arrays.fill(row, 'E');

    Random rand = new Random();
    int placed = 0;
    while (placed < mineCount) {
        int r = rand.nextInt(rows);
        int c = rand.nextInt(cols);
        if (board[r][c] != 'M') {
            board[r][c] = 'M';
            placed++;
        }
    }
    return board;
}

Iterative (BFS) instead of recursive

Can you make it iterative (BFS) instead of recursive? BFS traversal, queue use How to avoid stack overflow on large boards? Iterative vs recursive depth How to mark visited cells efficiently? In-place marking or boolean visited[][] How would you generate a random Minesweeper board? Random placement, constraints How to unit test this logic? Edge case thinking How to add difficulty levels (e.g. mine density)? Parameterization and scalability

⚠️ **GitHub.com Fallback** ⚠️