文章目录
- 前言
- 一、游戏规则介绍
- 二、基本思路流程介绍
- 三、代码实现
- 1.用户交互菜单(Menu函数)
- 2. Game函数
- 3.放雷函数(SetMines函数)
- 4.扫雷展示面板(ShowBoard函数和ShowLine函数)
- 5.统计周围雷的个数(CountMines函数)
- 6.mine函数
前言
一、游戏规则介绍
扫雷是一个十分经典的游戏,一张棋盘中有很多个不确定是雷还是安全区域的格子,当点击之后若没有雷则会在该区域显示周围八个格子雷的数目,若有雷则游戏结束。今天我就跟大家分享一下如何用c语言实现初阶版扫雷。
二、基本思路流程介绍
1.创建一个用户交互菜单
2.创建一个Show_Mines棋盘用来埋雷并初始化
3.创建一个Show_Table 棋盘用来和用户交互并初始化
4.玩家选择想要扫描的坐标
5.判定游戏是否结束
6.若没有踩雷则在刚扫描的区域上显示周围八个区域的地雷数目并继续游戏
7.继续扫雷
8.判定游戏是否结束
…
9.若全部扫描完非雷区域则游戏结束
效果展示
三、代码实现
1.用户交互菜单(Menu函数)
Menu(){printf("########################\\n");printf("# 1. Play 0.Exit #\\n");printf("########################\\n");}
2. Game函数
v20000oid Game(){srand((unsigned long)time(NULL)); //生成随机数种子char show_board[ROW][COL];char mines_board[ROW][COL];memset(show_board, WHAT, sizeof(show_board));//生成并且初始化用户显示棋盘memset(mines_board, '0', sizeof(mines_board));//生成并且初始化扫雷棋盘SetMines(mines_board, ROW, COL);//放雷int count = (ROW - 2)*(COL - 2) - NUM; //若扫完这些次 不触雷则胜利while (count){system("cls");ShowBoard(show_board, ROW, COL);printf("请选择你要扫描的区域坐标 ");int x = 0;int y = 0;scanf("%d %d", &x, &y);if (x < 1 || x > ROW-2 || y < 1 || y > COL-2){ //非法性输入判断printf("输入错误!\\n");continue;}if (show_board[x][y] != WHAT){printf("此处已经被扫过了,请从新输出\\n");continue;}if (mines_board[x][y] == '1'){system("cls");ShowBoard(mines_board, ROW, COL);printf("踩雷了!游戏结束!\\n");break;}show_board[x][y] = CountMines(mines_board, x, y);count--;}}
1.memset函数直接定义show_board函数并且初始化二维数组为全WHAT宏定义的*。2.先向用户展示用户展示棋盘,用户输入一个坐标进行非法性判断。3.把用户输入的坐标拿给放置雷的棋盘中,若该区域有雷则游戏结束,反之则继续4.游戏胜利条件为扫描完所有非雷区域
3.放雷函数(SetMines函数)
void SetMines(char board[][COL], int row, int col){ //放雷函数int count = NUM;while (count){int x = rand() % (row - 2) + 1;int y = rand() % (col - 2) + 1;if (board[x][y] == '0'){board[x][y] = '1';count--;}}}
使用随机数种子生成1到 棋盘大小长宽-2的随机数,这些随机数组成的坐标放雷,循环次数就是雷的数目。因为随机数可能生成一样的,所以要进行一次非法性判断,当棋盘这个位置没有雷的情况下才能往里面放雷。
4.扫雷展示面板(ShowBoard函数和ShowLine函数)
void ShowBoard(char board[][COL], int row, int col){//扫雷展示面板printf(" ");for (int i = 1; i <= (col - 2); i++){ //打印表头数字printf("%d ", i);}printf("\\n");ShowLine(col);//显示行线for (int i = 1; i <= (row - 2); i++){printf("%-3d|", i);for (int j = 1; j <= (col - 2); j++){printf(" %c |", board[i][j]);}printf("\\n");ShowLine(col);}}void ShowLine(int col){ //显示横着的虚线,作为行间隔for (int i = 0; i <= (col - 2); i++){printf("----");}printf("\\n");}
5.统计周围雷的个数(CountMines函数)
CountMines(char board[][COL], int x, int y){ //统计周围雷的个数return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + \\board[x][y + 1] + board[x + 1][y + 1] + board[x + 1][y] + \\board[x + 1][y - 1] + board[x][y - 1] - 7 * '0';//本来减八个零,但是整形转字符加一个‘0’}
由于数组中存放的是字符’0’,周围是8个数字,所以-8*'0’才能返回雷数的int值,为了把数字也能打印出来,所以+‘0’,否则打印的是数字作为的ASCLL码的值,最终的结果为-7*‘0’.
6.mine函数
int main(){int quit = 0;int select = 0;while (!quit){Menu();printf("请输入 ");scanf("%d", &select);switch (select){case 1:Game();break;case 0:quit = 1;break;default:printf("输入错误,请重试!\\n");break;}}printf("byebye!\\n");system("pause");return 0;}
四、总代码
#ifndef __Test_H__#define __Test_H__#include<stdio.h>#include<Windows.h>#include <stdlib.h>#include <time.h>#define WHAT '*'#define NUM 20#define COL 10#define ROW 10void Game();#pragma warning(disable:4996)#endif //以上都是头文件int main(){int quit = 0;int select = 0;while (!quit){Menu();printf("请输入 ");scanf("%d", &select);switch (select){case 1:Game();break;case 0:quit = 1;break;default:printf("输入错误,请重试!\\n");break;}}printf("byebye!\\n");system("pause");return 0;}void Game(){srand((unsigned long)time(NULL)); //生成随机数种子char show_board[ROW][COL];char mines_board[ROW][COL];memset(show_board, WHAT, sizeof(show_board));memset(mines_board, '0', sizeof(mines_board));SetMines(mines_board, ROW, COL);int count = (ROW - 2)*(COL - 2) - NUM; //若扫完这些次 不触雷则胜利while (count){system("cls");ShowBoard(show_board, ROW, COL);printf("请选择你要扫描的区域坐标 ");int x = 0;int y = 0;scanf("%d %d", &x, &y);if (x < 1 || x > ROW-2 || y < 1 || y > COL-2){ //非法性输入判断printf("输入错误!\\n");continue;}if (show_board[x][y] != WHAT){printf("此处已经被扫过了,请从新输出\\n");continue;}if (mines_board[x][y] == '1'){system("cls");ShowBoard(mines_board, ROW, COL);printf("踩雷了!游戏结束!\\n");break;}show_board[x][y] = CountMines(mines_board, x, y);count--;}}CountMines(char board[][COL], int x, int y){ //统计周围雷的个数return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + \\board[x][y + 1] + board[x + 1][y + 1] + board[x + 1][y] + \\board[x + 1][y - 1] + board[x][y - 1] - 7 * '0';//本来减八个零,但是整形转字符加一个‘0’}void ShowBoard(char board[][COL], int row, int col){//扫雷展示面板printf(" ");for (int i = 1; i <= (col - 2); i++){printf("%d ", i);}printf("\\n");ShowLine(col);//显示行线for (int i = 1; i <= (row - 2); i++){printf("%-3d|", i);for (int j = 1; j <= (col - 2); j++){printf(" %c |", board[i][j]);}printf("\\n");ShowLine(col);}}oid SetMines(char board[][COL], int row, int col){ //放雷函数int count = NUM;while (count){int x = rand() % (row - 2) + 1;int y = rand() % (col - 2) + 1;if (board[x][y] == '0'){board[x][y] = '1';count--;}}}void ShowLine(int col){for (int i = 0; i <= (col - 2); i++){printf("----");}printf("\\n");}Menu(){ //用户交互函数printf("########################\\n");printf("# 1. Play 0.Exit #\\n");printf("########################\\n");}