问题
I am creating a simple mine-sweeper board with 2D array. I wants to populate the squares surrounding the "Bomb(s)" with respective numbers. I don't need to care whether the board I created can be solved. (Not important here)
My question is: How can we populate the numbers elegantly without listing out all the possibilities as if we were hard-coding?
What I came out with for now is a massive nested if-statements to check whether the neighbour is
-Inside bounds of array
-Is it a bomb
-Is it empty
-Is it already a number
It looks awfully long and hard-coded.
Is there a simple and elegant way to check the values of the neighbours in a 2D Matrix?
I realize there is similar question in SO asking in Python language, the solutions there were very "pythonic". I am looking for a simple approach by just using simple structure like (loops, if-statement, etc.) on a simple 2D array.
Just imagine this task is given to a new student in programming who only knows the fundamentals like if-statements and loops. So suggested solutions with lambda, recursive, iterators, etc. should be avoided.
回答1:
A main cause of complexity when checking neighbors is the boundaries. If you're in a cell in the first row, for example, you don't want to check the three neighbors above because they would be outside the array.
There are several common ways of eliminating the boundary checking. Let's assume you have a class with an interface like this:
class Board {
public:
bool IsBomb(int row, int col) const;
int GetCount(int row, int col) const;
...
};
You can hide the boundary checking in the implementation of the IsBomb
method. For example, if you call IsBomb
with coordinates that are outside the playfield, it should return false
rather than actually looking in the array (or whatever your storage mechanism is). Now GetCount
can simply call IsBomb for all eight neighbors without worrying about whether any of those neighbors is off the edge of the playfield. This is the data abstraction approach.
Another approach is to make the board bigger on all sides, but only loop through the inner squares. Then you don't need to check if the neighboring squares are in bounds or not. This would be an implementation detail that you hide in the methods of Board. It's completely compatible with first approach.
There are other hacks for avoiding boundary checks in loops, like dividing the board into nine special cases (corners, edges, and middle), but that would be overkill for a minesweeper like game. And it doesn't reduce complexity; that would mostly be for performance in some extreme case.
回答2:
for(int x =0; x<numRows; x++){
for(int y = 0; y<numCols; y++){
if(array[x][y] != "bomb"){
array[x][y] = number
}
}
}
Best way to do this is just by cycling through each index and checking if theres a bomb. If there isn't you add a number. The first for loop goes through each row, then the next for loop goes through each column. So you would check row 1 versus column 1, column2, column3, etc. Then once row 1 is completed move onto row 2 and check versus column1, column2, etc. until every position has been searched.
来源:https://stackoverflow.com/questions/22845852/check-value-of-neighbouring-squares-in-2d-array