C语言构建连连看游戏(矩阵方式)

C语言构建连连看游戏

设计要求

用数字+英文字母,采用文本输出的方式。每次输出一个8*10的矩形,然后等待玩家输入两个数字或字母的坐标,如果满足消除规则就输出新的矩形。
注意:考虑类似迷宫的处理方式,在8 * 10矩形之外加一层空心围墙,可以用来连接。大家体验一下连连看游戏就可以发现这个规则。判断是否能连,用的是10 *12的数组,最外层添加的是空格,可用来辅助连接。

分析

大纲(简化):

/*******************************************************************/
	//1生成游戏桌面*
		//1.1选项
	//2生成游戏局*
	//3游戏操作
		//3.1选择方块
		//3.2判断是否有路径*
		//3.3修改矩阵图层和迷宫图层
		//3.4刷新页面
	//4游戏胜利条件
		//4.1时间限制
		//4.2游戏结束
		//4.3结算游戏*

/*******************************************************************/ 

本设计采用了双图层的思路,分别设计显示图层与连连看内部游戏图层。
显示图层方便用户操作,
内部游戏图层方便进行连连看消除处理。

设计

生成游戏桌面

#include<Windows.h>   	//生成游戏界面
#include<stdio.h>
#define GameWindoHight	16
#define GameWindoWidth	75

void GameInit()		//生成游戏主界面
{
	//界定游戏桌面大小 
	char chCmd[32];
	sprintf(chCmd,"mode con cols=%d lines=%d",GameWindoWidth,GameWindoHight);
	system(chCmd);

	//游戏引导 
	printf("\t\t\t欢迎进入矩阵连连看游戏");				printf("\n\n");
	printf("\t\t\t---- 游戏开始----\t\t");					printf("\n\n");
	printf("\t\t\t  请选择游戏模式 \t\t");					printf("\n\n");
	printf("\t\t\t----1基本模式----\t\t");					printf("\n");		//正向计时 
	printf("\t\t\t----2休闲模式----\t\t");					printf("\n");		//不计时 
	printf("\t\t\t----3关卡模式----\t\t");					printf("\n\n");		//倒计时 
	printf("\t\t\t----4退出游戏----\t\t");					printf("\n");		//退出程序
} 

生成游戏局

内部(迷宫)图层:

#define MaxSize 100
int mg[10][12]= {		//迷宫图层 
	{0,0,0,0,0,0,0,0,0,0,0,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,0,0,0,0,0,0,0,0,0,0,0}
	};
	struct MMP 
{ 
	int i,j;			//位置
	int di;				//下一步可走
} St[MaxSize];

bool mgpath(int xi, int yi, int xe, int ye)			//判断是否有路径
{ 	int i,j, i1,j1,di;
	int mg1[10][12];
	memcpy(mg1,mg,sizeof(mg));
	bool find;
	int top=-1;
	top++;
	St[top].i=xi;
	St[top].j=yi;
	St[top].di=-1;
	mg1[xi][yi]=-1;
	mg1[xe][ye]=0;
	while (top>-1)
	{ 	i= St[top].i;j= St[top].j;
		di=St[top].di;
		if (i==xe&& j== ye)	
		{
			return true;
		} 
		find= false;
		while (di<4 && !find)
		{
			di++; 
			switch(di)
			{ 
				case 0:i1=i-1; j1=j;break;
				case 1:i1=i;j1=j+1; break;
				case 2:i1=i+1; j1=j;break;
				case 3:i1=i;j1=j-1; break;
			}
			if(i1<12&&j1<10)
			{
				if (mg1[i1][j1]==0) find=true;
			}
		}
		if (find)
		{	St[top].di=di;
			top++;St[top].i=i1;St[top].j=j1;
			St[top].di= - 1;
			mg1[i1][j1]= -1;
		}
		else
		{
			mg1[i][j]=0;
			top-- ;
		} 
	} 
	return false;
}

用户(棋局)图层:

棋子生成阶段:

typedef struct pieces
{
	int data_num;
	int data_letter;
} Piece;				//棋子

