Leo
Leo

Reputation: 133

Creation 2D array for Mine game


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

Answers (2)

Anurag
Anurag

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:

  1. look at each mine
  2. increment all it's non-mine neighbors

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 :)

  1. look at each non-mine cell
  2. change its value to the number of neighboring mines

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

Ahmed Kotb
Ahmed Kotb

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

  1. we will start with empty grid (full of zeros)
  2. insert each bomb randomly in empty place (doesn't already have a bomb)
  3. increment all the non-bombs neighbors

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

Related Questions