C语言实现扫雷游戏(一步步教你如何写扫雷)

您所在的位置:网站首页 扫雷的代码 C语言实现扫雷游戏(一步步教你如何写扫雷)

C语言实现扫雷游戏(一步步教你如何写扫雷)

2024-04-01 17:25| 来源: 网络整理| 查看: 265

扫雷游戏 使用工具 一、基本思路和流程1. 扫雷游戏的游戏规则2. 代码实现思路 二、实现步骤(具体步骤)1. 使用多文件形式2. 代码实现定义各个难度等级的棋盘大小和雷的数量定义全局变量游戏规则界面菜单界面选择实现选择难度界面初始化和打印棋盘棋盘初始化棋盘打印棋盘 存放雷排查放雷 三、整体游戏流程附上所有代码test.c 文件game.h 文件game.c 文件

使用工具

Visual Studio 2019

一、基本思路和流程 1. 扫雷游戏的游戏规则

1. 在已经准备好的棋盘中,找出所有没有设有雷的位置,找出所有位置后,既获得胜利 2. 该游戏设有三种难度等级,分别是简单、中级和困难模式,每种模式的棋盘大小和 雷的数目都不一样 3. 踩到雷即游戏失败

2. 代码实现思路

1. 游戏规则界面,给玩家讲述该游戏的游戏规则 2. 菜单界面: 玩家可选择开始游戏或退出游戏 3. 选择游戏难度界面,玩家可选择游戏难度 4. 初始化棋盘和打印棋盘 5. 玩家开始选择排雷坐标 6. 玩家落下排雷坐标后打印棋盘,并判断玩家是否踩到雷或者是否已经找出所有非雷位置 7. 若玩家所排位置周围的雷的个数为0,则将该位置改为空格,并利用递归对周围八个位置分别进行排雷 8. 游戏结束后,玩家可选择继续游戏或者退出游戏

二、实现步骤(具体步骤) 1. 使用多文件形式

1. test.c 文件(源文件): 写整个游戏的大致过程 2. game.h 文件(头文件): 引用所需的头文件以及对各个程序所需函数的声明 3. game.c 文件(源文件):定义在game.h 中声明的函数

2. 代码实现 定义各个难度等级的棋盘大小和雷的数量

在game.h文件中,使用宏定义

//简单 #define EASY_ROW 9 #define EASY_COL 9 #define EASY_COUNT 15 //中级 #define MID_ROW 15 #define MID_COL 15 #define MID_COUNT 30 //困难 #define DIF_ROW 21 #define DIF_COL 21 #define DIF_COUNT 40 //简单 #define EASY_ROWS EASY_ROW+2 #define EASY_COLS EASY_COL+2 //中级 #define MID_ROWS MID_ROW+2 #define MID_COLS MID_COL+2 //困难 #define DIF_ROWS DIF_ROW+2 #define DIF_COLS DIF_COL+2 定义全局变量

在test.c 文件中

int ROW = 0; int COL = 0; int ROWS = 0; int COLS = 0; int count = 0; 游戏规则界面 参考代码如下: void game_rule() { printf("***********游戏规则: ***********\n"); printf("游戏开始前,你可以选择游戏难度,\n"); printf("设有简单,中级,困难三种难度,每\n"); printf("种难度棋盘大小和雷的数目都不一样,\n"); printf("当你把所有非雷位置找出时,既赢下\n"); printf("游戏,祝您游戏愉快\n"); printf("\n"); printf("\n"); } 菜单界面 代考代码如下: void menu() { printf("********************************\n"); printf("******** 1. play *********\n"); printf("******** 0. exit *********\n"); printf("********************************\n"); } 选择实现 参考代码如下 int main() { game_rule(); int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("选择错误\n"); break; } } while (input); return 0; } 选择难度界面 参考代码如下 void select_diffcult() { printf("************难度系数***********\n"); printf("********** 1. 简单 *********\n"); printf("********** 2. 中级 *********\n"); printf("********** 3. 困难 *********\n"); int input = 0; do { printf("请选择:>"); int select = 0; scanf("%d", &select); switch (select) { case 1: ROW = EASY_ROW; COL = EASY_COL; ROWS = EASY_ROWS; COLS = EASY_COLS; count = EASY_COUNT; input = 0; break; case 2: ROW = MID_ROW; COL = MID_COL; ROWS = MID_ROWS; COLS = MID_COLS; count = MID_COUNT; input = 0; break; case 3: ROW = DIF_ROW; COL = DIF_COL; ROWS = DIF_ROWS; COLS = DIF_COLS; count = DIF_COUNT; input = 0; break; default: input = 1; break; } } while (input); } 初始化和打印棋盘 棋盘 使用二维数组,由于定于数组设置大小只能用常量,所有为了避免越界,我们将棋盘大小设置为三种游戏模式中棋盘最大的那一类为了方便后续打印,我们将设置两个一样大小的数组,一个用来存放雷,一个用来打印 char mine[DIF_ROWS][DIF_COLS];//存放雷 char show[DIF_ROWS][DIF_COLS]; 初始化棋盘

