扫雷这个游戏大家都应该玩过,那么扫雷规则我就不细说了,我将会以9*9的扫雷棋盘进行讲解
制作一个扫雷游戏,肯定是比较复杂,所以我们选择多份文件、多个函数进行编写代码
一个,h头文件,两个.c文件
我们先来看看有文件
#pragma once
#include"game.h"
#include<stdio.h>
#define H 9
#define L 9
#define HS H+2
#define LS L+2
void game(char arr2[H][L], int h, int l);
void set_mine(char arr1[HS][LS], int hs, int ls);
#include<stdlib.h>
#include<time.h>
void play(char arr1[HS][LS],char arr2[H][L], int h, int l);
static int GetMineCount(char arr1[HS][LS], int x, int y);
void sign(char arr1[HS][LS], char arr2[H][L], int x, int y,int h,int l);
制作进入游戏界面
这个不难,和上一期猜数字(CSDN)一样就没什么问题了,你也可以有自己的想法,多增加以下观赏性,尽量与扫雷有关就好了
菜单函数
void menu()
{
printf("************************\n");
printf("******* 1. play *******\n");
printf("******* 0. exit *******\n");
printf("************************\n");
}
游戏中的界面
扫雷游戏是一个n*n的平面图,那么我们就可以想到使用二维数组,上一期讲到二维数组的创建
这就是我们的棋盘,字符‘0’就是没有炸弹的坐标,字符‘1’就是我们埋的炸弹
根据规则,当我们选定一个坐标的时候,如果这个坐标没有炸弹,那么将会显示它附近8个坐标的炸弹数量;如果这是炸弹,游戏失败并结束
我们可以想象,如果只设置一个二维数组那就真的太困难了,所以我们设置两个二维数组,可以理解为设置两个棋盘,只要用函数进行传参就能够使参数信息互通啦,一个用来给玩家看的,一个是用来埋炸弹的,不能给玩家看的
用for循环就用'*'可以布置图1
又因为这样看这些坐标不方便,所以我们加一些代码,使它有横坐标和纵坐标,然后合起来,形成一个不需要返回值的函数
玩家界面函数
void game(char arr2[H][L],int h,int l)
{
for (int i = 1; i <= h; i++)
{
for (int n = 1; n <= l; n++)
{
arr2[i][n] = '*';
}
}
for (int i = 0; i <= 9; i++)
{
printf("%d ", i);
}printf("\n");
for (int i = 1; i <= h; i++)
{
printf("%d ", i);
for (int n = 1; n <= l; n++)
{
printf("%c ", arr2[i][n]);
}
printf("\n");
}
}
就成功啦!!
有个问题啊,怎么计算附近8个坐标的炸弹数量,而且有些坐标附近只有三个坐标,为了解决这个问题,我们可以将埋炸弹的棋盘改成11*11的,不就解决了
这样,将最外层的坐标全部改为字符‘0’就可以方便计算了
好,那么棋盘搞定了,接下来埋炸弹,炸弹是要随即放的,我们可以使用rand(),这可以生成0~32767,但是,我们是9*9的棋盘,int ret = rand()%9+1就好了,用ret接受返回值
因为是平面坐标嘛,所以设置两个
int retx = rand()%9+1;
int rety = rand()%9+1;
这样我们就随机生成坐标啦,但是,有个BUG,如果生成了两个一样的坐标那么不就少了炸弹了吗,所以我们要加一个判断语句,再加一个while循环和count来设置10个炸弹,再将坐标传入二维数组就行啦,这是不能给玩家看的棋盘喔
int count = 10;
while (count) {
int ret1 = rand() % 9 + 1;
int ret2 = rand() % 9 + 1;
if (arr1[ret1][ret2] != '1') {
arr1[ret1][ret2] = '1';
count--;
}
}
由于rand()的基准值不会变,所以我们要引用srand()和time函数,在猜数字那一期有讲
srand((unsigned int)time(NULL));
那么埋炸弹就没有问题了
埋雷函数
void set_mine(char arr1[HS][LS], int hs, int ls)
{
for (int i = 0; i < hs; i++)
{
for (int n = 0; n < ls; n++)
{
arr1[i][n] = '0';
}
}
int count = 10;
while (count) {
int ret1 = rand() % 9 + 1;
int ret2 = rand() % 9 + 1;
if (arr1[ret1][ret2] != '1') {
arr1[ret1][ret2] = '1';
count--;
}
}
}
游戏规则(函数实现)
我们先来计算附近的炸弹数量,很简单,直接简单粗暴相加,但是因为是字符相加减得到的是数值,所以要加上字符‘0’才能将得到的值转换为字符,然后再传给二维数组。用函数就可以解决了
计算附近雷的数量
int GetMineCount(char mine[HS][LS], 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 sign(char arr1[HS][LS], char arr2[H][L],int x,int y,int h,int l)
{
re:
printf("是否标记雷,是请按1,否请按0\n");
int s = 0;
scanf("%d", & s);
while (s)
{
printf("请输入标记坐标:");
int x, y;
scanf("%d%d", &x, &y);
if (x > 9 || x < 1 || y > 9 || y < 1)
{
printf("输入有误,请重新输入!\n");
goto re;
}
else
{
system("cls");
for (int i = 0; i <= 9; i++)
{
printf("%d ", i);
}printf("\n");
arr2[x][y] = '!';
for (int i = 1; i <= h; i++)
{
printf("%d ", i);
for (int n = 1; n <= l; n++)
{
printf("%c ", arr2[i][n]);
}
printf("\n");
}
goto re;
}
}
}
1.首先判断所填的坐标是否合法,然后判断是不是炸弹,那么使用判断语句就轻松解决啦
2.接下来就是将选中的坐标转变为附近的炸弹数值
3.如果游戏失败,就要给玩家看看炸弹的分布
4.标记雷坐标
void play(char arr1[HS][LS],char arr2[H][L], int h, int l)
{
int count = H*L - 10;
while (count)
{
count--;
int x = 0, y = 0;
printf("-----------------------\n");
printf("请输入你的排雷坐标:");
scanf("%d%d", &x, &y);
if (x > 9 || x < 1 || y > 9 || y < 1)
{
printf("输入有误,请重新输入!\n");
}
else
{
if (arr1[x][y] != '1')
{
int g = GetMineCount(arr1, x, y);
arr2[x][y] = g + '0';
system("cls");
for (int i = 0; i <= 9; i++)
{
printf("%d ", i);
}printf("\n");
for (int i = 1; i <= h; i++)
{
printf("%d ", i);
for (int n = 1; n <= l; n++)
{
printf("%c ", arr2[i][n]);
}
printf("\n");
}sign(arr1, arr2, x, y,h,l);
}
else
{
printf("BOOM!\nGAME OVER!\n你失败了\n");
for (int i = 0; i <= 9; i++)
{
printf("%d ", i);
}printf("\n");
for (int i = 1; i <= h; i++)
{
printf("%d ", i);
for (int n = 1; n <= l; n++)
{
printf("%c ", arr1[i][n]);
}
printf("\n");
}break;
}
}
}
if (count==0){printf("恭喜你排雷成功!!!\n");
for (int i = 0; i <= 9; i++)
{
printf("%d ", i);
}printf("\n");
for (int i = 1; i <= h; i++)
{
printf("%d ", i);
for (int n = 1; n <= l; n++)
{
printf("%c ", arr1[i][n]);
}
printf("\n");
}
}
}
主函数
我们要让玩家选择是否游戏,所以要用到do while循环,必须先执行一次,看玩家玩不玩
然后再将我们写好的函数带入
int main()
{
int a = 0;
srand((unsigned int)time(NULL));
char arr2[H][L];
char arr1[HS][LS];
do
{
menu();
scanf("%d", &a);
switch (a)
{
case 1:
{
game(arr2, H, L); set_mine(arr1, HS, LS); play(arr1,arr2, H, L);
break;
}
case 0:printf("退出游戏\n"); break;
default:printf("输入错误\n");
}
} while (a);
return 0;
}