I would try to make it more logical and easier to follow myself by looping through the surrounding squares and checking mine count, but after deciding what my loop boundaries should be, taking all edges into consideration. For example, something like so:
// count neighbouring mines
for (int x = 0; x < background.length; x++) {
for (int y = 0; y < background[0].length; y++) {
// if a MINE, we don't care about the count
if (background[x][y] != MINE) {
int nCount = 0;
// find the left side of the boundary box
int xMin = Math.max(x - 1, 0);
// find the right side of the boundary box
int xMax = Math.min(x + 1, background.length - 1);
// find the y min side of the boundary box
int yMin = Math.max(y - 1, 0);
// find the y max side of the boundary box
int yMax = Math.min(y + 1, background[0].length - 1);
// now loop using the boundaries calculated above
for (int x2 = xMin; x2 <= xMax; x2++) {
for (int y2 = yMin; y2 <= yMax; y2++) {
// check to make sure not the same squre
if (x2 != x || y2 != y) {
// if MINE, then increment nCount by 1
nCount += (background[x2][y2] == MINE ? 1 : 0);
}
}
}
background[x][y] = nCount;
}
}
}
As proof of concept, the following program uses the above code unaltered, and works:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MineSweeperFun {
public static void main(String[] args) {
MineSweeperModel model = new MineSweeperModel(36, 18, 60);
model.displayGrid();
}
}
public class MineSweeperModel {
private static final int MINE = -1;
private int[][] backgroundGrid;
private int rows;
private int cols;
private int mineCount;
public MineSweeperModel(int rows, int cols, int mineCount) {
this.rows = rows;
this.cols = cols;
this.mineCount = mineCount;
backgroundGrid = refreshGrid();
}
private int[][] refreshGrid() {
int[][] grid = new int[rows][cols];
insertRandomMines(grid);
calculateNeighborCount(grid);
return grid;
}
private void insertRandomMines(int[][] grid) {
List<Integer> intList = new ArrayList<>();
for (int i = 0; i < rows * cols; i++) {
intList.add(i);
}
Collections.shuffle(intList);
for (int i = 0; i < mineCount; i++) {
int value = intList.remove(0);
int row = value / cols;
int col = value % cols;
grid[row][col] = MINE;
}
}
public void displayGrid() {
for (int row = 0; row < backgroundGrid.length; row++) {
for (int col = 0; col < backgroundGrid[row].length; col++) {
int value = backgroundGrid[row][col];
String txt = ".";
if (value == MINE) {
txt = "*";
} else if (value > 0) {
txt = "" + value;
}
System.out.printf("%4s", txt);
}
System.out.println();
}
}
private void calculateNeighborCount(int[][] background) {
// count neighboring mines
for (int x = 0; x < background.length; x++) {
for (int y = 0; y < background[0].length; y++) {
// if a MINE, we don't care about the count
if (background[x][y] != MINE) {
int nCount = 0;
// find the left side of the boundary box
int xMin = Math.max(x - 1, 0);
// find the right side of the boundary box
int xMax = Math.min(x + 1, background.length - 1);
// find the y min side of the boundary box
int yMin = Math.max(y - 1, 0);
// find the y max side of the boundary box
int yMax = Math.min(y + 1, background[0].length - 1);
// now loop using the boundaries calculated above
for (int x2 = xMin; x2 <= xMax; x2++) {
for (int y2 = yMin; y2 <= yMax; y2++) {
// check to make sure not the same squre
if (x2 != x || y2 != y) {
// if MINE, then increment nCount by 1
nCount += (background[x2][y2] == MINE ? 1 : 0);
}
}
}
background[x][y] = nCount;
}
}
}
}
}
Example output:
1 1 1 1 1 . . . . . . 1 1 1 . . . .
* 1 2 * 2 . . . . . . 1 * 1 1 1 1 .
1 1 2 * 2 . . 1 1 1 . 1 1 1 1 * 1 .
. . 1 1 1 . . 1 * 1 . . . . 2 2 2 .
. . . 1 1 1 . 1 1 1 . 1 1 1 2 * 2 .
. 1 1 2 * 1 . . . . 1 2 * 2 3 * 3 1
. 1 * 3 2 1 . 1 1 1 1 * 2 2 * 3 * 1
. 1 2 * 1 . . 1 * 2 2 2 1 1 1 2 1 1
. . 1 1 1 . . 1 1 3 * 2 . . . 1 1 1
. . . . . . . . . 2 * 2 . . . 1 * 1
1 2 2 1 . . . . . 2 2 2 . 1 1 2 2 2
2 * * 2 1 . . . . 1 * 2 1 2 * 1 1 *
* 3 3 * 1 . . 1 1 2 1 2 * 2 2 2 2 1
1 1 1 1 1 . . 1 * 1 . 1 1 1 1 * 2 1
. . . 1 1 1 . 1 1 1 . . . . 1 1 2 *
. . . 1 * 1 . . . . . . . 1 1 1 1 1
. . . 1 1 1 . . 1 1 1 1 1 2 * 2 1 1
. . 1 1 1 . . . 1 * 1 1 * 3 2 3 * 1
. . 1 * 1 . . . 1 1 2 2 2 2 * 2 1 1
. . 1 1 1 1 1 1 . 1 2 * 1 1 1 1 . .
. . . . . 1 * 1 . 1 * 2 1 . . . . .
1 1 1 . . 1 1 1 . 1 2 2 1 . . . . .
1 * 1 . . . . . . . 1 * 1 . . . . .
1 1 1 . . . . 1 1 1 1 1 1 . . . . .
. . . . . . . 1 * 1 . . . . . . . .
. . . . . 1 1 2 1 1 . . . . . . . .
. . . . 1 2 * 1 . . . . . . . . . .
. . . . 1 * 2 1 . . . . . . . . . .
. 1 1 1 1 1 1 . . . . . . . . . . .
. 1 * 1 . . . . 1 1 1 1 1 2 1 1 . .
. 1 1 1 . . . . 1 * 1 1 * 2 * 1 . .
. . . 1 1 1 . . 1 2 2 2 1 2 1 1 . .
1 1 . 1 * 2 1 1 . 1 * 2 2 2 1 . . .
* 1 . 1 2 3 * 1 1 2 2 2 * * 2 1 1 .
1 1 . . 1 * 2 1 1 * 1 2 3 4 3 * 1 .
. . . . 1 1 1 . 1 1 1 1 * 2 * 2 1 .