项目实战--扫雷C语言版

本节实战旨在激发大家学习兴趣,本节主要使用了数组和函数的知识,要想开发自己的扫雷小游戏,下两节可要好好听哦。

本文需要建立的文件预览。


一、游戏头文件"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';//将棋盘展示值改变
}

四、运行结果


感谢观看。可以看完下两节再回过头看一下哦,你独立思考写出来的程序甚至比我的更优哦,快去尝试吧!!!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值