Marina Belli
Marina Belli

Reputation: 13

"Minesweeper" in C, trouble on counting surrounding mines are near a certain spot in the board

I have to recreate a simple version of the game "Minefield" in C, but I'm having trouble on counting how many mines are near a certain spot in the board. My piece of code runs throughout the array (board) searching for mines. When it finds a mine, it should add up +1 in all the surrounding spots of the mine. My code only works to the surrounding spots of T[0][0]. m and n stand for the number of lines and columns on the board. Please, help!!

void mine_counting (int T[MMAX][NMAX], int m, int n)
{
int cont, i, j;

for (i = 0 ; i < m ; i++)
{
    printf("\ni = %d", i);
    for (j = 0 ; j < n ; j++)
        printf("\nj = %d", j);
        {
        if (T[i][j] == -3)
            {
            if (i == 0)
                {
                printf("i=0");
                if (j == 0)
                    {
                    if (T[i][j+1] != -3)
                        T[i][j+1] = T[i][j+1] + 1;
                    if (T[i+1][j] != -3)
                        T[i+1][j] = T[i+1][j] + 1;
                    if (T[i+1][j+1] != -3)
                        T[i+1][j+1] = T[i+1][j+1] + 1;
                    }
                if (j == (n-1))
                    {
                    printf("j = n-1");
                    if (T[i][j-1] != -3)
                        T[i][j-1] = T[i][j-1] + 1;
                    if (T[i+1][j] != -3)
                        T[i+1][j] = T[i+1][j] + 1;
                    if (T[i+1][j-1] != -3)
                        T[i+1][j-1] = T[i+1][j-1] + 1;
                    }
                if (j != 0 && j!= (n-1))
                    {
                    if (T[i+1][j] != -3)
                        T[i+1][j] = T[i+1][j] + 1;
                    if (T[i+1][j+1] != -3)
                        T[i+1][j+1] = T[i+1][j+1] + 1;
                    if (T[i+1][j-1] != -3)
                        T[i+1][j-1] = T[i+1][j-1] + 1;
                    if (T[i][j+1] != -3)
                        T[i][j+1] = T[i][j+1] + 1;
                    if (T[i][j-1] != -3)
                        T[i][j-1] = T[i][j-1] + 1;
                    }
                }
            if (i == (m-1))
                {
                if (j == 0)
                    {
                    if (T[i][j+1] != -3)
                        T[i][j+1] = T[i][j+1] + 1;
                    if (T[i-1][j] != -3)
                        T[i-1][j] = T[i-1][j] + 1;
                    if (T[i-1][j+1] != -3)
                        T[i-1][j+1] = T[i-1][j+1] + 1;
                    }
                if (j == (n-1))
                    {
                    if (T[i-1][j] != -3)
                        T[i-1][j] = T[i-1][j] + 1;
                    if (T[i-1][j-1] != -3)
                        T[i-1][j-1] = T[i-1][j-1] + 1;
                    if (T[i][j-1] != -3)
                        T[i][j-1] = T[i][j-1] + 1;
                    }

                if (j != 0 && j!= (n-1))
                    {
                    if (T[i-1][j] != -3)
                        T[i-1][j] = T[i-1][j] + 1;
                    if (T[i-1][j+1] != -3)
                        T[i-1][j+1] = T[i-1][j+1] + 1;
                    if (T[i-1][j-1] != -3)
                        T[i-1][j-1] = T[i-1][j-1] + 1;
                    if (T[i][j+1] != -3)
                        T[i][j+1] = T[i][j+1] + 1;
                    if (T[i][j-1] != -3)
                        T[i][j-1] = T[i][j-1] + 1;
                    }
                }
            if (j == 0 && i != 0 && i!= (m-1))
                {
                if (T[i-1][j] != -3)
                    T[i-1][j] = T[i-1][j] + 1;
                if (T[i-1][j+1] != -3)
                    T[i-1][j+1] = T[i-1][j+1] + 1;
                if (T[i][j+1] != -3)
                    T[i][j+1] = T[i][j+1] + 1;
                if (T[i+1][j+1] != -3)
                    T[i+1][j+1] = T[i+1][j+1] + 1;
                if (T[i+1][j] != -3)
                    T[i+1][j] = T[i+1][j] + 1;
                }
            if (j == (n-1) && i != 0 && i!= (m-1))
                {
                if (T[i-1][j] != -3)
                    T[i-1][j] = T[i-1][j] + 1;
                if (T[i-1][j-1] != -3)
                    T[i-1][j-1] = T[i-1][j-1] + 1;
                if (T[i][j-1] != -3)
                    T[i][j-1] = T[i][j-1] + 1;
                if (T[i+1][j-1] != -3)
                    T[i+1][j-1] = T[i+1][j-1] + 1;
                if (T[i+1][j] != -3)
                    T[i+1][j] = T[i+1][j] + 1;
                }
            if ((i != 0) && (i != (m-1)) && (j != 0) && (j != (n-1)))
                {
                if (T[i-1][j] != -3)
                    T[i-1][j] = T[i-1][j] + 1;
                if (T[i-1][j-1] != -3)
                    T[i-1][j-1] = T[i-1][j-1] + 1;
                if (T[i][j-1] != -3)
                    T[i][j-1] = T[i][j-1] + 1;
                if (T[i+1][j-1] != -3)
                    T[i+1][j-1] = T[i+1][j-1] + 1;
                if (T[i+1][j] != -3)
                    T[i+1][j] = T[i+1][j] + 1;
                if (T[i+1][j+1] != -3)
                    T[i+1][j+1] = T[i+1][j+1] + 1;
                if (T[i][j+1] != -3)
                    T[i][j+1] = T[i][j+1] + 1;
                if (T[i-1][j+1] != -3)
                    T[i-1][j+1] = T[i-1][j+1] + 1;
                }

Upvotes: 1

Views: 1369

Answers (2)

Micha&#235;l Roy
Micha&#235;l Roy

Reputation: 6471

You are really making it more complex than it is..

Why not use loops? They are made for doing these jobs. Cutting the task into smaller functions makes coding much easier and faster. It will also make your code easier to read and maintain.

[edit] I've added universal all-purpose, min and max macros, they're a must have in every C programmer's toolbox. Thanks @bolov for the suggestion.

#define MINE (-3)

// lower-case min, max are defined in <windows.h>, hence the choice 
// and the check.

#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif

int mine_detector(int board[M][N], int x, int y)
{
  int result, i, j, xmin, xmax, ymin, ymax;

  xmin = min(x - 1, 0);    // compute your boundaries beforehand
  xmax = max(x + 1, M - 1);
  ymin = min(y - 1, 0);
  ymax = max(y + 1, N - 1);

  if (board[x][y] == MINE)
    return MINE;

  result = 0;

  for (i = xmin; i <= xmax; ++i)
    for (j = ymin; j <= ymax; ++j)
      if (board[i][j] == MINE)
        ++result;

  return result;
}

void count_mines(int board[M][N])
{
  // returns detected mines on board[][] in board[][]
  int i, j;
  for (i = 0; i < M; ++i)
    for (j = 0; j < N; ++i)
       board[i][j] = mine_detector(board, i, j);
}

Upvotes: 1

Potatoswatter
Potatoswatter

Reputation: 137850

Your approach can probably be fixed to work, but it's already produced too many lines of code.

First, the data structure which holds both mines and adjacency counts is a little contrived. It does represent the visible board, but it's jamming two different kinds of information into the int datatype.

Second, listing the adjacent spots is less elegant than finding them automatically with a loop. The edges get special cases (literal edge cases!) but you could avoid this by padding them with zeroes.

So, for instance,

// Parameter "mines" is the minefield, plus a ring of zero values around the edge.
// Parameter "adjacence" must be pre-filled with zeroes. It has no such padding.
void mine_counting (const bool mines[MMAX+2][NMAX+2], int adjacence[MMAX][NMAX],
                    int m, int n) {
    for ( int di = -1; di <= 1; ++ di ) {
        for ( int dj = -1; dj <= 1; ++ dj ) {
            for ( int i = 0; i != m; ++ i ) {
                for ( int j = 0; j != n; ++ j ) {
                    adjacence[i][j] += mines[i + di + 1][j + dj + 1];
                }
            }
        }
    }
}

If you wanted to make the coordinate systems of the two arrays match exactly, you could add the same padding to adjacence — it would be harmless. Then the +1's in the innermost loop would disappear.

Upvotes: 1

Related Questions