扫雷是一款经典的单人益智游戏,游戏规则是在一个方格矩阵中,随机分布一定数量的地雷,玩家需要依靠已知的数字提示,找出所有没有地雷的方格,而不触发任何地雷。
以下是一个用C语言实现的扫雷游戏的示例代码,其中用到了控制台界面和键盘输入:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <windows.h>
#define WIDTH 10
#define HEIGHT 10
#define MINES 10
// 游戏状态
enum {GAME_PLAYING, GAME_WIN, GAME_LOSE};
// 地图
int map[HEIGHT][WIDTH];
// 游戏状态
int game_state;
// 绘制游戏界面
void draw_board()
{
system("cls");
printf("Minesweeper\n\n");
printf(" ");
for (int i = 0; i < WIDTH; i++) {
printf("%d ", i);
}
printf("\n");
printf(" ");
for (int i = 0; i < WIDTH; i++) {
printf("--");
}
printf("\n");
for (int i = 0;; i < HEIGHT; i++) {
printf("%2d |", i);
for (int j = 0; j < WIDTH; j++) {
if (map[i][j] == -1) {
printf("* ");
} else if (map[i][j] == 0) {
printf(". ");
} else {
printf("%d ", map[i][j]);
}
}
printf("\n");
if (i == HEIGHT-1) {
printf(" ");
for (int i = 0; i < WIDTH; i++) {
printf("--");
}
printf("\n");
break;
}
}
}
// 随机生成地雷
void generate_mines(int first_x, int first_y)
{
int count = 0;
while (count < MINES) {
int x = rand() % WIDTH;
int y = rand() % HEIGHT;
if (map[y][x] != -1 && (x != first_x || y != first_y)) {
map[y][x] = -1;
count++;
}
}
}
// 获取指定位置周围地雷数量
int get_mine_count(int x, int y)
{
int count = 0;
for (int i = y-1; i <= y+1; i++) {
for (int j = x-1; j <= x+1; j++) {
if (i >= 0 && i < HEIGHT && j >= 0 && j < WIDTH && map[i][j] == -1) {
count++;
}
}
}
return count;
}
// 检查是否已经赢得游戏
int check_win()
{
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if (map[i][j] >= 0 && map[i][j] <= 8) {
if (map[i][j] != get_mine_count(j, i)) {
return 0;
}
}
}
}
return 1;
}
// 开始游戏
void play_game(int first_x, int first_y)
{
// 初始化地图
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
map[i][j] = 0;
}
}
// 随机生成地雷
generate_mines(first_x, first_y);
// 计算周围地雷数量
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if (map[i][j] != -1) {
map[i][j] = get_mine_count(j, i);
}
}
}
// 游戏开始
game_state = GAME_PLAYING;
draw_board();
while (game_state == GAME_PLAYING) {
// 获取玩家输入
int x, y;
printf("Enter x and y (separated by space): ");
scanf("%d %d", &x, &y);
// 检查输入是否合法
if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
printf("Invalid input!\n");
continue;
}
if (map[y][x] != 0) {
printf("This cell has already been opened!\n");
continue;
}
// 打开该位置
if (map[y][x] == -1) {
game_state = GAME_LOSE;
} else {
map[y][x] = get_mine_count(x, y);
draw_board();
if (check_win()) {
game_state = GAME_WIN;
}
}
}
// 游戏结束
draw_board();
if (game_state == GAME_WIN) {
printf("Congratulations! You win!\n");
} else {
printf("Game over!\n");
}
}
int main()
{
srand((unsigned int) time(NULL));
int first_x, first_y;
printf("Enter the first move (x and y separated by space): ");
scanf("%d %d", &first_x, &first_y);
play_game(first_x, first_y);
return 0;
}
Minesweeper
0 1 2 3 4 5 6 7 8 9
--------------------
0 | 0 0 0 0 0 0 0 0 0 0
1 | 0 . . . . . . . . .
2 | 0 . . . . . . . . .
3 | 0 . . . . . . . . .
4 | 0 . . . . . . . . .
5 | 0 . . . . . . . . .
6 | 0 . . . . . . . . .
7 | 0 . . . . . . . . .
8 | 0 . . . . . . . . .
9 | 0 . . . . . . . . .
--------------------
Enter x and y (separated by space): 1 1
2. 如果该位置是地雷,则游戏失败,输出失败信息,例如:
Minesweeper
0 1 2 3 4 5 6 7 8 9
--------------------
0 | 0 0 0 0 0 0 0 0 0 0
1 | 0 * . . . . . . . .
2 | 0 . . . . . . . . .
3 | 0 . . . . . . . . .
4 | 0 . . . . . . . . .
5 | 0 . . . . . . . . .
6 | 0 . . . . . . . . .
7 | 0 . . . . . . . . .
8 | 0 . . . . . . . . .
9 | 0 . . . . . . . . .
--------------------
Game over!
3. 如果该位置不是地雷,则显示该位置周围的地雷数量,并将其标记为已经打开,例如:
Minesweeper
0 1 2 3 4 5 6 7 8 9
--------------------
0 | 0 0 0 0 0 0 0 0 0 0
1 | 0 * 1 . . . . . . .
2 | 0 1 1 . . . . . . .
3 | 0 . . . . . . . . .
4 | 0 . . . . . . . . .
5 | 0 . . . . . . . . .
6 | 0 . . . . . . . . .
7 | 0 . . . . . . . . .
8 | 0 . . . . . . . . .
9 | 0 . . . . . . . . .
--------------------
Enter x and y (separated by space):
4. 如果玩家打开了所有没有地雷的方格,则游戏胜利,输出胜利信息,例如:
Minesweeper
0 1 2 3 4 5 6 7 8 9
--------------------
0 | 0 0 0 0 0 0 0 0 0 0
1 | 0 * 1 0 0 0 0 0 0 0
2 | 0 1 1 0 0 0 0 0 0 0
3 | 0 1 0 0 0 0 0 0 0 0
4 | 0 1 1 1 0 0 0 0 0 0
5 | 0 0 0 1 1 0 0 0 0 0
6 | 0 0 0 0 1 1 1 0 0 0
7 | 0 0 0 0 0 0 1 1 1 0
8 | 0 0 0 0 0 0