mine[DIF_ROWS][DIF_COLS] 和 show[DIF_ROWS][DIF_COLS]都需要进行初始化

参考代码如下 void InitBoard(char board[DIF_ROWS][DIF_COLS], int rows, int cols, char ch) { int i = 0; for (i = 0; i board[i][j] = ch; } } } 打印棋盘 参考代码如下 void DisPlayBoard(char board[DIF_ROWS][DIF_COLS], int row, int col) { int i = 0; printf(" "); for (i = 1; i printf("---"); } printf("\n"); for (i = 1; i printf(" %c ", board[i][j]); } printf("\n"); } } 实现后效果 在这里插入图片描述 存放雷 存放雷可能出现的问题

1. 随机生成雷的过程中,需要判断雷的位置是否已被占用

可以使用时间戳生成随机数,随机生成雷的坐标,利用循环解决位置是否被占用的问题

参考代码如下 //cnt是雷的数量 void SetMine(char mine[DIF_ROWS][DIF_COLS], int row, int col, int cnt) { while (cnt > 0) { int x = 0; int y = 0; x = rand() % row + 1; y = rand() % col + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; cnt--; } } } 排查放雷

如果玩家排查的位置的周围雷的数量为0, 那么久要利用递归来对周围的八个位置进行排查,为了防止递归的栈溢出问题,需要将已经排查过得位置进行标记

