ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

(初阶版本)扫雷游戏(C语言)娱乐教程

2021-11-21 23:31:27  阅读:168  来源: 互联网

标签:教程 初阶 show int mine COLS char ROWS C语言


预祝梅西第七座金球!!!!!!你们说会是梅老七吗?

1.游戏分成三部分来写

  1. game.c里面进行实现函数
  2. game.h声明函数头文件宏定义等
  3. test.c写程序的主体部分

2.实现效果展示

3.全部代码

具体讲解请看注释

1.game.h

一》宏定义与头文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//生成随机数的头文件
#include <stdlib.h>
#include <time.h>
//#include<windows.h>
//我们操作的数组是9*9
#define ROW 9
#define COL 9
//但是我们创建的数组是11*11
//因为这样才能符合我自己写的逻辑
//即在一个棋盘即show数组显示旁边8个坐标的雷有多少
//那么我们就需要扫描旁边8个坐标
//但是在棋盘边缘如果是9*9我们没有办法获取不存在的区域的信息
//所以上下左右各多一行变成11*11
#define ROWS ROW+2
#define COLS COL+2

#define EASY_count 10

//#define DIF_count 80

二》函数声明

void InitBoard(char board[ROWS][COLS],int rows,int cols,char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//char mine[ROWS][COLS] = { 0 };//这是我们定义的数组,所以接收的只能是ROWS,COLS
//虽然我实际想验证的只是9*9,但是因为test.c定义数组如上所述

//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);//这里mine还是board是一个意思

//排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

2.test.c

一》//思路:
//两个棋盘存放
//一个棋盘显示排查雷信息,show数组
//即显示扫雷游戏的该落子旁边8个位置有多少雷,用数字显示,其他地方用*掩盖
//一个棋盘存储布置好的雷的信息,mine数组
//即有雷就放个字符1,没雷就是零,最开始全是零,需要你自己去选择几行几列去变0为1

二》main函数

int main()
{
	srand((unsigned int)time(NULL));//随机值生成起点
	//Sleep(100);
	test();
	return 0;
}

三》main函数具体内容

void game()
{
	//创建数组
	char mine[ROWS][COLS] = { 0 };//存储布置好的雷的信息
	char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息
	//初始化mine数组为'0'
	InitBoard(mine,ROWS,COLS,'0');
	//初始化show数组为'*’
	InitBoard(show, ROWS, COLS, '*');

	//打印棋盘,确定棋盘有没有创建正确,可以不确定,单纯为了严谨
	printf("mine>\n");
	DisplayBoard(mine,ROW,COL);
	printf("\n");
	//这下面就不要打印了,因为后面排雷还会显示,重复
	//printf("show雷的信息如下>\n");
	//DisplayBoard(show, ROW, COL);
	//printf("\n");
	//用COL为什么不用COLS,因为我们虽然要11*11但是实际有作用的还是9*9
	//我们验证对不对,只需要9*9能操做就行
	// 如果你想要写成11*11,虽然不会报错但是会打印出奇奇怪怪的东西
	
	//下面是真正的扫雷游戏了
	//布置雷
	SetMine(mine, ROW, COL);//只需要在9*9设计雷在mine中,show是显示雷信息的
	//下面只是测试,要是都告诉你还要你干嘛,相当于作弊器
	//printf("布置雷的情况>\n");
	//DisplayBoard(mine, ROW, COL);//布置好雷后观察观察为了严谨

	//这里开始排雷
	//在mine数组里排雷,显示附近的雷是在show数组,而且存在数组传递
	//即你下棋在mine的几行几列,下棋的地方要显示一个数字,这个数字表示的是你下棋位置周围的情侣
	//周围存在多少雷,存在多少雷显示在show棋盘上
	FindMine(mine,show,ROW,COL);//学会这种创建函数的方式,即翻译我上面的话
}
void menu()
{
	printf("**************\n");
	printf("***1.play*****\n");
	printf("***0.exit*****\n");
	printf("**************\n");
}
void test()
{
	
	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);
}

3.game.c

一》设计棋盘

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++)
		{
			//打出11*11
			board[i][j] = set;//每行每列都是我们设置的符号
		}
	}
}

二》显示棋盘

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	//标出行和列,更好的下棋
	for (i = 0; i <= col; i++)//标出列从0-9因为标出行的时候左边加了一列
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);//直接加在for里面,标出行row,从1-9
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);//打印了一行的字符
		}//后换行
		printf("\n");
	}
}

