一.前言:
扫雷游戏,一款经典的游戏,没玩过的话也可以试着玩一玩,这样对写扫雷游戏这个小游戏的化是会有一个很好的思路的。那么本片博客就来介绍如何实现扫雷游戏的具体步骤。扫雷游戏链接👉 扫雷游戏网页版 - Minesweeper
二.游戏思路与逻辑
1.创建菜单界面函数选择退出游戏或者是进入游戏
2.存放布置好雷的信息以及存放排查出雷的信息
3.进行雷的初始化棋盘
4.再打印出雷的初始化棋盘。注意:一定是要先进行 初始化 然后再 打印棋盘
5.就可以布置雷的信息了
6.输入排查雷的坐标
7.检查出的坐标是不是雷,布置雷存放的是字符(1) 没有放置的是字符(0)注:我们实现扫雷最好要用到模块化编程
模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等!
总的来说就是:当你代码比较多的时候,就可以采用模块化编程来完成这个程序。
三.游戏实现的步骤
1.游戏菜单
void menu()
{printf("*********************\n");printf("****** 1.play *******\n");printf("****** 0.exit *******\n");printf("*********************\n");
}
2.选择是否进行游戏
int main()
{int input = 0;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;
}
3. 实现多行多列扫雷
#define ROW 9
#define COL 9
#define宏定义的功能:
方便程序的修改,不用对整个程序进行修改,只需对宏定义上修改
如下图#define宏定义9*9的行列
4.实现多个雷
#define EASY_COUNT 10
这里表示宏定义10个雷
5.棋盘初始化
打印棋盘,本质上是打印数组的内容。
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set) {int i = 0;int j = 0;for (i = 0;i < rows;i++){for (j = 0;j < cols;j++){board[i][j] = set;}} }
char set 是实参传递到形参的字符。
注:实参数组名 行 可以省略,但是 列 不能进行省略。
6.棋盘打印
打印数组内容,这里数组的内容是字符'0'.
void DisplayBoard(char board[ROWS][COLS], int row, int col) {int i = 0;int j = 0;printf("******* 扫雷 *******\n");for (j = 0;j <= col;j++){printf("%d ", j);}printf("\n");for (i = 1;i <= row;i++){printf("%d ", i);for (j = 1;j <= col;j++){printf("%c ", board[i][j]);}printf("\n");} }
7.布置雷的信息
void SetMine(char mine[ROWS][COLS], int row, int col) {int count = EASY_COUNT;while (count){ int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}} }
这里还用到了一个知识点(随机数)
在实际开发中,我们往往需要一定范围内的随机数,过大或者过小都不符合要求,那么,如何产生一定范围内的随机数呢?我们可以利用取模的方法.
int a = rand() % 10; //产生0~9的随机数,注意10会被整除
如果要规定上下限:
int a = rand() % 51 + 13; //产生13~63的随机数
分析:取模即取余,rand()%51+13 我们可以看成两部分:rand()%51 是产生 0~50 的随机数,后面+13保证 a 最小只能是 13,最大就是 50+13=63使用 <time.h> 头文件中的 time() 函数即可得到当前的时间(精确到秒),就像下面这样:
srand((unsigned)time(NULL));
注意:这个在程序当中是只执行一次即可!
8.玩家输入雷实现步骤
这里的玩家输入坐标,在玩家输入下棋的时候,定义了个静态局部变量,在执行代码的时候。玩游戏的时候会提醒一次, 输入第一个坐标记得空一格!每次进入游戏只有一次,这里主要就是用到了 静态局部变量 就可以保证上一次的值不会被销毁。
检查坐标处是不是雷,布置存放的是字符'1',没有放置雷存放的是字符'0'。
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int win = 0;while (win<row*col-EASY_COUNT){printf("请输入要排查的坐标:>\n");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (mine[x][y] == '1'){printf("很遗憾,你被炸死了\n");DisplayBoard(mine, ROW, COL);break;}else{//如果该坐标不是雷,就要统计这个坐标周围有几个雷int count = GetMineCount(mine,x,y);show[x][y] = count + '0';DisplayBoard(show, ROW, COL);}}else{printf("排查的坐标非法,请重新输入\n"); }}if (win == row * col - EASY_COUNT){printf("恭喜你,排雷成功\n");DisplayBoard(mine, ROW, COL);}
}
9.排查 x ,y 周围有多少
int GetMineCount(char mine[ROWS][COLS],int x,int y )
{return (mine[x-1][y] + mine[x-1][y-1] +mine[x][y -1] +mine[x+1][y-1] +mine[x+1][y] +mine[x+1][y+1] +mine[x][y+1]+mine[x - 1][y + 1] - 8 * '0');}
四.源码
1.test.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void menu()
{printf("*********************\n");printf("****** 1.play *******\n");printf("****** 0.exit *******\n");printf("*********************\n");
}
void game()
{//mine数组是专门存放布置好的雷的信息char mine[ROWS][COLS] = { 0 };//show数组是专门存放布置好的雷的信息char show[ROWS][COLS] = { 0 };//初始化棋盘InitBoard(mine, ROWS, COLS,'0');//'0'InitBoard(show, ROWS, COLS,'*');//'*'//打印棋盘DisplayBoard(show, ROW, COL);//DisplayBoard(mine, ROW, COL);//布置雷SetMine(mine,ROW,COL);//DisplayBoard(show, ROW, COL);//排查雷FineMine(mine,show,ROW,COL);}
int main()
{int input = 0;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;
}
2.game.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
#include<stdio.h>
//初始化棋盘
void InitBoard(char board[ROWS][COLS],int rows,int cols,char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);//排查雷
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
3.game.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)
{int i = 0;int j = 0;for (i = 0;i < rows;i++){for (j = 0;j < cols;j++){board[i][j] = set;}}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i = 0;int j = 0;printf("******* 扫雷 *******\n");for (j = 0;j <= col;j++){printf("%d ", j);}printf("\n");for (i = 1;i <= row;i++){printf("%d ", i);for (j = 1;j <= col;j++){printf("%c ", board[i][j]);}printf("\n");}
}
void SetMine(char mine[ROWS][COLS], int row, int col)
{int count = EASY_COUNT;while (count){ int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}}
}
int GetMineCount(char mine[ROWS][COLS],int x,int y )
{return (mine[x-1][y] + mine[x-1][y-1] +mine[x][y -1] +mine[x+1][y-1] +mine[x+1][y] +mine[x+1][y+1] +mine[x][y+1]+mine[x - 1][y + 1] - 8 * '0');}
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int win = 0;while (win<row*col-EASY_COUNT){printf("请输入要排查的坐标:>\n");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (mine[x][y] == '1'){printf("很遗憾,你被炸死了\n");DisplayBoard(mine, ROW, COL);break;}else{//如果该坐标不是雷,就要统计这个坐标周围有几个雷int count = GetMineCount(mine,x,y);show[x][y] = count + '0';DisplayBoard(show, ROW, COL);}}else{printf("排查的坐标非法,请重新输入\n"); }}if (win == row * col - EASY_COUNT){printf("恭喜你,排雷成功\n");DisplayBoard(mine, ROW, COL);}
}
初学者可以尝试一下,锻炼编程能力,增进对代码的理解,希望可以帮助到大家!