我必须重新创建游戏的简单版本" 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;
}
答案 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);
}