本节实战旨在激发大家学习兴趣,本节主要使用了数组和函数的知识,要想开发自己的扫雷小游戏,下两节可要好好听哦。
本文需要建立的文件预览。
一、游戏头文件"game.h"
头文件声明了游戏所需要的函数(即执行功能的代码块,但此处不予实现)
int Menus();//声明打印菜单
void Init();//初始化雷
void Print();//打印棋盘
void Refresh(int x,int y);//刷新展示棋盘的指定坐标处周围的雷(o非雷 +是雷)的个数
char Judge(int x,int y);//返回输入后程序对输入结果的处理
bool isWin();//获胜与否的判断
二、主函数逻辑"main.c"
第一行引用创建的游戏头文件,旨在本文件中可以使用游戏功能函数。
第二行引用了系统头文件<Windows.h>,在本文主要使用System();函数,实现清屏操作,使界面更加简洁。
#include "game.h"
#include <Windows.h>
#include <stdio.h>
int main()
{
int x, y;//输入坐标
if (!Menus())exit(1);//打印游戏菜单,选择离开游戏,就进入条件语句,退出程序
else //否则进入else代码段,进行开始游戏
{
Begin:
system("cls");//游戏开始,将游戏菜单清理掉
Init();//初始化本局雷的位置,以及棋盘样式
while (1)
{
Print();//打印棋盘
printf("请输入排雷坐标:");
scanf("%d%d", &x, &y);//输入第几行,第几列
char res = Judge(x, y);
//判断输入坐标处是否是雷(若是,返回‘x’)
//判断输入坐标是否超出棋盘范围(若超,返回‘k’)
Refresh(int x,int y);
//刷新输入坐标周围有几个雷
if (res == 'k')
{
printf("输入错误\n");
}
else if (res == 'x')
{
printf("嘭!雷炸了!游戏失败了,但请不要气馁\n");
break;
}
if (isWin())//判断本局游戏所有非雷坐标是否全部排除
{
printf("哇!恭喜你获胜了,要不要再来一局呢\n");
break;
}
system("cls");//清屏
}
if (Menus()) goto Begin;//选择退出游戏或再来一局
}
return 0;
}
三、游戏的功能"game.c"
1.事先配置
游戏的常量,全局变量
#include <time.h>//方便设置随机数
#include <string.h>
#include <iostream>
using namespace std;
#include "game.h"
#define Rows 9//棋盘行数
#define Cells 9//棋盘列数
#define Numbers 20//所埋雷数
char arrShow[Rows][Cells];//该数组为显示棋盘,即用户看到的棋盘
char arrHide[Rows][Cells];//该数组为隐藏棋盘,非雷处存储‘o’,是雷的地方存储‘x’;根据自己喜好设置
srand((unsigned)time(NULL));//埋下随机数种子,使生成的随机数不是伪随机数
2.功能--打印菜单
int Menus()
{
cout << "--------------------------" << endl;
cout << "0 离开游戏 1 开始游戏" << endl;
cout << "--------------------------" << endl;
cout << "请选择:";
//此处cout<<"";等价于printf("");
//<<endl 即"\n"换行
int choice;
cin >> choice;
//scanf("%d",&choice);
return choice;
}
3.功能--初始棋盘
第一步:将展示的棋盘设置为字符 ‘ * ’ ;内部棋盘全部设置为无雷状态 ‘ o ’;
第二部: 埋雷。随机设置行列坐标,即(r,c),判断时,如果arrHide[r][c]==‘+’,埋雷失败,本次循环次数无效,i--;否则就将雷 ‘+’ 埋进去。我需要埋的雷的数量减一,lv--;
void Init()
{
for (int i = 0; i < Rows * Cells; i++)
{
arrShow[i / Cells][i % Rows] = '*';
}
for (int i = 0; i < Rows * Cells; i++)
{
arrHide[i / Cells][i % Rows] = 'o';
}
int lv = Numbers;
for (int i = 0; i < lv; i++)
{
int c = rand() % Cells;
int r = rand() % Rows;
if (arrHide[r][c] == '+')
{
i--;
}
else
{
arrHide[r][c] = '+';
lv--;
}
}
}
4.功能--打印棋盘
棋盘包括
(1)本局游戏雷的数目
(2)列坐标
(3)行坐标,加上本行面板展示
void Print()
{
cout << "本局共有雷:" << Numbers << endl;
cout << "0 ";
for (int i = 0; i < Cells; i++) cout << i+1 << " ";
cout << endl;
for (int i = 0; i < Rows; i++)
{
cout << i+1 << " ";
for (int j = 0; j < Cells; j++)
{
printf("%c ", arrShow[i][j]);
}
cout << endl;
}
}
5.功能--获胜判断
对所有地雷数组遍历,判断每一个非雷位置在展示数组位置对应是不是 ‘ * ’;是的话,就说明排雷尚未结束,需要继续游戏,函数非正常中断,返回false;如果遍历结束未中断,说明排雷结束,游戏胜利。
bool isWin()
{
for (int i = 0; i < Rows; i++)
{
for (int j = 0; j < Cells; j++)
{
if (arrHide[i][j] == 'o' && arrShow[i][j] == '*')
{
return false;
}
}
}
return true;
}
6.功能--输入判断
输入坐标后,判断坐标是否处于棋盘范围内,否则数组将越界,程序崩溃。
char Judge(int x, int y)
{
if (x<1 || x>Rows || y<1 || y>Rows)
{
return 'k';//设置k为输入错误标志
}
if (arrHide[x - 1][y - 1] == '+')
{
//如果该坐标对应是雷,结束
return 'x';//设置x为排雷失败结束标志
}
return '\0';
}
7.功能--附近的雷
下面就是判断所处坐标周围的雷的个数。在这里,有几个点:第一、逻辑坐标与物理坐标的转换(物理坐标即计算机硬件决定的相对位置,索引从0开始;逻辑坐标即从1开始的数学坐标)。第二、棋盘元素的分类(上图:)
void Refresh(int x, int y)
{
//Cells:列坐标--y
//Rows :行坐标--x
int cell = y;
int row = x;
x--, y--;//逻辑坐标转物理坐标
int count = 0;
if ((cell > 1 && cell < Cells) && (row > 1 && row < Rows))
{
if (arrHide[x - 1][ y ] == '+')count++;//正上↑
if (arrHide[x - 1][y - 1] == '+')count++;//左上↖
if (arrHide[x - 1][y + 1] == '+')count++;//右上↗
if (arrHide[ x ][y - 1] == '+')count++;//正左←
if (arrHide[ x ][y + 1] == '+')count++;//正右→
if (arrHide[x + 1][ y ] == '+')count++;//正下↓
if (arrHide[x + 1][y - 1] == '+')count++;//左下↙
if (arrHide[x + 1][y + 1] == '+')count++;//右下↘
}
else if (cell == 1 && (row > 1 && row < Rows))
{
if (arrHide[x - 1][y] == '+')count++;//正上↑
if (arrHide[x + 1][y] == '+')count++;//正下↓
if (arrHide[x - 1][y + 1] == '+')count++;//右上↗
if (arrHide[x][y + 1] == '+')count++;//正右→
if (arrHide[x + 1][y + 1] == '+')count++;//右下↘
}
else if (cell == Cells && (row > 1 && row < Rows))
{
if (arrHide[x - 1][y] == '+')count++;//正上↑
if (arrHide[x + 1][y] == '+')count++;//正下↓
if (arrHide[x - 1][y - 1] == '+')count++;//左上↖
if (arrHide[x][y - 1] == '+')count++;//正左←
if (arrHide[x + 1][y - 1] == '+')count++;//左下↙
}
else if ((cell > 1 && cell < Cells) && row == 1)
{
if (arrHide[x][y - 1] == '+')count++;//正左←
if (arrHide[x][y + 1] == '+')count++;//正右→
if (arrHide[x + 1][y] == '+')count++;//正下↓
if (arrHide[x + 1][y - 1] == '+')count++;//左下↙
if (arrHide[x + 1][y + 1] == '+')count++;//右下↘
}
else if ((cell > 1 && cell < Cells) && row == Rows)
{
if (arrHide[x][y - 1] == '+')count++;//正左←
if (arrHide[x][y + 1] == '+')count++;//正右→
if (arrHide[x - 1][y] == '+')count++;//正上↑
if (arrHide[x - 1][y - 1] == '+')count++;//左上↖
if (arrHide[x - 1][y + 1] == '+')count++;//右上↗
}
else if (cell == 1 && row == 1)
{
if (arrHide[x][y + 1] == '+')count++;//正右→
if (arrHide[x + 1][y] == '+')count++;//正下↓
if (arrHide[x + 1][y + 1] == '+')count++;//右下↘
}
else if (cell == 1 && row == Rows)
{
if (arrHide[x][y + 1] == '+')count++;//正右→
if (arrHide[x - 1][y] == '+')count++;//正上↑
if (arrHide[x - 1][y + 1] == '+')count++;//右上↗
}
else if (cell == Cells && row == 1)
{
if (arrHide[x][y - 1] == '+')count++;//正左←
if (arrHide[x + 1][y] == '+')count++;//正下↓
if (arrHide[x + 1][y - 1] == '+')count++;//左下↙
}
else if (cell == Cells && row == Rows)
{
if (arrHide[x][y - 1] == '+')count++;//正左←
if (arrHide[x - 1][y] == '+')count++;//正上↑
if (arrHide[x - 1][y - 1] == '+')count++;//左上↖
}
arrShow[x][y] = count + '0';//将棋盘展示值改变
}
四、运行结果
感谢观看。可以看完下两节再回过头看一下哦,你独立思考写出来的程序甚至比我的更优哦,快去尝试吧!!!