C语言实现扫雷游戏详细代码实例
什么是扫雷游戏
扫雷游戏是一款经典的益智游戏,玩家需要根据已知格子上的数字,推断出未知格子内是否包含地雷,在最短时间内将所有没有地雷的格子揭开。对于揭开有地雷的格子,游戏即结束。
扫雷游戏的实现思路
通过C语言编写扫雷游戏,需要实现以下几步:
- 初始化游戏:创建棋盘,布置地雷,设置每个格子周围地雷的数量。
- 根据玩家的输入操作,判断对应格子是否是地雷,如果存在地雷则结束游戏,否则将该格子打开。
- 判断游戏胜利条件是否满足:即所有非地雷的格子是否全部被打开。
扫雷游戏的实现代码示例
以下代码示例实现了一个基本的扫雷游戏,其中包括棋盘初始化、地雷布置、揭开格子等功能。
棋盘初始化
void init_board(char board[][WIDTH], int rows, int cols, char val) {
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
board[i][j] = val;
}
}
}
地雷布置
void setup_mines(char board[][WIDTH], int rows, int cols, int num_mines) {
int cnt = 0; /* 记录已布置的地雷数量 */
int x, y;
srand((unsigned)time(NULL)); /* 随机数种子 */
while (cnt < num_mines) {
x = rand() % rows;
y = rand() % cols;
if (board[x][y] != MINE_SYM) { /* 如果该位置不是地雷,进行布置 */
board[x][y] = MINE_SYM;
cnt++;
}
}
}
揭开格子
int open_cell(char board[][WIDTH], int rows, int cols, int x, int y) {
if (board[x][y] == MINE_SYM) { /* 如果该位置是地雷,游戏结束 */
return GAME_OVER;
} else {
int cnt_mines = count_adjacent_mines(board, rows, cols, x, y); /* 计算周围地雷数量 */
board[x][y] = cnt_mines + '0'; /* 将该位置的值设置为周围地雷数量 */
if (cnt_mines == 0) { /* 如果周围没有地雷,递归打开周围八个位置 */
open_cell(board, rows, cols, x-1, y-1);
open_cell(board, rows, cols, x-1, y);
open_cell(board, rows, cols, x-1, y+1);
open_cell(board, rows, cols, x, y-1);
open_cell(board, rows, cols, x, y+1);
open_cell(board, rows, cols, x+1, y-1);
open_cell(board, rows, cols, x+1, y);
open_cell(board, rows, cols, x+1, y+1);
}
}
if (is_win(board, rows, cols)) { /* 判断游戏是否获胜 */
return GAME_WIN;
} else {
return CONTINUE_GAME;
}
}
完整代码示例
以下是基本扫雷游戏的完整代码示例,其中包括了上述三个功能实现,以及游戏循环的处理。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROWS 10
#define COLS 10
#define MINES 10
#define MINE_SYM '*'
#define GAME_OVER -1
#define GAME_WIN 1
#define CONTINUE_GAME 0
/* 棋盘初始化 */
void init_board(char board[][COLS], int rows, int cols, char val) {
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
board[i][j] = val;
}
}
}
/* 地雷布置 */
void setup_mines(char board[][COLS], int rows, int cols, int num_mines) {
int cnt = 0; /* 记录已布置的地雷数量 */
int x, y;
srand((unsigned)time(NULL)); /* 随机数种子 */
while (cnt < num_mines) {
x = rand() % rows;
y = rand() % cols;
if (board[x][y] != MINE_SYM) { /* 如果该位置不是地雷,进行布置 */
board[x][y] = MINE_SYM;
cnt++;
}
}
}
/* 计算某个格子周围的地雷数量 */
int count_adjacent_mines(char board[][COLS], int rows, int cols, int x, int y) {
int i, j;
int cnt = 0;
for (i = x - 1; i <= x + 1; i++) {
for (j = y - 1; j <= y + 1; j++) {
if (i >= 0 && i < rows && j >= 0 && j < cols) { /* 如果该位置合法 */
if (board[i][j] == MINE_SYM) { /* 如果是地雷 */
cnt++;
}
}
}
}
return cnt;
}
/* 揭开某个格子 */
int open_cell(char board[][COLS], int rows, int cols, int x, int y) {
if (board[x][y] == MINE_SYM) { /* 如果该位置是地雷,游戏结束 */
return GAME_OVER;
} else {
int cnt_mines = count_adjacent_mines(board, rows, cols, x, y); /* 计算周围地雷数量 */
board[x][y] = cnt_mines + '0'; /* 将该位置的值设置为周围地雷数量 */
if (cnt_mines == 0) { /* 如果周围没有地雷,递归打开周围八个位置 */
open_cell(board, rows, cols, x-1, y-1);
open_cell(board, rows, cols, x-1, y);
open_cell(board, rows, cols, x-1, y+1);
open_cell(board, rows, cols, x, y-1);
open_cell(board, rows, cols, x, y+1);
open_cell(board, rows, cols, x+1, y-1);
open_cell(board, rows, cols, x+1, y);
open_cell(board, rows, cols, x+1, y+1);
}
}
if (is_win(board, rows, cols)) { /* 判断游戏是否获胜 */
return GAME_WIN;
} else {
return CONTINUE_GAME;
}
}
/* 判断是否获胜 */
int is_win(char board[][COLS], int rows, int cols) {
int i, j;
int cnt_mines = 0;
int cnt_open = 0;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
if (board[i][j] == MINE_SYM) { /* 统计地雷数量 */
cnt_mines++;
}
if (board[i][j] >= '0' && board[i][j] <= '9') { /* 统计已打开的格子 */
cnt_open++;
}
}
}
if (cnt_open == rows * cols - cnt_mines) { /* 如果所有非地雷格子都已打开 */
return 1;
} else {
return 0;
}
}
/* 显示棋盘 */
void display_board(char board[][COLS], int rows, int cols) {
int i, j;
printf(" ");
for (j = 0; j < cols; j++) {
printf("%d ", j);
}
printf("\n");
for (i = 0; i < rows; i++) {
printf("%d ", i);
for (j = 0; j < cols; j++) {
printf("%c ", board[i][j]);
}
printf("\n");
}
}
int main() {
char board[ROWS][COLS];
int i, j;
int x, y;
int result;
init_board(board, ROWS, COLS, '-');
setup_mines(board, ROWS, COLS, MINES);
printf("Welcome to Minesweeper!\n");
printf("Please input the coordinates (x,y) to open cells.\n");
printf("For example, if you want to open (1,2), please input \"1 2\".\n\n");
while (1) {
display_board(board, ROWS, COLS);
printf("\nPlease input the coordinates: ");
scanf("%d %d", &x, &y);
result = open_cell(board, ROWS, COLS, x, y);
if (result == GAME_OVER) {
printf("\nGame over. You stepped on a mine!\n");
display_board(board, ROWS, COLS);
break;
} else if (result == GAME_WIN) {
printf("\nCongratulations! You win!\n");
display_board(board, ROWS, COLS);
break;
}
}
return 0;
}
示例说明
init_board
函数使用双重循环初始化棋盘,每个格子初始值为'-'
。setup_mines
函数使用随机数生成地雷位置,地雷用'*'
表示。open_cell
函数传入要打开的格子坐标(x,y)
,如果该位置是地雷,则返回GAME_OVER
,游戏结束;否则将该位置设置为周围地雷数量,并递归打开周围八个位置。如果打开后所有非地雷格子都已打开,返回GAME_WIN
,游戏胜利。- 完整代码实现了扫雷游戏的基本功能,可以正常运行。
下面两条示例说明:
- 如何设置游戏的难度?
你可以通过更改常量定义中的ROWS
、COLS
和MINES
来设置游戏的难度。例如,将棋盘大小增加到15×15
,增加地雷数量到30
,即可提高游戏难度。
- 如何添加计时功能?
可以在游戏开始时记录当前时间,在游戏结束时计算游戏时长,并输出到屏幕上。具体实现可参考以下代码示例:
#include <time.h>
int main() {
time_t start_time, end_time;
double time_used;
start_time = time(NULL);
/* 执行游戏代码 */
end_time = time(NULL);
time_used = difftime(end_time, start_time);
printf("\nTime used: %.2fs.\n", time_used);
return 0;
}
这样可以将展示运行过程消耗的时间。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现扫雷游戏详细代码实例 - Python技术站