游戏介绍
扫雷,顾名思义,就是排除所有的雷,游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。
基本流程
1.创建用户交互菜单;
2.创建地图并初始化;
3.打印地图;
4.程序读取玩家要翻的坐标并校验;
5.判断该位置的坐标是否有地雷,如果有地雷,则游戏结束;
6.如果不是地雷, 统计当前位置周围雷的个数, 并显示到地图上;
7.判定游戏是否胜利。
代码实现
创建用户交互菜单
int menu(){
//用户交互菜单
printf("======================\n");
printf("1.开始游戏\n");
printf("0.结束游戏\n");
printf("======================\n");
printf("请输入您的选择:");
int choice = 0;
scanf("%d", &choice);
return choice;
}
这里我们最开始创建一个用户菜单供用户选择游戏的开始和结束。(这里小小的吐槽一下,每次我敲完代码,都会出现错误,而且大多数情况下都是scanf没有&,所以大家也要注意啦)
创建地图并初始化
void init(char ShowMap[MAX_ROW][MAX_COL], char MineMap[MAX_ROW][MAX_COL]){
//初始化地图
//先初始化showmap
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
ShowMap[row][col] = '*';//ShowMap的初始化我们用‘*’表示
}
}
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
MineMap[row][col] = '0';//MineMap的初始化我们用‘ ’表示
}
}
int n = DEFAULT_MINE_COUNT;
while (n > 0) {
// 生成雷的随机位置.
int row = rand() % MAX_ROW;
int col = rand() % MAX_COL;
if (MineMap[row][col] == '1') {
// 如果当前位置已经有雷了, 就直接进入下次循环, 重新
// 产生随机位置.
continue;
}
MineMap[row][col] = '1';
n--;
}
}
这里要注意的是我们打印地图的时候要打印两个地图,一个是供用户选择坐标翻的地图,另外一个是我们地雷随机出现的地图,在MineMap中,我们地雷随机出现采用srand随机数,同时定义宏地雷的总数。
我们初始化ShowMap一开始所有格子为’*’,MineMap一开始所有格子为‘0’,地雷我们用’1’来表示。
地图打印
void printMap(char theMap[MAX_ROW][MAX_COL]){
//打印地图
printf(" |");
for (int col = 0; col < MAX_COL; col++) {
printf("%d ", col);
}
printf("\n");
printf("--+------------------\n");
for (int row = 0; row < MAX_ROW; row++) {
printf(" %d|", row);
for (int col = 0; col < MAX_COL; col++) {
printf("%c ", theMap[row][col]);
}
printf("\n");
}
}
这里我们是打印一个地图的边框和每个格子的分隔线,数组是用%c来表示的。
地图更新
void updateShowMap(char showMap[MAX_ROW][MAX_COL],//地图更新
char mineMap[MAX_ROW][MAX_COL], int row, int col) {
int count = 0;
for (int r = row - 1; r <= row + 1; r++) {
for (int c = col - 1; c <= col + 1; c++) {
if (r < 0 || r >= MAX_ROW
|| c < 0 || c >= MAX_COL) {
continue;
}
if (mineMap[r][c] == '1') {
count++;
}
}
}
showMap[row][col] = count + '0';
}
这里我们写的是当用户每翻一个坐标的时候,这个坐标就要显示出以这个坐标为中心,与它相邻的坐标内,一共有多少个雷。
game()函数
void game() {
//1.创建地图并初始化;
//2.打印地图;
//3.程序读取玩家要翻的坐标并校验
//4.判断该位置的坐标是否有地雷,如果有地雷,则游戏结束
//5.如果不是地雷, 统计当前位置周围雷的个数, 并显示到地图上.
//6.判定游戏是否胜利
char ShowMap[MAX_ROW][MAX_COL] = {
0 };
char MineMap[MAX_ROW][MAX_COL] = {
0 };
init(ShowMap, MineMap);
int openedBlockCount = 0;
while (1){
printMap(MineMap);//测试
printf("===================\n");
printMap(ShowMap);
int row = 0;
int col = 0;
printf("请输入要翻开的坐标(row,col):");
scanf("%d %d", &row, &col);
if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL){
printf("您输入的坐标有误!\n");
continue;
}
if (ShowMap[row][col] != '*'){
printf("当前位置已经翻开!\n");
continue;
}
if (MineMap[row][col] == '1'){
printf("您踩到雷了,游戏结束!\n");
printMap(MineMap);
break;
}
updateShowMap(ShowMap, MineMap, row, col);
openedBlockCount++;
if (openedBlockCount == MAX_ROW * MAX_COL - DEFAULT_MINE_COUNT) {
printf("游戏胜利!\n");
printMap(MineMap);
break;
}
}
}
在game()函数中,我们在whlie循环中的第一个编写的就是雷的分布的printMap(MineMap),这个是为了方便我们测试我们所写的程序会不会出现问题。
总代码
#include<stdio.h>
#include<windows.h>
#include<time.h>
#pragma warning(disable:4996)
#define MAX_ROW 9
#define MAX_COL 9
#define DEFAULT_MINE_COUNT 10
int menu(){
//用户交互菜单
printf("======================\n");
printf("1.开始游戏\n");
printf("0.结束游戏\n");
printf("======================\n");
printf("请输入您的选择:");
int choice = 0;
scanf("%d", &choice);
return choice;
}
void printMap(char theMap[MAX_ROW][MAX_COL]){
//打印地图
printf(" |");
for (int col = 0; col < MAX_COL; col++) {
printf("%d ", col);
}
printf("\n");
printf("--+------------------\n");
for (int row = 0; row < MAX_ROW; row++) {
printf(" %d|", row);
for (int col = 0; col < MAX_COL; col++) {
printf("%c ", theMap[row][col]);
}
printf("\n");
}
}
void init(char ShowMap[MAX_ROW][MAX_COL], char MineMap[MAX_ROW][MAX_COL]){
//初始化地图
//先初始化showmap
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
ShowMap[row][col] = '*';//ShowMap的初始化我们用‘*’表示
}
}
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
MineMap[row][col] = '0';//MineMap的初始化我们用‘ ’表示
}
}
int n = DEFAULT_MINE_COUNT;
while (n > 0) {
// 生成雷的随机位置.
int row = rand() % MAX_ROW;
int col = rand() % MAX_COL;
if (MineMap[row][col] == '1') {
// 如果当前位置已经有雷了, 就直接进入下次循环, 重新
// 产生随机位置.
continue;
}
MineMap[row][col] = '1';
n--;
}
}
void updateShowMap(char showMap[MAX_ROW][MAX_COL],//地图更新
char mineMap[MAX_ROW][MAX_COL], int row, int col) {
int count = 0;
for (int r = row - 1; r <= row + 1; r++) {
for (int c = col - 1; c <= col + 1; c++) {
if (r < 0 || r >= MAX_ROW
|| c < 0 || c >= MAX_COL) {
continue;
}
if (mineMap[r][c] == '1') {
count++;
}
}
}
showMap[row][col] = count + '0';
}
void game() {
//1.创建地图并初始化;
//2.打印地图;
//3.程序读取玩家要翻的坐标并校验
//4.判断该位置的坐标是否有地雷,如果有地雷,则游戏结束
//5.如果不是地雷, 统计当前位置周围雷的个数, 并显示到地图上.
//6.判定游戏是否胜利
char ShowMap[MAX_ROW][MAX_COL] = {
0 };
char MineMap[MAX_ROW][MAX_COL] = {
0 };
init(ShowMap, MineMap);
int openedBlockCount = 0;
while (1){
printMap(MineMap);
printf("===================\n");
printMap(ShowMap);
int row = 0;
int col = 0;
printf("请输入要翻开的坐标(row,col):");
scanf("%d %d", &row, &col);
if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL){
printf("您输入的坐标有误!\n");
continue;
}
if (ShowMap[row][col] != '*'){
printf("当前位置已经翻开!\n");
continue;
}
if (MineMap[row][col] == '1'){
printf("您踩到雷了,游戏结束!\n");
printMap(MineMap);
break;
}
updateShowMap(ShowMap, MineMap, row, col);
openedBlockCount++;
if (openedBlockCount == MAX_ROW * MAX_COL - DEFAULT_MINE_COUNT) {
printf("游戏胜利!\n");
printMap(MineMap);
break;
}
}
}
int main(){
srand((unsigned int)time(0));
while (1){
int choice = menu();
if (choice == 1){
game();
}
else if (choice == 0){
printf("GoodBye!\n");
}
else{
printf("您的输入有误,请重新输入!\n");
}
}
system("pause");
return 0;
}
ok ,文章就先到这里了,希望这篇文章能够帮助到你对指针的认识,若有不足或者不正之处,希望谅解并欢迎批评指正!
如果本文章对你有帮助,哪怕一点点,那就请点一个赞呗,谢谢~~
转载:https://blog.csdn.net/qq_46877337/article/details/109500722