C语言入门游戏---扫雷

游戏程序的整体布局

1,test.c---游戏运行的主体

2,game.c---游戏函数实现的主体

3,game.h---游戏函数即一些头文件的声明

#include"game.h"
int main()
{
	int put = 0; 

	do
	{
		menu();
		printf("请输入对应功能的数字:");
		scanf("%d", &put);
		switch (put)
		{
		case 1:
			game();
			break;
		case 0:
			printf("已退出游戏");
			break;
		default:
			printf("非法输入,请重新输入");
		}
	} while (put);
	return 0;
}

这里没有引用<stdio.h>的头文件,该文件被封装到了game.h的文件中,其中的menu()菜单函数与游戏函数game()被封装到game.c文件中

游戏主体的实现

要想做出扫雷,首先要有游戏菜单,棋盘,布雷,及玩家排查的逻辑,和判断输赢的逻辑,其次要了解本质的实现原理,首先要有一个显示给玩家的棋盘(不显示雷),其次创建另一个棋盘不给玩家看(布置雷),在玩家游玩的过程实际是在内置的棋盘中进行排查,而在另一个棋盘显示。

​
void game()
{
	srand((unsigned)time(NULL));
	//创建棋子数组
	char showboard[SROW][SCOL];
	char setboard[SROW][SCOL];
	//创建棋盘
	init_sboard(showboard,SROW,SCOL);
	init_board(setboard, SROW, SCOL);
	//布置雷
	init_leiboard(setboard, ROW, COL);
	//排查与输赢的判断

}

​

游戏菜单

//菜单
void menu()
{
	printf("-------------- 扫雷 -----------\n");
	printf("---------- 1.开始游戏 ---------\n");
	printf("---------- 0.退出游戏 ---------\n");
	printf("-------------------------------\n");
	printf("游戏规则:在9*9的棋盘内布置10个雷,雷用数字1表示。\n");
	printf("踩到雷游戏结束,没踩到雷则计算出该位置周围8个位置中雷的个数\n");
	printf("-------------------------------\n");
}

初始化棋盘

 tips:为了提高代码的健壮性,我们使用了全局变量 ROW 和 COL ,SROW,SCOL来进行操作,通过改变这两个全局变量的值就可以操作棋盘的格局,方便了日后的进一步优化改进,提高游戏可操作性。在game.h文件中使用

#define ROW 9
#define COL 9
#define SROW ROW+2
#define SCOL COL+2

在显示的棋盘中我们只显示9*9的棋盘大小,而在内置的棋盘中为了方便排查边角处的雷所以要多加两行两列

初始化显示棋盘

//显示棋盘
void init_sboard(char showboard[SROW][SCOL], int srow, int scol);

 在此创建一个showboard二维数组,用‘*’来初始化。

//初始化显示棋盘
void init_sboard(char showboard[SROW][SCOL], int srow, int scol)
{
	for (int i = 0; i < srow; i++)
	{
		for (int j = 0; j < scol; j++)
		{
			showboard[i][j] = '*';
		}
	}
	
}

初始化内置棋盘

//内置棋盘
void init_board(char setboard[SROW][SCOL], int srow, int scol);

 在此创建一个setboard二维数组,用‘0’来初始化,之后用字符1来布置雷。

//初始化内置棋盘
void init_board(char setboard[SROW][SCOL], int srow, int scol)
{
	for (int i = 0; i < srow; i++)
	{
		for (int j = 0; j < scol; j++)
		{
			setboard[i][j] = '0';
		}
	}
}

布置雷

//布置雷
void init_leiboard(char setboard[SROW][SCOL], int row, int col);

 在这里宏定义雷的个数为10

#define LEI 10

通过库函数随机布置雷的位置 

//布置雷
void init_leiboard(char setboard[SROW][SCOL], int row, int col)
{
	int lei = LEI;
	int i, j;
	while (lei)
	{
		i = rand() % row + 1;
		j = rand() % col + 1;
		if (setboard[i][j] == '0')
		{
			setboard[i][j] = '1';
			lei--;
		}
	}
}

循环排查直到排查完或踩到雷

void game()
{
	srand((unsigned)time(NULL));
	//创建棋子数组
	char showboard[SROW][SCOL];
	char setboard[SROW][SCOL];
	//创建棋盘
	init_sboard(showboard,SROW,SCOL);
	init_board(setboard, SROW, SCOL);
	//布置雷
	init_leiboard(setboard, ROW, COL);
	//排查与输赢的判断
	while (1)
	{
		//打印棋盘
		print_sboard(showboard, ROW, COL);
		//排查与判断输赢
		find_lei(showboard,setboard,ROW,COL);
		//打印最终结果
		printf("以下是全部雷区\n");
		print_board(setboard, ROW, COL);
		break;
	}
}

