C语言学习记录230624

        许久未见,上次写的博文已经是两天前的,这两天正值端午放假,出去玩了两天,虽然人在外面也在学习,但用笔记本敲代码实在是力不从心,所以想想就也暂停一下博客。

        当然玩了两天之后,今天过来也算是一番苦战,将作业题扫雷小游戏算是写出来了,讲师一共给出了可选的拓展增加难度的选项,不过这俩选项对于原版的扫雷来说可太寻常了。一个是空白部分自己爆开,另一个是给雷添加标记,第二个其实我也能写,但是已经想休息了,所以就放弃了,但是第一个拓展功能我是写出来了。接下来附上我的源代码,跟之前的三子棋一样,也是多文件组合的项目,所以这次给出的代码也是拆分的。(感觉也挺倒霉的,就是回到家网络因为运营商那边出问题,所以网络停了,现在是通过自己手机开热点,给自己笔记本开了热点,把这点东西写出来,所以很多东西弄的比之前还差,请见谅)

        (一)主程序

/*  扫雷  */
//主程序实现的功能 
//1、点开程序弹出菜单图,用户选择1游玩扫雷游戏,选择2退出程序。
//2、用户玩好一把扫雷之后,再次弹出菜单图,用户选择1游玩扫雷游戏,选择2退出程序 、

#include"saolei.h"

int main(void)
{
	char input;
	
	do
	{	
		Print_menu();
		while(scanf("%c%*c",&input)!=1)getchar();
		switch(input)
		{
			case '1':Game();break;
			case '2':input=0;break;
			default:printf("您输入的是非法值,请依照菜单重新输入:\n");break;
		}
	}while(input);
	
	return 0;
}

        (二)头文件

#ifndef SAOLEI_H_
#define SAOLEI_H_

//头文件 
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

//宏
#define NEED_ROW 10//需要显示的扫雷棋盘行数
#define NEED_COLUMN 10//需要显示的扫雷棋盘列数
#define REAL_ROW 12 //实际建立的扫雷棋盘行数,该值为显示的棋盘行数+2
#define REAL_COLUMN 12//实际建立的扫雷棋盘列数,该值为显示的棋盘列数+2
#define VALUE_LANDMINE 10//需要生成的地雷数量

#endif

//定义了一个枚举类型,用于表示游戏的胜利条件 
enum
{
	CONTINUE=1,FAILURE,WIN
};

//自定义函数1:打印游戏菜单
void Print_menu(void);

//自定义函数2:扫雷游戏主程序模块
void Game(void);

//自定义函数2.1:创建一个row行column列的矩阵棋盘
char** Creative_chequer(int ,int );

//自定义函数2.2:用于初始化背面棋盘
void Initialize_back_chequer(char** ,int ,int );

//自定义函数2.3:用于初始化正面棋盘
void Initialize_show_chequer(char** ,int ,int );

//自定义函数2.4:在需要展示的棋盘范围内,在背面棋盘随机生成规定数量的地雷
void Generator_landmine(char** ,int ,int ,int );

//自定义函数2.5:用于在已生成雷的背面棋盘,依照雷的布置,对应生成数字
void Generator_number(char** ,int ,int );

//自定义函数2.5.1:用于计算对应元素周围一圈的地雷数量
int Counter_number(char** ,int ,int );

//自定义函数2.6:用于打印扫雷的棋盘
void Print_chequer(char** ,int ,int );

//自定义函数2.7:当选中的是个空白区域时,将空白区域周边8个格子都打开,同时若打开有空白格子,则继续以那个空白格子为中心打开其他格子 
void Explode_chequer(char** ,char** ,int ,int ,int ,int );

//自定义函数2.8:用于判断是否胜利
int Analyze_chequer(char** ,char** ,int ,int ,int );//若返回值为1,说明没输没赢,游戏继续,若返回值为2,说明挖到了地雷,玩家输了;若返回值为3,说明已经排雷排干净了,地图上只剩下雷了  

//自定义函数2.9:用于释放申请的棋盘动态内存 
void Release_chequer(char** ,int );

        (三)扫雷自定义函数主模块

//游戏主程序功能
//1、生成两个棋盘,一个是展示给玩家的棋盘,一个是背面实际藏好雷的棋盘,考虑到后续的方便,两个棋盘都比实际大一圈。 
//2、初始化正反两个棋盘,正面棋盘全部用#号表示覆盖,还未挖开;背面棋盘用空格初始化所有格子。
//3、背面棋盘先随机生成地雷,然后再根据随机生成的地雷在地雷周边的空格产生数字。
//4、接下来打印一个棋盘,棋盘应该有正交十字坐标,方便用户选出自己要挖的位置
//5、用户输入要挖的位置后,分三种情况先进行判断,若为雷,则将雷赋值到正面棋盘对应位置,然后宣布玩家输了,游戏结束;
//   若为数字,则将数组赋值到正面棋盘,展示给玩家,让玩家继续;若为空,则应进行空爆反应,将相连的所有空格区域赋值
//	 给正面棋盘,展示给玩家后,让玩家继续。 
// 