typedef struct rand_factor
{
	int data;
	int data_times;
} factor;				//随机因子属性——用于随机棋子

 void Rand_Num(int a[],int Num_Range,int T)		//生成棋子属性——作为棋子生成阶段的一部分
{
	srand((unsigned)time(NULL));//生成随机数种子
	int n=0;
	int i=0;
	factor b[Num_Range];
	for(int ii=0;ii<Num_Range;ii++)
	{
//		b[ii].data=ii;					
		b[ii].data_times=0;
	}
	while(n<Num_Range*T){
		int m=rand()%Num_Range;
		if(b[m].data_times<T){
			a[i]=m;
			b[m].data_times++;
			m=rand()%Num_Range;
			i++;
			n++;
		}
		else
		 continue;
	}
 } 
 
 void ChesspiecesInit(Piece* pieces)  //棋子生成
{
	
	int data_num[80];
	Rand_Num(data_num,10,8);
	int Num_Range=10;
	for(int num=0;num<Num_Range*8;num++)
	{
		pieces[num].data_num=data_num[num];			//数值 
	}

	for(int i=0;i<Num_Range;i++)
	{
		int letter[8];
		Rand_Num(letter,8,1);
		int k=0;
		int j=0;
		while(k<8)
		{
			if(pieces[j].data_num==i)
			{
				pieces[j].data_letter=letter[k];	//颜色 
				k++;
			}
			j++;
		}
	}
} 

棋盘生成阶段

void CameBordInit(Piece* pieces)
{
	for(int i=0;i<10;i++)
		printf("------%d",i+1);
	printf("\n");
	for(int i=0;i<8;i++)
	{
		printf("[%d]",i+1);
		for(int j=0;j<10;j++)
		{
			if(pieces[j+i*10].data_num!=10&&pieces[j+i*10].data_letter!=10)
				printf(" <%d,%c> ",pieces[j+i*10].data_num,35+pieces[j+i*10].data_letter%4);
			else
				printf(" <*v*> ");			//本来想打空格的,可是这个表情太可爱了!(可以选择全空格输出,界面会清晰一点
		}
		printf("\n");
	}
}

游戏操作

选择——简单粗暴

		scanf("%d,%d",&x1,&y1);
		scanf("%d,%d",&x2,&y2);

判断路径等行为发生在迷宫图层:

bool mgpath(int xi, int yi, int xe, int ye)
{ 	int i,j, i1,j1,di;
	int mg1[10][12];
	memcpy(mg1,mg,sizeof(mg));
	bool find;
	int top=-1;
	top++;
	St[top].i=xi;
	St[top].j=yi;
	St[top].di=-1;
	mg1[xi][yi]=-1;
	mg1[xe][ye]=0;
	while (top>-1)
	{ 	i= St[top].i;j= St[top].j;
		di=St[top].di;
		if (i==xe&& j== ye)	
		{
			return true;
		} 
		find= false;
		while (di<4 && !find)
		{
			di++; 
			switch(di)
			{ 
				case 0:i1=i-1; j1=j;break;
				case 1:i1=i;j1=j+1; break;
				case 2:i1=i+1; j1=j;break;
				case 3:i1=i;j1=j-1; break;
			}
			if(i1<12&&j1<10)
			{
				if (mg1[i1][j1]==0) find=true;
			}
		}
		if (find)
		{	St[top].di=di;
			top++;St[top].i=i1;St[top].j=j1;
			St[top].di= - 1;
			mg1[i1][j1]= -1;
		}
		else
		{
			mg1[i][j]=0;
			top-- ;
		} 
	} 
	return false;
}

修改显示图层:

void GamePlay(int x1,int y1,int x2,int y2,Piece* pieces)
{
	if(pieces[y1*10+x1].data_num==pieces[y2*10+x2].data_num)
		if(abs(pieces[y1*10+x1].data_letter-pieces[y2*10+x2].data_letter)==4)
		{
			if(mgpath(x1+1, y1+1, x2+1, y2+1))
			{
				pieces[y1*10+x1].data_letter=pieces[y1*10+x1].data_num=pieces[y2*10+x2].data_letter=pieces[y2*10+x2].data_num=10;
				mg[x1+1][y1+1]=mg[x2+1][y2+1]=0;
			} 
		}
}
		//配合上棋盘生成函数中的
	else
		printf(" <*v*> ");	

刷新界面用:

system("cls");  //简单粗暴