​

打印棋盘

//打印棋盘
void print_sboard(char showboard[SROW][SCOL], int row, int col);
//打印棋盘
void print_sboard(char showboard[SROW][SCOL], int row, int col)
{
	for (int i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 0; i <= col; i++)
	{
		printf("--");
	}
	printf("\n");
	for (int i = 1; i <= row; i++)
	{
		printf("%d|", i);
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", showboard[i][j]);
		}
		printf("|\n");
	}
}

在此为了方便玩家排雷,将数组的下角标与真实行列坐标对应,以下是演示图

 排查与判断输赢
 

//排查与判断输赢
void find_lei(char showboard[SROW][SCOL], char setboard[SROW][SCOL], int row, int col);

 在此我们宏定义排查次数WIN

#define WIN ((ROW*COL)-LEI)
​
//排查与判断输赢
void find_lei(char showboard[SROW][SCOL], char setboard[SROW][SCOL], int row, int col)
{
	int i, j;
	int win = WIN;
	while (win)
	{
		printf("请输入想要排查的行:");
		scanf("%d", &i);
		printf("请输入想要排查的列:");
		scanf("%d", &j);
		if (i >= 1 && i <= row && j >= 1 && j <= col)
		{
			if (showboard[i][j] == '*')
			{
				if (setboard[i][j] == '1')
				{
					printf("恭喜你踩到雷了小笨蛋!\n");
					return ;
				}
				else
				{
					showboard[i][j] = countlei(setboard, i, j);
					system("cls");
					print_sboard(showboard, ROW, COL);
					win--;
				}
			}
			else
				printf("该位置已经排查过了,请重新输入\n");
		}
		else
			printf("非法输入,请重新输入\n");
	}
	if (win == 0)
	{
		printf("真可惜你排查完所有的雷,没炸到你!\n");
		return ;
	}
}

​

这里如果没有踩到雷则在该位置计算出周围8个方位雷的个数

计算雷个数

//计算雷的个数
char countlei(char setboard[SROW][SCOL], int i, int j);
//计算雷的个数
char countlei(char setboard[SROW][SCOL], int i, int j)
{
	return  (setboard[i - 1][j - 1] + setboard[i - 1][j]  // 将布置雷棋盘该位置周围八个对应的字符相加减去 7*‘0’ 得到的是周围雷的个数 赋给排查雷的棋盘
		+ setboard[i - 1][j + 1] + setboard[i][j - 1]
		+ setboard[i][j + 1] + setboard[i + 1][j - 1]
		+ setboard[i + 1][j] + setboard[i + 1][j + 1])-(7*'0');
}

字符储存的是ascll,字符‘0’对应的ascll是48,因为在内置棋盘中只有字符‘0’和字符‘1’,将周围的8个字符相加后减去7个字符‘0’的大小,如果有一个雷则返回字符‘1’的ascll码值49,如果有两个则返回49+1即字符‘2’的ascll值,以此来计算并显示雷的多少。

打印最终的结果
 

//打印最终的结果
void print_board(char setboard[SROW][SCOL], int row, int col);

在排查完或踩到雷后显示出所有雷的位置

//打印最终结果
void print_board(char setboard[SROW][SCOL], int row, int col)
{
	for (int i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 0; i <= col; i++)
	{
		printf("--");
	}
	printf("\n");
	for (int i = 1; i <= row; i++)
	{
		printf("%d|", i);
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", setboard[i][j]);
		}
		printf("|\n");
	}
}

test.c

#include"game.h"
int main()
{
	int put = 0; 

	do
	{
		menu();
		printf("请输入对应功能的数字:");
		scanf("%d", &put);
		switch (put)
		{
		case 1:
			game();
			break;
		case 0:
			printf("已退出游戏");
			break;
		default:
			printf("非法输入,请重新输入");
		}
	} while (put);
	return 0;
}

game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#define ROW 9
#define COL 9
#define SROW ROW+2
#define SCOL COL+2
#define LEI 10
#define WIN ((ROW*COL)-LEI) 
//菜单
void menu();
//游戏主函数
void game();
//显示棋盘
void init_sboard(char showboard[SROW][SCOL], int srow, int scol);
//内置棋盘
void init_board(char setboard[SROW][SCOL], int srow, int scol);
//布置雷
void init_leiboard(char setboard[SROW][SCOL], int row, int col);
//打印棋盘
void print_sboard(char showboard[SROW][SCOL], int row, int col);
//排查与判断输赢
void find_lei(char showboard[SROW][SCOL], char setboard[SROW][SCOL], int row, int col);
//计算雷的个数
char countlei(char setboard[SROW][SCOL], int i, int j);
//打印最终的结果
void print_board(char setboard[SROW][SCOL], int row, int col);

