C语言实现 扫雷游戏 | 简单项目

Posted juice 999

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言实现 扫雷游戏 | 简单项目相关的知识,希望对你有一定的参考价值。

目录

文件组成

test.c 游戏主题框架         

infor.h 信息模块函数的声明

 infor.c 信息模块的函数定义与功能实现

game.h 游戏模块函数的声明

game.c 游戏模块的函数定义与功能实现

结尾 源码


文件组成

要写一个扫雷游戏,由于体量较大,我们打算分三个.c 文件(源文件) 来定义函数,实现代码,两个 .h 文件(头文件) 来实现我们.c文件中函数的声明和库函数头文件的引用。

三个 源文件 : test.c , game.c , print.c

两个头文件:game.h , print.h

文件的源码 我会放在结尾以供大家学习

test.c 游戏主题框架         

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"  /这里引上我们编写好的头文件
#include "infor.h"/里面有我们所有自定函数的声明和库函数头文件的引用

void menu() /游戏主界面的菜单
	printf("***************************\\n");
	printf("*******   1. PLAY   *******\\n");
	printf("*******   0. EXIT   *******\\n");
	printf("*******   2. INFOR  *******\\n");
	printf("***************************\\n");



int main() 
	srand((unsigned int)time(NULL));/由于游戏中布置雷需要随机数,我们在这里就将它初始化
	int input;/用来接收玩家输入
	do /主题采用循环结构 当玩家结束游戏后可以进行选择进入或者退出
		menu();/打印菜单
		printf("请选择序号:>");/提示玩家选择
		scanf("%d", &input);
		switch (input) 
		case 1:
			game();/进入游戏模块
			break;
		case 0:
			printf("退出游戏\\n");/退出游戏
			break;
		case 2:
			INFOR();/进入信息菜单 查看规则以及其他信息
			break;
		default:
			printf("输入错误 重新输入\\n");/输入错入提示
		

	 while (input);/当玩家输入0 退出程序

	return 0;

此时我们程序运行起来 就会是这个样子

 

infor.h 信息模块函数的声明

#pragma once

void INFOR();/信息模块入口
void menu_in();/信息模块的菜单
void game_rules();/游戏规则说明
void infor();/补充信息

 infor.c 信息模块的函数定义与功能实现

#include<stdio.h>/引上库函数的头文件


void menu_in() /只是当玩家选择 1 后显示的菜单
	printf("1.游戏规则\\n");
	printf("2.制作信息\\n");
	printf("3.奖励\\n");
	printf("0.返回\\n");


void game_rules() /游戏规则
	printf("\\n踩点和标记需输入对应 行和列如 第一行第一列 应该输入 \\"1 1\\"\\n猜到雷会被炸死,恐怖至极,骨灰都找不到!!!\\n踩到非雷会显示以它中心3X3矩形范围内雷的个数.\\n如果显示0会自动帮你展开\\n正确标记出所有雷,或者踩完所有非雷点即可获胜.\\nthats it...\\n\\n");

void infor() /其他信息这里可以看自己喜好添加
	printf(".一步一步按提示来 不然要炸\\n\\n");

void reward() /奖励
	printf("完成1级难度即可获得:> ");
	printf("游戏作者的大拇指!!!\\n");



以上是这一模块函数的定义
——————————————————————————————————————————————————————
以下是则以模块的的框架
跟主界面类似 用到循环体 以实现重复选择

void INFOR() /这一模块的框架
	menu_in();/菜单
	int input;
	do 
		printf("请选择序号:>");
		scanf("%d", &input);
		switch (input) 
		case 1:
			game_rules();/规则
			break;
		case 2:
			infor();/信息
			break;
		case 3:
			reward();/奖励
			break;
		case 0:
			break;/退出循环,回到主界面
        default:
			printf("输入错误 重新输入\\n");/输入错入提示
		
	 while (input);/可以重复选择

结束后回到主界面

这时 如果你运行程序 并在主界面输入 2 并按下回车

将会是这样

如继续输入 0 就回到主界面  

至此 扫雷游戏除了游戏 就都编写完成了(狗头)

game.h 游戏模块函数的声明

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>
#include<string.h>

/定义 棋盘行列的全局变量
为了方便 我们定义11X11的棋盘 但只使用 其中9X9的空间
#define ROW 9 
#define COL 9 
#define ROWS 11
#define COLS 11

/扫雷游戏主体
void game();
/初始化棋盘的函数
void InitBoard(char Board[ROWS][COLS], int rows, int cols, char set);
/打印棋盘的函数
void DisplayBoard(char Board[ROWS][COLS], int row, int col);
/设置雷的函数
void SetMine(char Board[ROWS][COLS],int row,int col,int nub);
/玩家排雷(一直玩到结束,返回值为输赢结果)
char FindMine(char Board[ROWS][COLS], char show[ROWS][COLS], int row, int col,int nub);
/返回点周围雷的个数
char CountMine(char Board[ROWS][COLS],char[ROWS][COLS] ,int row, int col);
/将点展开
void Extend(char Board[ROWS][COLS], char show[ROWS][COLS], int row, int col);
/判断赢没赢(赢返回 1 ,没赢返回 0 )
int Is_win(char Board[ROWS][COLS],char show[ROWS][COLS], int row, int col,int nub);
/游戏胜利 或 失败后延时打印结果
void SleepPrint(char* p);