游戏胜利(结束)

判断结束:(暂不解释,看代码理解)
1.时间限制
2.自主退出
时间限制使用系统计时
自动退出引导用户输入特定符号

游戏结算:输出分数

void Game_Score()
{
	int score=80;
	for(int i=0;i<10;i++)
		for(int j=0;j<12;j++)
			score=score-mg[i][j];
	printf("\t\t\t您现在的得分是:%d \n",score);
}

完整程序

/*******************************************************************/
	//1生成游戏桌面
		//1.1选项
	//2生成游戏局
	//3游戏操作
		//3.1选择方块
		//3.2判断是否有路径
		//3.3判断是否消除
		//3.4消除并刷新页面
	//4游戏胜利条件
		//4.1时间限制
		//4.2游戏结束
		//4.3判断是否胜利 

/*******************************************************************/ 
#include<Windows.h>   	//生成游戏界面
#include<stdio.h>
#define GameWindoHight	16
#define GameWindoWidth	75

#include<stdio.h>		//生成棋局图层 
#include<time.h>
#include<stdlib.h>

#include"sqstack.cpp"

#include<time.h>

#define MaxSize 100
typedef struct rand_factor
{
	int data;
	int data_times;
} factor;				//随机到你了吗? 

typedef struct pieces
{
	int data_num;
	int data_letter;
} Piece;

int mg[10][12]= {		//路径图层 
	{0,0,0,0,0,0,0,0,0,0,0,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,1,1,1,1,1,1,1,1,1,1,0},
	{0,0,0,0,0,0,0,0,0,0,0,0}
	};

struct MMP 
{ 
	int i,j;
	int di;
} St[MaxSize];

double DDL=600;

	//1生成游戏桌面
void GameInit()
{
	//界定游戏桌面大小 
	char chCmd[32];
	sprintf(chCmd,"mode con cols=%d lines=%d",GameWindoWidth,GameWindoHight);
	system(chCmd);

//	printf("-----------------李云龙应约召唤而来!---------------");printf("\n");
//	printf("-------------你他娘的就是老子的Master吗?-----------");printf("\n\n");
	//游戏引导 
	printf("\t\t      欢迎进入矩阵连连看游戏");				printf("\n\n");
	printf("\t\t\t---- 游戏开始----\t\t");					printf("\n\n");
	printf("\t\t\t  请选择游戏模式 \t\t");					printf("\n\n");
	printf("\t\t\t----1基本模式----\t\t");					printf("\n");		//正向计时 
	printf("\t\t\t----2休闲模式----\t\t");					printf("\n");		//不计时 
	printf("\t\t\t----3关卡模式----\t\t");					printf("\n");		//倒计时 
//	printf("\t\t----4米斯达骂骂咧咧地退出房间了……");	printf("\n");		//退出程序 
	printf("\t\t\t----4退出游戏----\t\t");					printf("\n");		//退出程序
} 
	//生成棋局 
void Rand_Num(int a[],int Num_Range,int T)
{
	srand((unsigned)time(NULL));//生成随机数的种子
	int n=0;
	int i=0;
	factor b[Num_Range];
	for(int ii=0;ii<Num_Range;ii++)
	{
//		b[ii].data=ii;					
		b[ii].data_times=0;
	}
	while(n<Num_Range*T){
		int m=rand()%Num_Range;
		if(b[m].data_times<T){
			a[i]=m;
			b[m].data_times++;
			m=rand()%Num_Range;
			i++;
			n++;
		}
		else
		 continue;
	}
 } 

void ChesspiecesInit(Piece* pieces)
{
	
	int data_num[80];
	Rand_Num(data_num,10,8);
	int Num_Range=10;
	for(int num=0;num<Num_Range*8;num++)
	{
		pieces[num].data_num=data_num[num];			//数值 
	}

	for(int i=0;i<Num_Range;i++)
	{
		int letter[8];
		Rand_Num(letter,8,1);
		int k=0;
		int j=0;
		while(k<8)
		{
			if(pieces[j].data_num==i)
			{
				pieces[j].data_letter=letter[k];	//颜色 
				k++;
			}
			j++;
		}
	}
} 

