我目前开始学习C语言。 作为我的家庭作业,我试图在C中制作一个控制台版的扫雷。 但是,它在某种程度上不起作用,我不知道为什么。 问题是,我不允许修改其中的一些功能和变量。他们是
(init_board,display_board,show_interface) 这些是我不允许修改的。
对于10 * 10扫雷, 我的第一个想法是制作一个12 * 12的电路板,并在第一次用户输入之前计算我需要的所有功能。
当用户扫描采矿方块时,程序终止并且它正是我想要的,所以它工作正常。但是,当用户扫描未定义的方形时,函数reveal()似乎无法正常工作。
这是我有缺陷的代码......有人可以帮助我吗?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#pragma warning(disable: 4996)
#define BOARD_SIZE 10
#define SQUARE_NUM (BOARD_SIZE*BOARD_SIZE)
#define MINE_NUM 17
#define SHUFFLE_NUM 100000
int left_square;
int mines; // only for debugging
int end; // only 1 when player lose
int mine_board[BOARD_SIZE][BOARD_SIZE];
/* 0 : non-mined, 1 : mined */
int display_board[BOARD_SIZE][BOARD_SIZE];
/* -1 : no mines around, 0 : unknown, 1~8 : number of mines */
int board_revealed[BOARD_SIZE + 2][BOARD_SIZE + 2];
int calculate_board[BOARD_SIZE + 2][BOARD_SIZE + 2][2];
// 0 : non-mined, 1 : mined
// layer 0 : current mine state
// layer 1 : how many mines are nearby
void board_oracle();
void store_board(); // store mine_board to calculate_board
void init_board(); // initialize mine_board by randomly planting fixed number of mines
void show_interface(); // print display_board
void reveal(int x, int y);
int sweep(int x, int y);
/*
* return : 1 if player sweeps mined square, else 0
*/
int check_game();
/*
* check if the player swept all non-mined squares
* return : 1 if player swept all non-mined squares, else 0
*/
int main(void) //Todo
{
init_board();
show_interface();
store_board();
printf("%d unmined square remaining, %d mines here\n", left_square, mines); // debugging
while (check_game() == 0)
{
int x, y;
printf("input coordinate : ");
scanf("%d %d", &x, &y);
if (sweep(x, y) == 0)
{
reveal(x, y);
}
else
{
display_board[x - 1][y - 1] = -1;
end = 1;
show_interface();
printf("player lost");
return 0;
}
show_interface();
}
}
void init_board()
{
int i;
int shuffle[BOARD_SIZE * BOARD_SIZE];
int temp;
int r1, r2;
srand(time(NULL)); // set seed
// initialize shuffle array
for (i = 0; i<SQUARE_NUM; i++)
shuffle[i] = i;
// shuffling
for (i = 0; i<SHUFFLE_NUM; i++)
{
r1 = rand() % SQUARE_NUM;
r2 = rand() % SQUARE_NUM;
temp = shuffle[r1];
shuffle[r1] = shuffle[r2];
shuffle[r2] = temp;
}
// get mine coordinates from shuffled array
for (i = 0; i<MINE_NUM; i++)
mine_board[shuffle[i] / BOARD_SIZE][shuffle[i] % BOARD_SIZE] = 1;
}
//given
void show_interface()
{
int i, j;
system("cls"); // clear the screen
// rest of this function just prints out display_board
printf(" ");
for (i = 0; i<BOARD_SIZE; i++)
printf(" %2d ", i + 1);
for (i = 0; i<BOARD_SIZE; i++)
{
printf("\n %2d ", i + 1);
for (j = 0; j<BOARD_SIZE; j++)
{
if (display_board[i][j] == -1)
{
if (mine_board[i][j] == 1)
printf(" * ");
else
printf(" X ");
}
else if (display_board[i][j] == 0)
printf(" - ");
else
printf(" %d ", display_board[i][j]);
}
printf("\n");
}
printf("\n |\n v\n\n Y\n\n");
}
//given
int sweep(int x, int y) // TODo
{
if (calculate_board[x][y][0] == 0)
{
return 0;
}
else
{
return 1;
}
}
//done
int check_game()
{
if (end == 1)
{
return 1;
}
else if (left_square == 0)
{
printf("You win");
return 2; // indicates win
}
else
{
return 0;
}
}
void store_board()
{
for (int i = 0; i < 100; i++)
{
int x = i / 10;
int y = i % 10;
calculate_board[x + 1][y + 1][0] = mine_board[x][y];
if (calculate_board[x + 1][y + 1][0] == 0)
{
left_square++;
}
else
{
mines++;
}
}
}
// properly working.
void board_oracle()
{
int i = 1, j = 1;
for (; i < 11; i++)
{
for (; j < 11; j++)
{
calculate_board[i][j][1] = calculate_board[i - 1][j - 1][0] + calculate_board[i][j - 1][0] + calculate_board[i - 1][j][0] + calculate_board[i][j + 1][0] + calculate_board[i - 1][j + 1][0] + calculate_board[i + 1][j - 1][0] + calculate_board[i + 1][j][0] + calculate_board[i + 1][j + 1][0];
}
}
}
void reveal(int x, int y)
{
if (x >= 1 && y >= 1 && x<= 11 && y <= 11)
{
if (board_revealed[x][y] == 1)
{
return;
}
else
{
if (calculate_board[x][y][1] == 0)
{
reveal(x - 1, y - 1);
reveal(x - 1, y);
reveal(x - 1, y + 1);
reveal(x, y - 1);
reveal(x, y + 1);
reveal(x + 1, y - 1);
reveal(x + 1, y);
reveal(x + 1, y + 1);
}
else
{
display_board[x - 1][y - 1] = calculate_board[x][y][1];
board_revealed[x][y] = 1;
}
}
}
else
{
return;
}
}
正如一些评论所说,准确地陈述问题 当我运行程序并输入像2 3这样的输入时,程序就崩溃并说 &#34;分段错误(核心转储)&#34; 当它被开采方形时,错误不会发生(它打印&#34;玩家丢失&#34;并完成) 只有在扫描非开采方块时才会出现错误。
正如一些人所说,我添加了一行以确保reveal()停在边缘......但它不会让它变得更好......
答案 0 :(得分:1)
问题1:
test.c: In function 'reveal':
test.c:221:41: warning: statement with no effect [-Wunused-value]
display_board[x - 1][y - 1] == calculate_board[x][y][1];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
这应该是=
。但更重要的是,您应该启用编译器警告,例如在带有-Wall
的gcc上。
问题2:
当我选择2 2
时,函数reveal
会被坐标调用:
2 2 1 1 0 0 -1 -1 -1 0 -2 -1 -3 -2 -4 -3
。所以不管你是否让网格变得更大,它最终都会崩溃。在你调用reveal
8次的时候,首先要检查坐标是否有效,即&gt; = 0和&lt; ñ。那么也许你也不需要让网格更大。