#include"saolei.h"

//自定义函数1:打印游戏菜单
void Print_menu(void)
{
	printf("\n*************************************\n");
	printf("*-----------------------------------*\n");
	printf("*------------GAME MENU--------------*\n");
	printf("*-----------------------------------*\n");
	printf("*-------------1. PLAY---------------*\n");
	printf("*-------------2. EXIT---------------*\n");
	printf("*-----------------------------------*\n");
	printf("*************************************\n");
}

//自定义函数2:扫雷游戏主程序模块
void Game(void)
{
	char **back_chequer=NULL;
	char **show_chequer=NULL;
	int irow,icolumn;
	int r=1;
	
	srand(time(NULL));
	back_chequer=Creative_chequer(REAL_ROW,REAL_COLUMN);
	show_chequer=Creative_chequer(REAL_ROW,REAL_COLUMN);
	Initialize_back_chequer(back_chequer,REAL_ROW,REAL_COLUMN);
	Initialize_show_chequer(show_chequer,REAL_ROW,REAL_COLUMN);
	Generator_landmine(back_chequer,NEED_ROW,NEED_COLUMN,VALUE_LANDMINE);
	Generator_number(back_chequer,NEED_ROW,NEED_COLUMN);
	
	system("cls");
	Print_chequer(show_chequer,NEED_ROW,NEED_COLUMN);
	do
	{
		printf("请输入您想要挖的位置:\n");
		while(scanf("%d%d%*c",&irow,&icolumn)!=2)getchar();
		if((irow>0&&irow<=NEED_ROW)&&(icolumn>0&&icolumn<=NEED_COLUMN)&&show_chequer[irow][icolumn]=='#')
		{
			if(back_chequer[irow][icolumn]=='*')
			{
				show_chequer[irow][icolumn]=back_chequer[irow][icolumn];
			}
			else if(back_chequer[irow][icolumn]>47&&back_chequer[irow][icolumn]<58)
			{
				show_chequer[irow][icolumn]=back_chequer[irow][icolumn];
			}
			else if(back_chequer[irow][icolumn]=' ')
			{
				Explode_chequer(back_chequer,show_chequer,NEED_ROW,NEED_COLUMN,irow,icolumn);
			}
			
			system("cls");
			Print_chequer(show_chequer,NEED_ROW,NEED_COLUMN);
			r=Analyze_chequer(back_chequer,show_chequer,NEED_ROW,NEED_COLUMN,VALUE_LANDMINE);//若返回值为1,说明没输没赢,游戏继续,若返回值为2,说明挖到了地雷,玩家输了;若返回值为3,说明已经排雷排干净了,地图上只剩下雷了 
			switch(r)
			{
				case CONTINUE:break;
				case FAILURE:r=0;printf("很遗憾,您挖到了地雷,你输了。\n");break;
				case WIN:r=0;printf("恭喜您,你排除了所有地雷!!!\n");break; 
			}
		}
		else
		{
			printf("您输入的位置越界或者已展开,请重新输入想要挖的位置:\n");
			
		}
	}while(r);
	
	Release_chequer(back_chequer,REAL_ROW);
	Release_chequer(show_chequer,REAL_ROW);
}

//自定义函数2.1:创建一个row行column列的矩阵棋盘
char** Creative_chequer(int row,int column)
{
	char **p=NULL;
	int i;
	
	p=(char**)malloc(row*sizeof(char*));
	
	for(i=0;i<row;i++)
	{
		p[i]=(char*)malloc(column*sizeof(char));
	}
	
	return p;
}

//自定义函数2.2:用于初始化背面棋盘
void Initialize_back_chequer(char **back_chequer,int real_row,int real_column)
{
	int i1,i2;
	
	for(i1=0;i1<real_row;i1++)
	{
		for(i2=0;i2<real_column;i2++)
			back_chequer[i1][i2]=' ';
	}
}

//自定义函数2.3:用于初始化正面棋盘
void Initialize_show_chequer(char **show_chequer,int real_row,int real_column)
{
	int i1,i2;
	
	for(i1=0;i1<real_row;i1++)
	{
		for(i2=0;i2<real_column;i2++)
			show_chequer[i1][i2]='#';
	}
}

//自定义函数2.4:用于在背面棋盘随机生成规定数量的地雷
void Generator_landmine(char **back_chequer,int need_row,int need_column,int value_landmine)
{
	int i;
	int irow,icolumn;
	
	for(i=0;i<value_landmine;i++)
	{
		do
		{
			irow=(rand()%need_row)+1;
			icolumn=(rand()%need_column)+1;
		}while(back_chequer[irow][icolumn]!=' ');
		
		back_chequer[irow][icolumn]='*';
	}
}