game.c 游戏模块的函数定义与功能实现

为了方便 我们定义两个二维数组 来分别代表 用户看到的棋盘数字 ,标记 (排查雷的信息)的棋盘 和 存放雷的棋盘 里面 只有 雷。

用户棋盘show board:

 

存雷棋盘:

 

玩家可以选择是要踩 还是 要 标记,把所有非标记的雷周围的点都踩完 就赢了:

当玩家踩到非雷时 会显示 这个点 周围雷的个数:

当这个点周围没有雷时 不会显示数字0,而是自动帮你展开 到周围有雷的位置:

 

 只有胜利 或者 被炸死从而结束游戏时 会 打印一次 存放雷的棋盘:

 代码如下 :

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"


/初始化棋盘的函数
void InitBoard(char Board[ROWS][COLS],int rows,int cols,char set) 
	int i;
	int j;
	for (i = 0; i < rows; i++) /将每个元素都设为0
		for (j = 0; j < cols; j++) 
			Board[i][j] = set;
		
	

/打印棋盘的函数   
void DisplayBoard(char Board[ROWS][COLS], int row, int col) 
	int i;
	int j;
	
	printf("————扫雷游戏————\\n");
	for (j = 0; j < 10; j++) 
		if (0 == j) 
			printf("%d  ", j);
			continue;
		
		printf("%d ",j);
	
	printf("\\n\\n");
	for (i = 1; i <=row; i++) 
		printf("%d  ", i);
		for (j = 1; j <= col; j++) 
			printf("%c ", Board[i][j]);
		
		printf("\\n");
	
	printf("————扫雷游戏————\\n");


会打印如下棋盘

/设置雷的函数
void SetMine(char Board[ROWS][COLS], int row, int col,int nub) 	 
	int i;
	int j;
	while (nub)  /nub为雷的个数
		 i = rand() % row + 1;/随机生成行
		 j = rand() % col + 1;/随机生成列
		if (Board[i][j] == '*') /查重
			Board[i][j] = '#';/我们用 字符'#'来表示雷
			nub--;/每设置一个雷 nub自减

		
	

/数雷的个数的函数
char CountMine(char Board[ROWS][COLS], char show[ROWS][COLS],int row, int col) 
	char count = '0';
	int i; int j;
	for (i = row - 1; i < row + 2; i++) 

		for (j = col - 1; j < col + 2; j++) /排查点 周围 雷的个数
			
			if (Board[i][j] == '#') 
				count++;

			
		

	
	return count;
	
	
/当3X3范围内没有雷时 自动展开的函数
这里用到了递归,若周围没有雷就把这个点设成 空白字符 并自动把周围的点都踩了,直到周围有雷为止
void Extend(char Board[ROWS][COLS],char show[ROWS][COLS],int row,int col)
	show[row][col] = ' ';

	int i, j;
	for (i = row - 1; i < row + 2; i++) 
		for (j = col - 1; j < col + 2; j++) 
			
			if (show[i][j] == '*') 
				show[i][j] = CountMine(Board, show, i, j);
				if (show[i][j] == '0') 
					Extend(Board, show, i, j);
				
			
		
		
	

/判断 游戏的函状态的函数
int Is_win(char Board[ROWS][COLS],char show[ROWS][COLS], int row, int col,int nub) 
	int i,j;
	int count = 0;/数正确的标记
	int count0 = 0;/数标记的总个数
	int COUNT = 0;/数*号后面是雷的个数
	int COUNT0 = 0;/数*号的总个数
	for (i = 1; i <=row; i++) 
		for (j = 1; j <= col; j++) 
			if (show[i][j] == '!') 
				count0++;
				if (Board[i][j] == '#') 
					count++;
				
			if (show[i][j] == '*') 
				COUNT0++;
				if (Board[i][j] == '#') 
					COUNT++;


				
			
		
	
	if ((nub == count&&nub==count0)|| COUNT == COUNT0)  
/如果标记出了所有雷 或者 正确标记了所有没踩了的雷 就代表胜利

		return 1;返回 1
	
	else if (nub == count && nub <= count0) 
/如果有错误标记或者标记过多
		return 2;返回 2
	
	/一切正常 但没赢 
	return 0; 返回 0 