参考代码如下 //排查位置周围雷的数量 int MineCount(char mine[DIF_ROWS][DIF_COLS], int x, int y) { int cnt = mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0'; return cnt; } //对排查位置周围八个位置进行排查 void Expend(char mine[DIF_ROWS][DIF_COLS], char show[DIF_ROWS][DIF_COLS], int x, int y, int visted[DIF_ROWS][DIF_COLS]) { //visted[x][y] == 1; int vist[DIF_ROWS][DIF_COLS] = { 0 }; int cnt = MineCount(mine, x, y); if (cnt > 0) show[x][y] = cnt + '0'; else { show[x][y] = ' '; if (visted[x - 1][y - 1] == 0) { vist[x - 1][y - 1] = 1; visted[x - 1][y - 1] = 1; } if (visted[x - 1][y] == 0) { vist[x - 1][y] = 1; visted[x - 1][y] = 1; } if (visted[x - 1][y + 1] == 0) { vist[x - 1][y + 1] = 1; visted[x - 1][y + 1] = 1; } if (visted[x][y - 1] == 0) { vist[x][y - 1] = 1; visted[x][y - 1] = 1; } if (visted[x][y + 1] == 0) { vist[x ][y + 1] = 1; visted[x][y + 1] = 1; } if (visted[x + 1][y - 1] == 0) { vist[x + 1][y - 1] = 1; visted[x + 1][y - 1] = 1; } if (visted[x + 1][y] == 0) { vist[x + 1][y] = 1; visted[x + 1][y] = 1; } if (visted[x + 1][y + 1] == 0) { vist[x + 1][y + 1] = 1; visted[x + 1][y + 1] = 1; } if (vist[x - 1][y - 1] == 1) { Expend(mine, show, x - 1, y - 1, visted); } if (vist[x - 1][y] == 1) { Expend(mine, show, x - 1, y, visted); } if (vist[x - 1][y + 1] == 1) { Expend(mine, show, x - 1, y + 1, visted); } if (vist[x][y - 1] == 1) { Expend(mine, show, x, y - 1, visted); } if (vist[x][y + 1] == 1) { Expend(mine, show, x, y + 1, visted); } if (vist[x + 1][y - 1] == 1) { Expend(mine, show, x + 1, y - 1, visted); } if (vist[x + 1][y] == 1) { Expend(mine, show, x + 1, y, visted); } if (vist[x + 1][y + 1] == 1) { Expend(mine, show, x + 1, y + 1, visted); } } } //排查雷 void FindMine(char mine[DIF_ROWS][DIF_COLS], char show[DIF_ROWS][DIF_COLS], int row, int col, int cnt, int visted[DIF_ROWS][DIF_COLS]) { while (1) { int x = 0; int y = 0; printf("请输入:>"); scanf("%d%d", &x, &y); if (x >= 1 && x = 1 && y printf("该位子已被占用\n"); } else if (mine[x][y] == '1') { show[x][y] = '$'; DisPlayBoard(show, row, col); printf("你踩到雷了\n"); break; } else { visted[x][y] == 1; Expend(mine, show, x, y, visted); DisPlayBoard(show, row, col); } } else { printf("超出范围\n"); } int count = 0; int i = 0; for (i = 1; i if (show[i][j] == '*') { count++; } } } if (count == cnt) { printf("恭喜你,你赢了\n"); break; } } } 三、整体游戏流程 参考代码如下 void game() { select_diffcult(); char mine[DIF_ROWS][DIF_COLS]; char show[DIF_ROWS][DIF_COLS]; int visted[DIF_ROWS][DIF_COLS]; int i = 0; for (i = 0; i if (i == 0) visted[i][j] = 1; else if (j == 0) visted[i][j] = 1; else if (i == ROWS - 1) visted[i][j] = 1; else if (j == COLS - 1) visted[i][j] = 1; else visted[i][j] = 0; } } //初始化棋盘 InitBoard(mine, ROWS, COLS, '0'); InitBoard(show, ROWS, COLS, '*'); //打印棋盘 DisPlayBoard(show, ROW, COL); //存放雷 SetMine(mine, ROW, COL, count); //排查雷 FindMine(mine, show, ROW, COL, count, visted); } 附上所有代码 test.c 文件 #include "game.h" int ROW = 0; int COL = 0; int ROWS = 0; int COLS = 0; int count = 0; void game_rule() { printf("***********游戏规则: ***********\n"); printf("游戏开始前,你可以选择游戏难度,\n"); printf("设有简单,中级,困难三种难度,每\n"); printf("种难度棋盘大小和雷的数目都不一样,\n"); printf("当你把所有非雷位置找出时,既赢下\n"); printf("游戏,祝您游戏愉快\n"); printf("\n"); printf("\n"); } void menu() { printf("********************************\n"); printf("******** 1. play *********\n"); printf("******** 0. exit *********\n"); printf("********************************\n"); } void select_diffcult() { printf("************难度系数***********\n"); printf("********** 1. 简单 *********\n"); printf("********** 2. 中级 *********\n"); printf("********** 3. 困难 *********\n"); int input = 0; do { printf("请选择:>"); int select = 0; scanf("%d", &select); switch (select) { case 1: ROW = EASY_ROW; COL = EASY_COL; ROWS = EASY_ROWS; COLS = EASY_COLS; count = EASY_COUNT; input = 0; break; case 2: ROW = MID_ROW; COL = MID_COL; ROWS = MID_ROWS; COLS = MID_COLS; count = MID_COUNT; input = 0; break; case 3: ROW = DIF_ROW; COL = DIF_COL; ROWS = DIF_ROWS; COLS = DIF_COLS; count = DIF_COUNT; input = 0; break; default: input = 1; break; } } while (input); } void game() { select_diffcult(); char mine[DIF_ROWS][DIF_COLS]; char show[DIF_ROWS][DIF_COLS]; int visted[DIF_ROWS][DIF_COLS]; int i = 0; for (i = 0; i if (i == 0) visted[i][j] = 1; else if (j == 0) visted[i][j] = 1; else if (i == ROWS - 1) visted[i][j] = 1; else if (j == COLS - 1) visted[i][j] = 1; else visted[i][j] = 0; } } //初始化棋盘 InitBoard(mine, ROWS, COLS, '0'); InitBoard(show, ROWS, COLS, '*'); //打印棋盘 DisPlayBoard(show, ROW, COL); //存放雷 SetMine(mine, ROW, COL, count); //排查雷 FindMine(mine, show, ROW, COL, count, visted); } int main() { game_rule(); int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("选择错误\n"); break; } } while (input); return 0; } game.h 文件 #pragma once #include #include #include //简单 #define EASY_ROW 9 #define EASY_COL 9 #define EASY_COUNT 15 //中级 #define MID_ROW 15 #define MID_COL 15 #define MID_COUNT 30 //困难 #define DIF_ROW 21 #define DIF_COL 21 #define DIF_COUNT 40 //简单 #define EASY_ROWS EASY_ROW+2 #define EASY_COLS EASY_COL+2 //中级 #define MID_ROWS MID_ROW+2 #define MID_COLS MID_COL+2 //困难 #define DIF_ROWS DIF_ROW+2 #define DIF_COLS DIF_COL+2 //初始化棋盘 extern void InitBoard(char board[DIF_ROWS][DIF_COLS], int rows, int cols,char ch); //打印棋盘 extern void DisPlayBoard(char board[DIF_ROWS][DIF_COLS], int row, int col); //存放雷 extern void SetMine(char mine[DIF_ROWS][DIF_COLS], int row, int col, int cnt); //排查雷 extern void FindMine(char mine[DIF_ROWS][DIF_COLS], char show[DIF_ROWS][DIF_COLS], int row, int col, int cnt, int visted[DIF_ROWS][DIF_COLS]); extern int MineCount(char mine[DIF_ROWS][DIF_COLS], int x, int y); extern void Expend(char mine[DIF_ROWS][DIF_COLS], char show[DIF_ROWS][DIF_COLS], int x, int y, int visted[DIF_ROWS][DIF_COLS]); game.c 文件 #include "game.h" void InitBoard(char board[DIF_ROWS][DIF_COLS], int rows, int cols, char ch) { int i = 0; for (i = 0; i board[i][j] = ch; } } } void DisPlayBoard(char board[DIF_ROWS][DIF_COLS], int row, int col) { int i = 0; printf(" "); for (i = 1; i printf("---"); } printf("\n"); for (i = 1; i printf(" %c ", board[i][j]); } printf("\n"); } } void SetMine(char mine[DIF_ROWS][DIF_COLS], int row, int col, int cnt) { while (cnt > 0) { int x = 0; int y = 0; x = rand() % row + 1; y = rand() % col + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; cnt--; } } } int MineCount(char mine[DIF_ROWS][DIF_COLS], int x, int y) { int cnt = mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0'; return cnt; } void Expend(char mine[DIF_ROWS][DIF_COLS], char show[DIF_ROWS][DIF_COLS], int x, int y, int visted[DIF_ROWS][DIF_COLS]) { //visted[x][y] == 1; int vist[DIF_ROWS][DIF_COLS] = { 0 }; int cnt = MineCount(mine, x, y); if (cnt > 0) show[x][y] = cnt + '0'; else { show[x][y] = ' '; if (visted[x - 1][y - 1] == 0) { vist[x - 1][y - 1] = 1; visted[x - 1][y - 1] = 1; } if (visted[x - 1][y] == 0) { vist[x - 1][y] = 1; visted[x - 1][y] = 1; } if (visted[x - 1][y + 1] == 0) { vist[x - 1][y + 1] = 1; visted[x - 1][y + 1] = 1; } if (visted[x][y - 1] == 0) { vist[x][y - 1] = 1; visted[x][y - 1] = 1; } if (visted[x][y + 1] == 0) { vist[x ][y + 1] = 1; visted[x][y + 1] = 1; } if (visted[x + 1][y - 1] == 0) { vist[x + 1][y - 1] = 1; visted[x + 1][y - 1] = 1; } if (visted[x + 1][y] == 0) { vist[x + 1][y] = 1; visted[x + 1][y] = 1; } if (visted[x + 1][y + 1] == 0) { vist[x + 1][y + 1] = 1; visted[x + 1][y + 1] = 1; } if (vist[x - 1][y - 1] == 1) { Expend(mine, show, x - 1, y - 1, visted); } if (vist[x - 1][y] == 1) { Expend(mine, show, x - 1, y, visted); } if (vist[x - 1][y + 1] == 1) { Expend(mine, show, x - 1, y + 1, visted); } if (vist[x][y - 1] == 1) { Expend(mine, show, x, y - 1, visted); } if (vist[x][y + 1] == 1) { Expend(mine, show, x, y + 1, visted); } if (vist[x + 1][y - 1] == 1) { Expend(mine, show, x + 1, y - 1, visted); } if (vist[x + 1][y] == 1) { Expend(mine, show, x + 1, y, visted); } if (vist[x + 1][y + 1] == 1) { Expend(mine, show, x + 1, y + 1, visted); } } } void FindMine(char mine[DIF_ROWS][DIF_COLS], char show[DIF_ROWS][DIF_COLS], int row, int col, int cnt,int visted[DIF_ROWS][DIF_COLS]) { while (1) { int x = 0; int y = 0; printf("请输入:>"); scanf("%d%d", &x, &y); if (x >= 1 && x = 1 && y printf("该位子已被占用\n"); } else if (mine[x][y] == '1') { show[x][y] = '$'; DisPlayBoard(show, row, col); printf("你踩到雷了\n"); break; } else { visted[x][y] == 1; Expend(mine, show, x, y, visted); DisPlayBoard(show, row, col); } } else { printf("超出范围\n"); } int count = 0; int i = 0; for (i = 1; i if (show[i][j] == '*') { count++; } } } if (count == cnt) { printf("恭喜你,你赢了\n"); break; } } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3