game.c

#include"game.h"
//菜单
void menu()
{
	printf("-------------- 扫雷 -----------\n");
	printf("---------- 1.开始游戏 ---------\n");
	printf("---------- 0.退出游戏 ---------\n");
	printf("-------------------------------\n");
	printf("游戏规则:在9*9的棋盘内布置10个雷,雷用数字1表示。\n");
	printf("踩到雷游戏结束,没踩到雷则计算出该位置周围8个位置中雷的个数\n");
	printf("-------------------------------\n");
}
//初始化显示棋盘
void init_sboard(char showboard[SROW][SCOL], int srow, int scol)
{
	for (int i = 0; i < srow; i++)
	{
		for (int j = 0; j < scol; j++)
		{
			showboard[i][j] = '*';
		}
	}
	
}
//初始化内置棋盘
void init_board(char setboard[SROW][SCOL], int srow, int scol)
{
	for (int i = 0; i < srow; i++)
	{
		for (int j = 0; j < scol; j++)
		{
			setboard[i][j] = '0';
		}
	}
}
//布置雷
void init_leiboard(char setboard[SROW][SCOL], int row, int col)
{
	int lei = LEI;
	int i, j;
	while (lei)
	{
		i = rand() % row + 1;
		j = rand() % col + 1;
		if (setboard[i][j] == '0')
		{
			setboard[i][j] = '1';
			lei--;
		}
	}
}
//打印棋盘
void print_sboard(char showboard[SROW][SCOL], int row, int col)
{
	for (int i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 0; i <= col; i++)
	{
		printf("--");
	}
	printf("\n");
	for (int i = 1; i <= row; i++)
	{
		printf("%d|", i);
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", showboard[i][j]);
		}
		printf("|\n");
	}
}
//排查与判断输赢
void find_lei(char showboard[SROW][SCOL], char setboard[SROW][SCOL], int row, int col)
{
	int i, j;
	int win = WIN;
	while (win)
	{
		printf("请输入想要排查的行:");
		scanf("%d", &i);
		printf("请输入想要排查的列:");
		scanf("%d", &j);
		if (i >= 1 && i <= row && j >= 1 && j <= col)
		{
			if (showboard[i][j] == '*')
			{
				if (setboard[i][j] == '1')
				{
					printf("恭喜你踩到雷了小笨蛋!\n");
					return ;
				}
				else
				{
					showboard[i][j] = countlei(setboard, i, j);
					system("cls");
					print_sboard(showboard, ROW, COL);
					win--;
				}
			}
			else
				printf("该位置已经排查过了,请重新输入\n");
		}
		else
			printf("非法输入,请重新输入\n");
	}
	if (win == 0)
	{
		printf("真可惜你排查完所有的雷,没炸死你狗日的!\n");
		return ;
	}
}
//计算雷的个数
char countlei(char setboard[SROW][SCOL], int i, int j)
{
	return  (setboard[i - 1][j - 1] + setboard[i - 1][j]  // 将布置雷棋盘该位置周围八个对应的字符相加减去 7*‘0’ 得到的是周围雷的个数 赋给排查雷的棋盘
		+ setboard[i - 1][j + 1] + setboard[i][j - 1]
		+ setboard[i][j + 1] + setboard[i + 1][j - 1]
		+ setboard[i + 1][j] + setboard[i + 1][j + 1])-(7*'0');
}
//打印最终结果
void print_board(char setboard[SROW][SCOL], int row, int col)
{
	for (int i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 0; i <= col; i++)
	{
		printf("--");
	}
	printf("\n");
	for (int i = 1; i <= row; i++)
	{
		printf("%d|", i);
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", setboard[i][j]);
		}
		printf("|\n");
	}
}
void game()
{
	srand((unsigned)time(NULL));
	//创建棋子数组
	char showboard[SROW][SCOL];
	char setboard[SROW][SCOL];
	//创建棋盘
	init_sboard(showboard,SROW,SCOL);
	init_board(setboard, SROW, SCOL);
	//布置雷
	init_leiboard(setboard, ROW, COL);
	//排查与输赢的判断
	while (1)
	{
		//打印棋盘
		print_sboard(showboard, ROW, COL);
		//排查与判断输赢
		find_lei(showboard,setboard,ROW,COL);
		//打印最终结果
		printf("以下是全部雷区\n");
		print_board(setboard, ROW, COL);
		break;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

9527#

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值