//自定义函数2.5:用于在已生成雷的背面棋盘,依照雷的布置,对应生成数字
void Generator_number(char **back_chequer,int need_row,int need_column)
{
	int i1,i2;
	int counter=0;
	
	for(i1=1;i1<=need_row;i1++)
	{
		for(i2=1;i2<=need_column;i2++)
		{
			if(back_chequer[i1][i2]==' ')
			{
				counter=Counter_number(back_chequer,i1,i2);
				if(counter!=0)
					back_chequer[i1][i2]='0'+counter;
				counter=0;
			}
		}
	}
}

//自定义函数2.5.1:用于计算对应元素周围一圈的地雷数量
int Counter_number(char **back_chequer,int i1,int i2)
{
	int counter=0;
	if(back_chequer[i1-1][i2-1]=='*')
		counter++;
	if(back_chequer[i1-1][i2]=='*')
		counter++;
	if(back_chequer[i1-1][i2+1]=='*')
		counter++;
	if(back_chequer[i1][i2-1]=='*')
		counter++;
	if(back_chequer[i1][i2+1]=='*')
		counter++;
	if(back_chequer[i1+1][i2-1]=='*')
		counter++;
	if(back_chequer[i1+1][i2]=='*')
		counter++;
	if(back_chequer[i1+1][i2+1]=='*')
		counter++;
	
	return counter;
}

//自定义函数2.6:用于打印扫雷的棋盘
void Print_chequer(char **show_chequer,int need_row,int need_column)
{
	int i1,i2;
	int c_number=1,r_number=1;
	
	printf("                   CHEQUER\n\n");
	for(i1=1;i1<=need_row;i1++)
	{	
		if(i1==1)
		{
			printf("   ");
			for(i2=1;i2<=need_column;i2++)
			{
				printf("  %d ",c_number);
				c_number++;
				if(i2==need_column)printf(" \n");
			}
		}
		for(i2=1;i2<=need_column;i2++)
		{
			if(i2==1)
			{
				printf("   ");
			}
			printf("----");
			if(i2==need_column)
				printf("-\n");
		}
		for(i2=1;i2<=need_column;i2++)
		{
			if(i2==1)
			{
				if(r_number!=10)
					printf(" %d ",r_number);
				else
					printf("%d ",r_number);
				r_number++;
			}
			printf("| %c ",show_chequer[i1][i2]);
			if(i2==need_column)
				printf("|\n");
		}
		if(i1==need_row)
		{
			if(i2==1)
			{
				printf("   ");
			}
			for(i2=1;i2<=need_column;i2++)
			{	
				if(i2==1)printf("   ");
				printf("----");
				if(i2==need_column)
					printf("-\n");
			}
		}
	}
}

