Reputation: 133
Hello
I am trying to create emulation of "Mine game"
suppose we have matrix
0 0 0 0
0 0 -1 0
0 0 0 -1
0 -1 0 -1
now each cell that not equal -1 should be represent numbers of mines
here code
for(int i=0;i
for(int j=0;j<N;j++)
if(box[i][j]!=-1)
{
switch (i)
{
case 0:
iLEFT=0;
iRIGHT=1;break;
case 3:
iRIGHT=0;
iLEFT=1;
break;
case 1:
iLEFT=1;
iRIGHT=1;
break;
case 2:
iLEFT=1;
iRIGHT=1;
break;
default:
iLEFT=1;
iRIGHT=1;
break;
}
switch (j)
{
case 0:
jLEFT=0;`
jRIGHT=1;
break;
case 3:
jRIGHT=0;
jLEFT=1;
break;
case 1:
jLEFT=1;
jRIGHT=1;
break;
case 2:
jLEFT=1;
jRIGHT=1;
break;
default:
jLEFT=1;
jRIGHT=1;
break;
}
// checking neighbor
if(box[i][j+jRIGHT]==-1)
count+=1;
if(box[i][j-jLEFT]==-1)
count+=1;
if(box[i+iRIGHT][j]==-1)
count+=1;
if (box[i-iLEFT][j]==-1)
count+=1;
if(box[i-iLEFT][j-jLEFT]==-1)
{
if(i-iLEFT!=i) // trying to avoid double checking
count+=1;
}
if(box[i+iRIGHT][j-jLEFT]==-1)
{
if(i+iRIGHT!=i) //trying to avoid double checking
count+=1;
}
if (box[i-iLEFT][j+jRIGHT]==-1)
{
if(i!=iLEFT) //trying to avoid double checking
count+=1;
}
if (box[i+iRIGHT][j+jRIGHT]==-1)
{
if(i!=iRIGHT) //trying to avoid double checking
count+=1;
}
box[i][j]=count;
count=0;
}
My algorithm
iLEFT present row step left.
iRIGHT present row step right.
jLEFT and JRIGHT same for column
Suppose i=0 so we can step only one step right(down)
if i=1 we can step up and done ..same for j
"Case statement " update iLEFT/iRIGTH and jLEFT/jRIGHT for for enable side steps
now "if" statement checking left/right up/done 2 diagonals for box[i][j](only one step always)
count counting performance of -1 values neighbor for box[i][j]
you can see I still have double checking for same cells
0 1 1 1
0 1 -1 2
1 2 4 -1
2 -1 4 -1
Upvotes: 1
Views: 1846
Reputation: 141879
You should also outline your algorithm along with the code to give out a better idea of how you are approaching the problem. It's really difficult to understand this code without an accompanying algorithm.
You could outline your algorithm in plain english, doesn't have to be pseudocode. It will help you understand the problem and solution better. For instance, something like this:
I think you are over-complicating the way you check for boundary conditions. Let's assume if the minefield was infinitely large in each direction. If we then picked any random cell(i,j)
, it's 8 neighbours would be at:
cell(i-1, j-1) // top-left
cell(i-1, j) // top
cell(i-1, j+1) // top-right
cell(i, j-1) // left
cell(i, j+1) // right
cell(i+1, j-1) // bottom-left
cell(i+1, j) // bottom
cell(i+1, j+1) // bottom-right
Back to the actual finite-length case now. I'd suggest that instead of pre-calculating whether a cell is within bounds, you should always check all 8 neighbors, and discard the invalid ones.
A function that checks if a cell is valid is easy to write:
bool is_cell_valid(int x, int y, int rows, int cols) {
if(x < 0 || x >= cols) {
return false;
}
if(y < 0 || y >= rows) {
return false;
}
return true;
}
I understand you algorithm now finally :)
The double checking is happening because you are not checking for all variables that are changing. For example, in this condition you are using iLEFT and jLEFT to go to the top-left cell. Since both variables are being used, you have to make sure that both of them are non-zero.
if(box[i-iLEFT][j-jLEFT]==-1)
{
if(i-iLEFT!=i) // trying to avoid double checking
count+=1;
}
The above should instead be
if(iLEFT != 0 && jLEFT != 0)
{
if(box[i-iLEFT][j-jLEFT]==-1)
count+=1;
}
And this check should be applied on each of the 8 cells, not just the diagonal cells.
Here's a tiny alternative to go through all 8 cells that are adjacent to some cell at (x, y) without using an if for each neighbor.
for(int i = -1; i < = 1; i++) {
for(int j = -1; j <= 1; j++) {
if(i == 0 && j == 0) {
continue;
}
if(is_cell_valid(x + i, y + j, N, N);
// cell is adjacent and within boundaries
// do whatever calculations are needed
}
}
}
Upvotes: 2
Reputation: 6307
i second on including the illustration of your algorithm which will be alot easier to read any way i have made a minesweeper game before and this could be the outline of the generate function
additional feature delay the generation of the bombs after the first click so you can make sure not to place a bomb on the first cell the user clicks
and here is a code snippet
var i = 0
while (i < bombsNum){
//generate a random location for the bomb
var col=Math.floor(Math.random()*cols);
var row=Math.floor(Math.random()*rows);
//if new location is already a bomb
if (cellsData[row][col] == -1) continue;
//if new location is near the start region
if (col == startCol-1 || col == startCol || col == startCol +1){
if (row == startRow -1 || row == startRow || row == startRow+1)
continue;
}
i++;
cellsData[row][col] = -1;
//increment all the neighbors cells and make sure to handle the special cases cells (cells at the corner)
}
Upvotes: 0