三》布置雷

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	//位置处有雷就不布置,我设定的是有雷就放个字符1,没雷就是他本来的零
	int count = EASY_count;
	while (count)//非零为真
	{
		int x = (rand() % row) + 1;
		int y = (rand() % col) + 1;//生成1-9的随机数
		if (mine[x][y] == '0')
		{
			//是零不是一,可以布置雷,布置雷变成1
			mine[x][y] = '1';//注意这样只有一次循环,故加while
		}
		count--;//这样就能布置十个雷,当然你可以布置更多的雷
	}
}

四》排雷

//排雷里主体里的函数
static int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
	//这里就体现了在mine中写0和1的好处,但注意这里是字符
	//'1'-'0'=1
	//如果我们用的是*和#这种奇怪的字符,我们就要判断你扫雷位置处周围八个坐标的情况,是雷就加一
	//这样0.1就只要把旁边八个数相加即可,相加是几说明几个雷,送给show显示出来
	//思路如下:

	return  mine[x][y - 1] + mine[x][y + 1] + mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x + 1][y + 1] + mine[x + 1][y] + mine[x + 1][y - 1]-8*'0';


}
//排雷主体
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
//again:
	int x = 0;
	int y = 0;
	int win = 0;
	//while(1)
	while (win<row*col-EASY_count)
	{
		printf("你要排雷的位置: ");
		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
			{
				//计算(x,y)周围有几个雷,并且保存到show棋盘里
				int n = get_mine_count(mine, x, y);
				//show[x][y]我们定义的他是一个字符型数组
				show[x][y] = n + '0';//注意:字符‘0’的ASCII码是48,依次类推,所以2+‘0’=‘2’
				DisplayBoard(show, ROW, COL);
				//这里看上去已经写完实则不然,因为while的缘故,你排完了还要你排雷
				//故改变while的括号内容
				win++;
			}
		}
		else
		{
			printf("无法扫雷,请重新输入坐标:\n");
			//goto again;//不建议用goto
		}
	}
	//if (win == ROW * COL - 80)
	if (win == row * col - EASY_count)
	{
		//这样都满了,排完了
		printf("小伙子,你很有潜力,我觉得你可以去做几个500万的项目!\n");
		DisplayBoard(mine, ROW, COL);
	}//一直说严谨,怎么判断我这个真能排雷成功了,只需要把雷的个数改一改进行,改成80个雷你试试
}

2.实现效果展示

3.全部代码

一》game.c

#define _CRT_SECURE_NO_WARNINGS 1
#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++)
		{
			//打出11*11
			board[i][j] = set;//每行每列都是我们设置的符号
		}
	}
}
//显示棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	//标出行和列,更好的下棋
	for (i = 0; i <= col; i++)//标出列从0-9因为标出行的时候左边加了一列
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);//直接加在for里面,标出行row,从1-9
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);//打印了一行的字符
		}//后换行
		printf("\n");
	}
}
//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col)
{
	//位置处有雷就不布置,我设定的是有雷就放个字符1,没雷就是他本来的零
	int count = EASY_count;
	while (count)//非零为真
	{
		int x = (rand() % row) + 1;
		int y = (rand() % col) + 1;//生成1-9的随机数
		if (mine[x][y] == '0')
		{
			//是零不是一,可以布置雷,布置雷变成1
			mine[x][y] = '1';//注意这样只有一次循环,故加while
		}
		count--;//这样就能布置十个雷,当然你可以布置更多的雷
	}
}
//排雷
//排雷里主体里的函数
static int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
	//这里就体现了在mine中写0和1的好处,但注意这里是字符
	//'1'-'0'=1
	//如果我们用的是*和#这种奇怪的字符,我们就要判断你扫雷位置处周围八个坐标的情况,是雷就加一
	//这样0.1就只要把旁边八个数相加即可,相加是几说明几个雷,送给show显示出来
	//思路如下:

	return  mine[x][y - 1] + mine[x][y + 1] + mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x + 1][y + 1] + mine[x + 1][y] + mine[x + 1][y - 1]-8*'0';


}
//排雷主体
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
//again:
	int x = 0;
	int y = 0;
	int win = 0;
	//while(1)
	while (win<row*col-EASY_count)
	{
		printf("你要排雷的位置: ");
		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
			{
				//计算(x,y)周围有几个雷,并且保存到show棋盘里
				int n = get_mine_count(mine, x, y);
				//show[x][y]我们定义的他是一个字符型数组
				show[x][y] = n + '0';//注意:字符‘0’的ASCII码是48,依次类推,所以2+‘0’=‘2’
				DisplayBoard(show, ROW, COL);
				//这里看上去已经写完实则不然,因为while的缘故,你排完了还要你排雷
				//故改变while的括号内容
				win++;
			}
		}
		else
		{
			printf("无法扫雷,请重新输入坐标:\n");
			//goto again;//不建议用goto
		}
	}
	//if (win == ROW * COL - 80)
	if (win == row * col - EASY_count)
	{
		//这样都满了,排完了
		printf("小伙子,你很有潜力,我觉得你可以去做几个500万的项目!\n");
		DisplayBoard(mine, ROW, COL);
	}//一直说严谨,怎么判断我这个真能排雷成功了,只需要把雷的个数改一改进行,改成80个雷你试试
}

  二》game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//生成随机数的头文件