//自定义函数2.7:当选中的是个空白区域时,将空白区域周边8个格子都打开,同时若打开有空白格子,则继续以那个空白格子为中心打开其他格子 
void Explode_chequer(char **back_chequer,char **show_chequer,int need_row,int need_column,int irow,int icolumn)
{
	show_chequer[irow][icolumn]=back_chequer[irow][icolumn];
	
	if((irow-1>0&&irow-1<=need_row)&&(icolumn-1>0&&icolumn-1<=need_column))
	{
		if(back_chequer[irow-1][icolumn-1]>47&&back_chequer[irow-1][icolumn-1]<58&&show_chequer[irow-1][icolumn-1]=='#')
			show_chequer[irow-1][icolumn-1]=back_chequer[irow-1][icolumn-1];
		else if(back_chequer[irow-1][icolumn-1]==' '&&show_chequer[irow-1][icolumn-1]!=back_chequer[irow-1][icolumn-1])
			Explode_chequer(back_chequer,show_chequer,need_row,need_column,irow-1,icolumn-1);
	}

	if((irow-1>0&&irow-1<=need_row)&&(icolumn>0&&icolumn<=need_column))
	{
		if(back_chequer[irow-1][icolumn]>47&&back_chequer[irow-1][icolumn]<58&&show_chequer[irow-1][icolumn]=='#')
			show_chequer[irow-1][icolumn]=back_chequer[irow-1][icolumn];
		else if(back_chequer[irow-1][icolumn]==' '&&show_chequer[irow-1][icolumn]!=back_chequer[irow-1][icolumn])
			Explode_chequer(back_chequer,show_chequer,need_row,need_column,irow-1,icolumn);
	}
	
	if((irow-1>0&&irow-1<=need_row)&&(icolumn+1>0&&icolumn+1<=need_column))
	{
		if(back_chequer[irow-1][icolumn+1]>47&&back_chequer[irow-1][icolumn+1]<58&&show_chequer[irow-1][icolumn+1]=='#')
			show_chequer[irow-1][icolumn+1]=back_chequer[irow-1][icolumn+1];
		else if(back_chequer[irow-1][icolumn+1]==' '&&show_chequer[irow-1][icolumn+1]!=back_chequer[irow-1][icolumn+1])
			Explode_chequer(back_chequer,show_chequer,need_row,need_column,irow-1,icolumn+1);
	}
	
	if((irow>0&&irow<=need_row)&&(icolumn-1>0&&icolumn-1<=need_column))
	{
		if(back_chequer[irow][icolumn-1]>47&&back_chequer[irow][icolumn-1]<58&&show_chequer[irow][icolumn-1]=='#')
			show_chequer[irow][icolumn-1]=back_chequer[irow][icolumn-1];
		else if(back_chequer[irow][icolumn-1]==' '&&show_chequer[irow][icolumn-1]!=back_chequer[irow][icolumn-1])
			Explode_chequer(back_chequer,show_chequer,need_row,need_column,irow,icolumn-1);
	}
	
	if((irow>0&&irow<=need_row)&&(icolumn+1>0&&icolumn+1<=need_column))
	{
		if(back_chequer[irow][icolumn+1]>47&&back_chequer[irow][icolumn+1]<58&&show_chequer[irow][icolumn+1]=='#')
			show_chequer[irow][icolumn+1]=back_chequer[irow][icolumn+1];
		else if(back_chequer[irow][icolumn+1]==' '&&show_chequer[irow][icolumn+1]!=back_chequer[irow][icolumn+1])
			Explode_chequer(back_chequer,show_chequer,need_row,need_column,irow,icolumn+1);
	}
	
	if((irow+1>0&&irow+1<=need_row)&&(icolumn-1>0&&icolumn-1<=need_column))
	{
		if(back_chequer[irow+1][icolumn-1]>47&&back_chequer[irow+1][icolumn-1]<58&&show_chequer[irow+1][icolumn-1]=='#')
			show_chequer[irow+1][icolumn-1]=back_chequer[irow+1][icolumn-1];
		else if(back_chequer[irow+1][icolumn-1]==' '&&show_chequer[irow+1][icolumn-1]!=back_chequer[irow+1][icolumn-1])
			Explode_chequer(back_chequer,show_chequer,need_row,need_column,irow+1,icolumn-1);
	}
	
	if((irow+1>0&&irow+1<=need_row)&&(icolumn>0&&icolumn<=need_column))
	{
		if(back_chequer[irow+1][icolumn]>47&&back_chequer[irow+1][icolumn]<58&&show_chequer[irow+1][icolumn]=='#')
			show_chequer[irow+1][icolumn]=back_chequer[irow+1][icolumn];
		else if(back_chequer[irow+1][icolumn]==' '&&show_chequer[irow+1][icolumn]!=back_chequer[irow+1][icolumn])
			Explode_chequer(back_chequer,show_chequer,need_row,need_column,irow+1,icolumn);
	}

	if((irow+1>0&&irow+1<=need_row)&&(icolumn+1>0&&icolumn+1<=need_column))
	{
		if(back_chequer[irow+1][icolumn+1]>47&&back_chequer[irow+1][icolumn+1]<58&&show_chequer[irow+1][icolumn+1]=='#')
			show_chequer[irow+1][icolumn+1]=back_chequer[irow+1][icolumn+1];
		else if(back_chequer[irow+1][icolumn+1]==' '&&show_chequer[irow+1][icolumn+1]!=back_chequer[irow+1][icolumn+1])
			Explode_chequer(back_chequer,show_chequer,need_row,need_column,irow+1,icolumn+1);
	}
}

//自定义函数2.8:用于判断是否胜利
int Analyze_chequer(char **back_chequer,char **show_chequer,int need_row,int need_column,int value_landmine)//若返回值为1,说明没输没赢,游戏继续,若返回值为2,说明挖到了地雷,玩家输了;若返回值为3,说明已经排雷排干净了,地图上只剩下雷了  
{
	int r=-1;
	int i1,i2;
	int counter=0;
	
	for(i1=1;i1<=need_row;i1++)
	{
		for(i2=1;i2<=need_column;i2++)
		{
			if(show_chequer[i1][i2]=='*')
			{
				r=2;
				goto out;
			}
			else if(show_chequer[i1][i2]=='#')
				counter++;
		}
	}
	out:
	
	if(counter==value_landmine)
		r=3;
	else if(r!=2)
		r=1;
		
	return r;
}

//自定义函数2.9:用于释放申请的棋盘动态内存 
void Release_chequer(char **chequer,int row)
{
	int i;
	
	for(i=0;i<row;i++)
		free(chequer[i]);
	free(chequer);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值