"扫雷"在C中,计算周围地雷的麻烦在电路板的某个位置附近

时间:2017-06-30 19:35:41

标签: c minesweeper

我必须重新创建游戏的简单版本" Minefield"在C中,但我在计算电路板上某个位置附近有多少个地雷时遇到了麻烦。我的代码遍布整个阵列(板)搜索地雷。当它找到一个矿山时,它应该在矿山的所有周边地点加起来+1。我的代码仅适用于T [0] [0]的周围点。 m和n代表电路板上的行数和列数。请帮助!!

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;
                }

2 个答案:

答案 0 :(得分:1)

您的方法可能已经修复,但已经生成了太多代码。

首先,包含地雷和邻接计数的数据结构有点人为。它确实代表了可见的电路板,但它将两种不同类型的信息干扰到int数据类型中。

其次,列出相邻点不如使用循环自动查找它们更优雅。边缘得到特殊情况(字面边缘情况!),但你可以通过用零填充它们来避免这种情况。

所以,例如,

// 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];
                }
            }
        }
    }
}

如果你想让两个数组的坐标系完全匹配,你可以将相同的填充添加到adjacence - 它将是无害的。然后,最里面的循环中的+1将消失。

答案 1 :(得分:1)

你真的让它变得更复杂。

为什么不使用循环?他们是为做这些工作而做的。将任务切割成更小的功能使编码更容易,更快捷。它还可以使您的代码更易于阅读和维护。

[edit]我已经添加了通用的通用,最小和最大宏,它们是每个C程序员工具箱中必备的。谢谢@bolov的建议。

#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);
}