void CameBordInit(Piece* pieces)
{
	for(int i=0;i<10;i++)
		printf("------%d",i+1);
	printf("\n");
	for(int i=0;i<8;i++)
	{
		printf("[%d]",i+1);
		for(int j=0;j<10;j++)
		{
			if(pieces[j+i*10].data_num!=10&&pieces[j+i*10].data_letter!=10)
				printf(" <%d,%c> ",pieces[j+i*10].data_num,35+pieces[j+i*10].data_letter%4);
			else
				printf(" <*v*> ");
		}
		printf("\n");
	}
}

bool mgpath(int xi, int yi, int xe, int ye)
{ 	int i,j, i1,j1,di;
	int mg1[10][12];
	memcpy(mg1,mg,sizeof(mg));
	bool find;
	int top=-1;
	top++;
	St[top].i=xi;
	St[top].j=yi;
	St[top].di=-1;
	mg1[xi][yi]=-1;
	mg1[xe][ye]=0;
	while (top>-1)
	{ 	i= St[top].i;j= St[top].j;
		di=St[top].di;
		if (i==xe&& j== ye)	
		{
			return true;
		} 
		find= false;
		while (di<4 && !find)
		{
			di++; 
			switch(di)
			{ 
				case 0:i1=i-1; j1=j;break;
				case 1:i1=i;j1=j+1; break;
				case 2:i1=i+1; j1=j;break;
				case 3:i1=i;j1=j-1; break;
			}
			if(i1<12&&j1<10)
			{
				if (mg1[i1][j1]==0) find=true;
			}
		}
		if (find)
		{	St[top].di=di;
			top++;St[top].i=i1;St[top].j=j1;
			St[top].di= - 1;
			mg1[i1][j1]= -1;
		}
		else
		{
			mg1[i][j]=0;
			top-- ;
		} 
	} 
	return false;
}

void GamePlay(int x1,int y1,int x2,int y2,Piece* pieces)
{
	if(pieces[y1*10+x1].data_num==pieces[y2*10+x2].data_num)
		if(abs(pieces[y1*10+x1].data_letter-pieces[y2*10+x2].data_letter)==4)
		{
			if(mgpath(x1+1, y1+1, x2+1, y2+1))
			{
				pieces[y1*10+x1].data_letter=pieces[y1*10+x1].data_num=pieces[y2*10+x2].data_letter=pieces[y2*10+x2].data_num=10;
				mg[x1+1][y1+1]=mg[x2+1][y2+1]=0;
			} 
		}
}

void Game_Score()
{
	int score=80;
	for(int i=0;i<10;i++)
		for(int j=0;j<12;j++)
			score=score-mg[i][j];
	printf("\t\t\t您现在的得分是:%d \n",score);
}

int main()
{
	//生成游戏桌面 
	GameInit();
	//选择游戏模式 
	int Gmode;
	int x1,y1,x2,y2;
	double time,end;
	scanf("%d",&Gmode);
	//刷新界面->进入游戏 
	clock_t start;
	start=clock();
	Piece pieces[80];
	ChesspiecesInit(pieces);
	while(1)
	{
		end = clock();
		system("cls");
/***************************************************/ 
	switch(Gmode)                           //其他模式配件 
	{
		case 1:
			printf("当前游戏时间:%f s\n\n",(double)(end-start)/CLK_TCK);break;
		case 3:
			time=DDL-(double)(end-start)/CLK_TCK;
			printf("剩余游戏时间:%f\t\t\t(输入qqqq结束游戏\n\n",time);
			if(time<0)
			{
				printf("游戏结束!交作业的小伙伴给个三连吧,要不评论区下次一定?<*v*>\n"); 
				Game_Score();
				return 0;
			};break; 
		case 4:
			printf("?!?!?!?\n");
			printf("  我自闭了!");
			return 0;
	}
	
	
/****************娱乐模式主体***********************/ 
		Game_Score();
		CameBordInit(pieces);		
		scanf("%d,%d",&x1,&y1);
		scanf("%d,%d",&x2,&y2);
		if(x1=='q')
		{
			Game_Score();
			return 0; 
		}
		x1=x1-1;y1=y1-1;
		x2=x2-1;y2=y2-1;
		GamePlay(x1,y1,x2,y2,pieces);

	}

	return 0;
} 
  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值