/玩家 排雷或者标记的函数!
char FindMine(char Board[ROWS][COLS],char show[ROWS][COLS], int row,int col,int nub) 
	int a, b;
	int input=1;
	while (1) 
		printf("请选择是要踩(1)还是要标记(2):>");/标记(插旗)或者 踩点
		scanf("%d", &input);
		switch (input)/这里用switch语句来对玩家的输入 执行不同的语句
		
		case 1:/ 若玩家输入 1 就是踩点 ,则执行一下语句
			printf("请输入要走的行列:>");
			while (1)  /执行踩
				scanf("%d %d", &a, &b);
				if (a > 0 && a < 10 && b>0 && b < 10) 
					if (show[a][b] != '*' && show[a][b] != '!') /查重
						printf("这个点 (%d行%d列) 已经踩过了,重新输入:>", a, b);
						continue;
					
					break;
				
				else
					printf("输入错误,重新输入:>");/输入错误提示 
			
			if (Board[a][b] == '#') /如果该点是雷,则失败,结束游戏
				return 'F';

			
			else 
				show[a][b] = CountMine(Board, show, a, b);/如果不是雷,数周围雷的个数
				if (show[a][b] == '0') /如果周围没有雷,调用自动展开函数来自动展开
					Extend(Board, show, a, b);
				
			
			if (1 == Is_win(Board, show, row, col, nub)) /每次走完 判断是否已经赢下游戏
				DisplayBoard(show, row, col);/如果赢了就结束游戏
				return 'W';
			
			
			DisplayBoard(show, row, col);/打印棋盘
		
			

			break;
		case 2://标记
/更踩点思路相似
			printf("请输入要标记的行列:>");
			while (1) 
				scanf("%d %d", &a, &b);/行 列
				if (a > 0 && a < 10 && b>0 && b < 10) /判断坐标的合法性

					if (show[a][b] == '!') /如果这是标记过的点 ,我们就把这个标记取消
						show[a][b] = '*';
/判断是否赢得游戏
						if (1 == Is_win(Board, show, row, col, nub)) 
							DisplayBoard(show, row, col);
							return 'W';
						
/如果标记多了就提示
						if (2 == Is_win(Board, show, row, col, nub)) 
							printf("标记多了...");
						
						
						break;
					
					else /如果是没标记过的点 我们就把这个点 标记上
/随后在检测是否赢得游戏
						show[a][b] = '!';
						if (1==Is_win(Board, show, row, col,nub)) 
							return 'W';
						
						if (2 == Is_win(Board, show, row, col, nub)) 
							printf("标记多了...");
						
						break;
					
				
				else 
					printf("输入错误,重新输入:>");
				
			
			DisplayBoard(show, row, col);
			break;
/这里判断 最开始选择要踩还是标记那里 是否 输入错误
		default:
			printf("输入错误,重新输入:>");
			printf("\\n");
		
	
	


/这是一个 延时打印 胜利图案的函数 增加游戏的趣味性
void SleepPrint(char* p) 
	int i;
	int len = strlen(p);
	for (i = 0; i < len; i += 2) 
		printf("%c%c", *(p + i), *(p + i + 1));
		Sleep(600);
	


这是游戏模块的主体框架
void game() 
	char Board[ROWS][COLS] =  0 ;//布置好雷的信息
	char show[ROWS][COLS] =  0 ;//排查出雷的信息
	InitBoard(Board, ROWS, COLS, '*');
	InitBoard(show, ROWS, COLS, '*');
	printf("请选择游戏难度(1~3):>");
	int tmpe;
	int nub=0;
	do 
		scanf("%d", &tmpe);
		switch (tmpe)
		
		case 1:
			nub = 10;
			break;
		case 2:
			nub = 15;
			break;
		case 3:
			nub = 20;
			break;
		default:
			printf("输入错误,重新输入:>");
			break;
		
	 while (tmpe != 1 && tmpe != 3 && tmpe != 2);
	SetMine(Board, ROW, COL, nub);
	DisplayBoard(show, ROW, COL);
	
	char Result=FindMine(Board, show, ROW, COL,nub);
	switch (Result) 
	case 'F':/如果输了 就延时打印 “你被炸死了”
		SleepPrint("你被炸死了");
		for (int i = 0; i < 3; i++) 
			printf(".");
			Sleep(600);
		
		printf("\\n");
		DisplayBoard(Board, ROW, COL);
		break;
	case'W':/如果赢了就延时打印 “你赢了”

		SleepPrint("你赢了");
		for (int i = 0; i < 3; i++) 
			printf("!");
			Sleep(600);
		
		printf("\\n");
		DisplayBoard(Board, ROW, COL);
	

/随后退出到 主界面 让玩家选择是退出程序 或是进入某个模块

这样 ,我们的扫雷游戏的部分就 完成了 .

结尾 源码

希望这篇博客 能对大家有所帮助,祝看到这篇的博客的人都早日成为 大牛!!!

 游戏的 源文件 头文件:>

                                                 扫雷游戏https://gitee.com/leyi999/project.githttps://gitee.com/leyi999/project.git

        .

以上是关于C语言实现 扫雷游戏 | 简单项目的主要内容,如果未能解决你的问题,请参考以下文章

C语言实现小游戏篇我接触的第一款电脑游戏,你可以永远相信 “ 扫雷 ” 。[ C语言实现 ] [ 超详细,超清楚 ] [ 有代码 ]

用C语言实现扫雷小游戏(附上思路+项目展示+源代码)

C语言实现简单小游戏---扫雷

简单扫雷 游戏 (C语言实现)

C语言实现小游戏:扫雷

C语言项目实战:《扫雷游戏》零基础项目,230 行源码注释示例