C 语言扫雷游戏算法实现 - 基于控制台的简单方法
由于扫雷游戏的实现涉及到图形界面、事件处理等方面,本算法只提供一种基于控制台的简单实现方式。
- 定义游戏棋盘及雷区数组
使用二维数组定义游戏棋盘,其中每个元素表示一个方格,用数字表示该方格周围的雷数,-1表示该方格为雷。
int board[ROW][COL]; // 游戏棋盘,每个元素表示一个方格
int mine[ROW][COL]; // 雷区,-1表示该方格为雷,0表示非雷
- 初始化雷区
随机生成雷区,即在二维数组中随机选取若干个元素赋值为-1,表示该方格为雷。同时,计算每个非雷方格周围的雷数。
void initMine() {
int i, j, k;
// 初始化雷区
memset(mine, 0, sizeof(mine));
srand((unsigned int)time(NULL));
for (i = 0; i < MINE_NUM; i++) {
int x = rand() % ROW;
int y = rand() % COL;
if (mine[x][y] == -1) {
i--;
continue;
}
mine[x][y] = -1;
}
// 计算每个非雷方格周围的雷数
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
if (mine[i][j] == -1) continue;
for (k = 0; k < 8; k++) {
int x = i + dx[k];
int y = j + dy[k];
if (x >= 0 && x < ROW && y >= 0 && y < COL && mine[x][y] == -1) {
mine[i][j]++;
}
}
}
}
}
- 打印游戏棋盘
使用字符表示游戏棋盘,其中'*'表示未翻开的方格,'-'表示已翻开的空方格,“1-8”表示周围雷数,“X”表示已翻开的雷方格。
void printBoard() {
int i, j;
printf(" ");
for (j = 0; j < COL; j++) {
printf("%d ", j + 1);
}
printf("\n");
for (i = 0; i < ROW; i++) {
printf("%c ", 'A' + i);
for (j = 0; j < COL; j++) {
if (board[i][j] == -2) printf("* ");
else if (board[i][j] == -1) printf("X ");
else if (board[i][j] == 0) printf("- ");
else printf("%d ", board[i][j]);
}
printf("\n");
}
}
- 翻开指定方格
根据用户输入的坐标,翻开指定方格,如果该方格为雷,则游戏失败,否则更新游戏棋盘,并递归翻开周围的空方格。
void uncover(int x, int y) {
if (board[x][y] != -2) return; // 已翻开或标记为雷的方格无法翻开
if (mine[x][y] == -1) { // 翻开雷方格,游戏失败
printf("BOOM! You lose.\n");
board[x][y] = -1;
printBoard();
exit(0);
}
board[x][y] = mine[x][y];
if (board[x][y] == 0) { // 翻开空方格,递归翻开周围的空方格
int i;
for (i = 0; i < 8; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && nx < ROW && ny >= 0 && ny < COL) {
uncover(nx, ny);
}
}
}
}
- 标记雷方格
根据用户输入的坐标,将指定方格标记为雷,如果已经标记为雷,则取消标记。
void mark(int x, int y) {
if (board[x][y] == -2) board[x][y] = -3; // 标记为雷
else if (board[x][y] == -3) board[x][y] = -2; // 取消标记
}
- 主函数
在主函数中依次调用上述函数,实现扫雷游戏的逻辑。
int main() {
int i, j;
char x, y;
// 初始化游戏棋盘和雷区
memset(board, -2, sizeof(board));
initMine();
// 开始游戏
while (1) {
printBoard();
printf("Enter coordinate (row,column) or 'm' to mark a mine: ");
scanf(" %c%c", &x, &y);
if (x == 'm' || x == 'M') { // 标记雷方格
scanf(" %c%c", &x, &y);
mark(x - 'A', y - '1');
} else { // 翻开方格
uncover(x - 'A', y - '1');
}
// 判断游戏是否胜利
int count = 0;
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
if (board[i][j] == -2 || board[i][j] == -3) {
count++;
}
}
}
if (count == MINE_NUM) {
printf("Congratulations! You win.\n");
printBoard();
break;
}
}
return 0;
}
说明:
- 代码中
ROW、COL、MINE_NUM、dx、dy等变量需要根据实际情况进行定义。 - 由于这是一个简单的控制台版本,用户需要手动输入坐标,没有图形界面。
- 可以根据需要添加其他功能,例如游戏难度选择、计时器等。
原文地址: https://www.cveoy.top/t/topic/n2EI 著作权归作者所有。请勿转载和采集!