#include <stdlib.h>
#include <time.h>
//#include<windows.h>
//我们操作的数组是9*9
#define ROW 9
#define COL 9
//但是我们创建的数组是11*11
//因为这样才能符合我自己写的逻辑
//即在一个棋盘即show数组显示旁边8个坐标的雷有多少
//那么我们就需要扫描旁边8个坐标
//但是在棋盘边缘如果是9*9我们没有办法获取不存在的区域的信息
//所以上下左右各多一行变成11*11
#define ROWS ROW+2
#define COLS COL+2

#define EASY_count 10

//#define DIF_count 80
//声明函数,char set 即自己所设计的符号‘0’‘*’,这个函数在game.c里面进行实现
//即test.c确定思路写程序的主体部分,game.h写声明的函数头文件宏定义等
//game.c对于game.h中的函数做具体的解释,即写出这个函数是什么
void InitBoard(char board[ROWS][COLS],int rows,int cols,char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//char mine[ROWS][COLS] = { 0 };//这是我们定义的数组,所以接收的只能是ROWS,COLS
//虽然我实际想验证的只是9*9,但是因为test.c定义数组如上所述

//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);//这里mine还是board是一个意思

//排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

   三》test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
//思路:
//两个棋盘存放
//一个棋盘显示排查雷信息,show数组
//即显示扫雷游戏的该落子旁边8个位置有多少雷,用数字显示,其他地方用*掩盖
//一个棋盘存储布置好的雷的信息,mine数组
//即有雷就放个字符1,没雷就是零,最开始全是零,需要你自己去选择几行几列去变0为1
void game()
{
	//创建数组
	char mine[ROWS][COLS] = { 0 };//存储布置好的雷的信息
	char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息
	//初始化mine数组为'0'
	InitBoard(mine,ROWS,COLS,'0');
	//初始化show数组为'*’
	InitBoard(show, ROWS, COLS, '*');

	//打印棋盘,确定棋盘有没有创建正确,可以不确定,单纯为了严谨
	printf("mine>\n");
	DisplayBoard(mine,ROW,COL);
	printf("\n");
	//这下面就不要打印了,因为后面排雷还会显示,重复
	//printf("show雷的信息如下>\n");
	//DisplayBoard(show, ROW, COL);
	//printf("\n");
	//用COL为什么不用COLS,因为我们虽然要11*11但是实际有作用的还是9*9
	//我们验证对不对,只需要9*9能操做就行
	// 如果你想要写成11*11,虽然不会报错但是会打印出奇奇怪怪的东西
	
	//下面是真正的扫雷游戏了
	//布置雷
	SetMine(mine, ROW, COL);//只需要在9*9设计雷在mine中,show是显示雷信息的
	//下面只是测试,要是都告诉你还要你干嘛,相当于作弊器
	//printf("布置雷的情况>\n");
	//DisplayBoard(mine, ROW, COL);//布置好雷后观察观察为了严谨

	//这里开始排雷
	//在mine数组里排雷,显示附近的雷是在show数组,而且存在数组传递
	//即你下棋在mine的几行几列,下棋的地方要显示一个数字,这个数字表示的是你下棋位置周围的情侣
	//周围存在多少雷,存在多少雷显示在show棋盘上
	FindMine(mine,show,ROW,COL);//学会这种创建函数的方式,即翻译我上面的话
}
void menu()
{
	printf("**************\n");
	printf("***1.play*****\n");
	printf("***0.exit*****\n");
	printf("**************\n");
}
void test()
{
	
	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);
}
int main()
{
	srand((unsigned int)time(NULL));//随机值生成起点
	//Sleep(100);
	test();
	return 0;
}

    玩过扫雷都知道,本游戏只是实现了简单的扫雷游戏真实的扫雷游戏的功能并没有全部实现。该段代码只适用于初学者!

标签:教程,初阶,show,int,mine,COLS,char,ROWS,C语言
来源: https://blog.csdn.net/weixin_57604904/article/details/121462146

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有