扫雷c语言
时间: 2023-06-21 10:15:23 浏览: 52
扫雷是一种经典的游戏,可以使用C语言来实现。以下是一个简单的扫雷程序的实现示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROWS 10 // 行数
#define COLS 10 // 列数
#define MINES 10 // 雷的数量
void init_game(char board[][COLS], int rows, int cols); // 初始化游戏面板
void print_board(char board[][COLS], int rows, int cols); // 打印游戏面板
void set_mines(char board[][COLS], int rows, int cols, int mines); // 布雷
void get_neighbors(int row, int col, int rows, int cols, int neighbors[]); // 获取邻居格子
int count_mines(char board[][COLS], int row, int col, int rows, int cols); // 计算某个格子周围的雷数
void reveal(char board[][COLS], int row, int col, int rows, int cols); // 翻开某个格子
int game_over(char board[][COLS], int rows, int cols); // 判断游戏是否结束
int main()
{
char board[ROWS][COLS];
int row, col;
srand((unsigned)time(NULL)); // 设置随机数种子
init_game(board, ROWS, COLS); // 初始化游戏面板
set_mines(board, ROWS, COLS, MINES); // 布雷
print_board(board, ROWS, COLS); // 打印游戏面板
while (1) {
printf("请输入坐标(行 列): ");
scanf("%d %d", &row, &col);
if (row < 0 || row >= ROWS || col < 0 || col >= COLS) {
printf("输入错误,请重新输入\n");
continue;
}
if (board[row][col] == '*') { // 点到雷了
printf("游戏结束!你输了\n");
board[row][col] = 'X'; // 标记点到的雷
print_board(board, ROWS, COLS);
break;
} else {
reveal(board, row, col, ROWS, COLS); // 翻开格子
print_board(board, ROWS, COLS);
}
if (game_over(board, ROWS, COLS)) { // 判断游戏是否结束
printf("游戏结束!你赢了\n");
break;
}
}
return 0;
}
// 初始化游戏面板
void init_game(char board[][COLS], int rows, int cols)
{
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
board[i][j] = '-';
}
}
}
// 打印游戏面板
void print_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");
}
printf("\n");
}
// 布雷
void set_mines(char board[][COLS], int rows, int cols, int mines)
{
int count = 0, i, j;
while (count < mines) {
i = rand() % rows;
j = rand() % cols;
if (board[i][j] == '-') {
board[i][j] = '*';
count++;
}
}
}
// 获取邻居格子
void get_neighbors(int row, int col, int rows, int cols, int neighbors[])
{
int i, j, k = 0;
for (i = row - 1; i <= row + 1; i++) {
for (j = col - 1; j <= col + 1; j++) {
if (i >= 0 && i < rows && j >= 0 && j < cols && (i != row || j != col)) {
neighbors[k++] = i * cols + j;
}
}
}
}
// 计算某个格子周围的雷数
int count_mines(char board[][COLS], int row, int col, int rows, int cols)
{
int neighbors[8], count = 0, i;
get_neighbors(row, col, rows, cols, neighbors);
for (i = 0; i < 8; i++) {
if (board[neighbors[i] / cols][neighbors[i] % cols] == '*') {
count++;
}
}
return count;
}
// 翻开某个格子
void reveal(char board[][COLS], int row, int col, int rows, int cols)
{
int count;
if (board[row][col] != '-') { // 已经翻开了
return;
}
count = count_mines(board, row, col, rows, cols);
if (count > 0) { // 周围有雷
board[row][col] = '0' + count;
} else { // 周围没有雷
board[row][col] = ' ';
reveal(board, row - 1, col, rows, cols);
reveal(board, row + 1, col, rows, cols);
reveal(board, row, col - 1, rows, cols);
reveal(board, row, col + 1, rows, cols);
}
}
// 判断游戏是否结束
int game_over(char board[][COLS], int rows, int cols)
{
int i, j, count = 0;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
if (board[i][j] == '-' || board[i][j] == '*') {
count++;
}
}
}
return count == MINES;
}
```
在这个示例程序中,我们使用二维字符数组来表示游戏面板。其中,'-'表示未翻开的格子,'*'表示雷,' '表示周围没有雷的格子,'1'-'8'表示周围有1-8个雷的格子,'X'表示点到的雷。我们使用了递归算法来实现翻开格子的功能,当某个格子周围没有雷时,我们会递归地翻开它周围的格子,直到所有周围有雷的格子都被标记为'1'-'8'。
这只是一个简单的示例程序,还有很多可以改进的地方。比如,可以添加计时器和计分系统,以及更加友好的界面等等。