I am fairly new to Java and I have been working on a Minesweeper game. I am trying to get the adjacent cells to be revealed recursively when an empty cell is clicked. I do this by calling showCell() shown below:
Cells array declaration and population:
private final Cell[][] cells;
public void newGame()
{
numMinesLeft = NUM_MINES;
numCellsLeft = NUM_ROWS * NUM_COLS;
hasHitMine = false;
Cell[] newCells = new Cell[NUM_ROWS * NUM_COLS];
int k = 0; // index in newCells
// create the cells with the mines
while (k < NUM_MINES && k < newCells.length)
{
newCells[k] = new Cell(MINE);
k++;
}
// create the cells without the mines
while (k < newCells.length)
{
newCells[k] = new Cell();
k++;
}
// uniformly mix newCells
for (k = newCells.length; k > 1;)
{
int r = generator.nextInt(k);
k--;
// interchange newCells[r] and newCells[k]
Cell temp = newCells[k];
newCells[k] = newCells[r];
newCells[r] = temp;
}
k = 0;
// place cells into the cells array
for (int i = 0; i < NUM_ROWS; ++i)
{
for (int j = 0; j < NUM_COLS; ++j)
{
cells[i][j] = newCells[k];
k++;
}
}
for(int i = 0; i<NUM_ROWS; i++)
{
for (int j = 0; j<NUM_COLS; j++)
{
int numOfBorderMines = 0;
if (cells[i][j].value != MINE)
{
if(isInTheGrid(i-1, j) == true)
{
if (cells[i-1][j].value == MINE )
{
numOfBorderMines++;
}
}
if(isInTheGrid(i+1, j) == true)
{
if (cells[i+1][j].value == MINE )
{
numOfBorderMines++;
}
}
if(isInTheGrid(i, j - 1) == true)
{
if (cells[i][j - 1].value == MINE )
{
numOfBorderMines++;
}
}
if(isInTheGrid(i, j + 1) == true)
{
if (cells[i][j + 1].value == MINE )
{
numOfBorderMines++;
}
}
if(isInTheGrid(i - 1, j + 1) == true)
{
if (cells[i - 1][j + 1].value == MINE )
{
numOfBorderMines++;
}
}
if(isInTheGrid(i + 1, j - 1) == true)
{
if (cells[i + 1][j - 1].value == MINE )
{
numOfBorderMines++;
}
}
if(isInTheGrid(i + 1, j + 1) == true)
{
if (cells[i + 1][j + 1].value == MINE )
{
numOfBorderMines++;
}
}
if(isInTheGrid(i - 1, j - 1) == true)
{
if (cells[i - 1][j - 1].value == MINE )
{
numOfBorderMines++;
}
}
cells[i][j].value = numOfBorderMines;
}
}
}
}
toggleFlag()
public void toggleFlag(int row, int col)
{
if (isCellShowing(row, col) || isOver()) return;
if (isCellFlagged(row, col))
{
// unflag cell
cells[row][col].hasFlag = false;
numMinesLeft++;
numCellsLeft++;
}
else if (numMinesLeft > 0)
{
// flag cell
cells[row][col].hasFlag = true;
numMinesLeft--;
numCellsLeft--;
}
ui.updateCell(row, col);
}
showCell()
public void showCell(int row, int col)
{
// checks is cell has been flagged or if the game is over, otherwise it reveals the cell
if(isCellFlagged(row, col) == true || isOver())
{
return;
}
else
{
cells[row][col].isShowing = true;
ui.updateCell(row, col);
}
// checks if cell has a mine and triggers hasHitMine otherwise subtracts 1 from class variable numCellsLeft
if (cells[row][col].value == MINE)
{
hasHitMine = true;
}
else
{
numCellsLeft--;
}
// if there are no mines adjacent, recursively reveal the adjacent cells
if(cells[row][col].value == 0)
{
showCell(row + 1, col);
showCell(row - 1, col);
showCell(row, col + 1);
showCell(row, col -1);
showCell(row + 1, col - 1);
showCell(row + 1, col + 1);
showCell(row - 1, col - 1);
showCell(row - 1, col + 1);
}
}
The problem I am having is when I hit this portion of the code and click an empty cell, it reveals all cells adjacent continuously down a column or a row in one direction. I can't get my implementation of recursion right, perhaps I am approaching it wrong. My idea was to reveal each adjacent cell according to the grid position.
I solved my problem by implementing Tail Recursion. Here is my updated showCell() method and tail recursion method:
public void showCell(int row, int col)
{
// checks is cell has been flagged or if the game is over, otherwise it reveals the cell
if(isCellFlagged(row, col) == true || isOver())
{
return;
}
else
{
cells[row][col].isShowing = true;
ui.updateCell(row, col);
}
// checks if cell has a mine and triggers hasHitMine otherwise subtracts 1 from class variable numCellsLeft
if (cells[row][col].value == MINE)
{
hasHitMine = true;
}
else
{
numCellsLeft--;
}
// if there are no mines adjacent, recursively reveal the adjacent cells
if(cells[row][col].value == 0)
{
if(isInTheGrid(row - 1, col) == true)
{
showCell(row - 1, col, cells[row - 1][col].isShowing);
}
if(isInTheGrid(row + 1, col) == true)
{
showCell(row + 1, col, cells[row + 1][col].isShowing);
}
if(isInTheGrid(row, col - 1) == true)
{
showCell(row, col - 1, cells[row][col - 1].isShowing);
}
if(isInTheGrid(row, col + 1) == true)
{
showCell(row, col + 1, cells[row][col + 1].isShowing);
}
if(isInTheGrid(row + 1, col - 1) == true)
{
showCell(row + 1, col - 1, cells[row + 1][col - 1].isShowing);
}
if(isInTheGrid(row - 1, col + 1) == true)
{
showCell(row - 1, col + 1, cells[row - 1][col + 1].isShowing);
}
if(isInTheGrid(row + 1, col + 1) == true)
{
showCell(row + 1, col + 1, cells[row + 1][col + 1].isShowing);
}
if(isInTheGrid(row - 1, col - 1) == true)
{
showCell(row - 1, col - 1, cells[row - 1][col - 1].isShowing);
}
}
else
{
return;
}
}
public boolean isInTheGrid(int x, int y)
{
if (x < 0 || y < 0) return false;
if(x >= NUM_ROWS || y >= NUM_COLS) return false;
return true;
}
public void showCell(int row, int col, boolean isShown)
{
if (isShown != true)
{
cells[row][col].isShowing = true;
ui.updateCell(row, col);
}
else
{
return;
}
}