C语言实现数字连连看

C语言实现数字连连看

要求

连连看小游戏开发,使用二维数组来保存游戏地图的数据,实现连连看的核心功能。欢乐连连看的功能有:主界面、开始游戏、消子、判断胜负、提示、重排、计时、游戏模式。
 主界面
游戏主界面就是进行各项操作的入口。
 开始游戏
玩家选择开始游戏模式,进入游戏后,选择开始游戏,系统根据设置随机生成数字,以供玩家点击消除。
 消子
对玩家选中的两张图片进行判断,判断是否符合消除规则。只有符合以下规则的图片对才能被消除:
 一条直线连通
 两条直线连通
 三条直线连通
如果可以消除,两个数字变为0。如果不能消除,则保持原来的游戏地图。
 判断胜负
当游戏完成后,需要判断游戏胜负。不同模式下判断胜负的规则不同。
 基本模式时,如果在五分钟内将游戏地图的所有图片都消除,则提示玩家胜利。
 休闲模式时,如果游戏地图中所有图片都被消除,则提示玩家获胜。
 提示
可以提示界面上能够消除的一对图片。
 计时
设定一定时间来辅助游戏是否结束。
 游戏模式
游戏模式有:基本模式、休闲模式和关卡模式三种,可以根据是否定时等规则进行设置。

代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define WIDTH 10
#define HEIGHT 12
int datas[HEIGHT][WIDTH] = {0};

int Choose_type ();
void Creat_datas (int fol);
bool IsHLinked(int x1,int y1,int x2,int y2);
bool IsVLinked(int x1,int y1,int x2,int y2);
bool IsZeroTurnLinked(int x1,int y1,int x2, int y2);		//一条线 
bool IsOneTurnLinked(int x1, int y1, int x2,int y2);		//二条线  
bool IsTwoTurnLinked(int x1,int y1,int x2,int y2);		//三条线 
bool Judge_Answer (int x1,int y1,int x2,int y2);  //判断是否可消去 
void Print_datas ();
bool Play_Game (int Flo);
bool Isblank ();
bool Help_ans ();
bool Basic_Play ();//基础 
bool Relax_Play ();//休闲 
bool Win_Play ();//闯关 

int main()
{
	int Flo;
	Flo = Choose_type ();  // choose the type
	if (Flo == 0)	return 0;
	srand(unsigned(time(NULL)));
	Creat_datas(Flo);  //creat the graph
	Print_datas ();
	bool ov;
	ov = Play_Game (Flo);
	if (ov == true){
		printf ("VICTORY");
	}
	else{
		printf ("FAILED");
	}
	return 0;
 }
 
 bool Basic_Play ()
 {
 	long int t1 ,t2 = 0 ;
 	int op = 1;
 	int x1,y1,x2,y2;
 	bool ANS;
 	printf ("五分钟计时开始\n");
 	t1 = clock();
 	while (t2 < 300000 && !Isblank() && op != 0 )
 	{
 		if (op == 1)
 		{
 			Print_datas ();
 			printf("请输入两者的坐标[x1 y1 x2 y2]:");			//从上到下,从左到右,先行后列 
 			scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
 			if (Judge_Answer (x1, y1, x2,y2))
 			{
 				datas[x1][y1] = datas[x2][y2] = 0;
 				Print_datas ();
			}
		 	else{
				printf("错误");
		 	}
		}
		if (op == 2)
		{ 
		 	ANS = Help_ans ();
		 	Print_datas ();
		 	if (ANS == false)  
		 	{
		 		printf ("已没有可以消去的\n");
			 	return true;
			 }
	 	}
		printf("是否继续游戏 1、YES 0、NO 2、HELP:");
		scanf ("%d",&op);
		t2 = clock() - t1;
	}
	if (t2 > 299)
	{
		printf ("超时\n");
		return false;
	}
	if (Isblank())	return true;
	else return false;
}

bool Help_ans ()
{
	int k;
	for (int i = 1; i < 11;i++)
	{
		for (int j = 1; j < 9;j++)
		{
			if (datas[i][j] != 0)
			{
				k = j+1;
				for (int m = i; m < 11;m++)
				{
					for (int n = k; n < 9;n++)
					{
						if (datas[i][j] == datas[m][n])
						{
							if (Judge_Answer(i,j,m,n))
 							{
 								printf ("(%d,%d)  (%d,%d)\n",i,j,m,n);
 								datas[i][j] = datas[m][n] = 0;
 								return true;
							 }
						}
					}
					k = 1;
				}
			}
		}
	}
	return false;
}

 
  bool Relax_Play ()
 {
 	int op = 1;
 	int x1,y1,x2,y2;
 	bool ANS;
 	while (!Isblank() && op != 0)   //G isn't blank
 	{
 		if (op == 1)
 		{
 			Print_datas ();
 			printf("请输入两者的坐标[x1 y1 x2 y2]:");
 			scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
 			if (Judge_Answer (x1, y1, x2,y2))
 			{
 				datas[x1][y1] = datas[x2][y2] = 0;
 				Print_datas ();
			 }
			 else{
		 		printf("错误");
		 	}
		 }
		 if (op == 2)
		 { 
		 	ANS = Help_ans ();
		 	Print_datas ();
		 	if (ANS == false)  
		 	{
		 		printf ("已没有可以消去的\n");
			 	return true;
			 }
		 }
		 printf("是否继续游戏 1、YES 0、NO 2、HELP:");
		 scanf ("%d",&op);
	 }
	 if (!Isblank())	return false;
	 else 	return true;
 }
 
  bool Win_Play ()
 {
 	int op = 1;
 	int x1,y1,x2,y2;
 	bool ANS;
 	while (!Isblank() && op != 0)   //G isn't blank
 	{
 		if (op == 1)
 		{
 			Print_datas ();
 			printf("请输入两者的坐标[x1 y1 x2 y2]:");
 			scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
 			if (Judge_Answer (x1, y1, x2,y2))
 			{
 				datas[x1][y1] = datas[x2][y2] = 0;
 				Print_datas ();
			 }
			 else{
		 		printf("错误");
		 	}
		 }
		 printf("是否继续游戏 1、YES 0、NO :");
		 scanf ("%d",&op);
	 }
	 if (!Isblank() && Help_ans)	return false;
	 else	
	 	return true ;
 }
 
 bool Isblank ()
 {
 	for(int j=1; j < 10 ; j++)
	{
		for (int i= 1; i< 8 ; i++)
		{
			if (datas[j][i] != 0)		return false;
		}
	}
	return true;
 }
 
bool Play_Game (int Flo)
 {
 	bool Ans;
 	if (Flo == 1) 			//the basic type
 	{
 		printf ("基本模式:\n");
 		Ans = Basic_Play ();
 		return Ans;
	 }
	 if (Flo == 2) 			//the relax type
 	{
 		printf ("休闲模式:\n");
 		Ans = Relax_Play ();
 		return Ans;
	 }
	 else 			//the win type
 	{
 		printf ("第%d关游戏:\n",Flo - 2);
 		Ans = Win_Play ();
 		return Ans;
	 }
 }
 
 void Print_datas ()
 {
 	for(int j=1; j < 11 ; j++)
	{
		printf("\t\t");
		for (int i= 1; i< 9 ; i++)
		{
			printf("%d\t",datas[j][i]);
		}
		printf("\n");
	}
 }
 
 bool Judge_Answer (int x1,int y1,int x2,int y2)
 {
 	if (datas [x1][y1] != datas[x2][y2] || datas [x1][y1] == 0 || datas [x2][y2] == 0 ) return false;
 	if (x1 == x2  &&  y1 == y2)   return false;
 	if (x1 > 11 || x2 > 11 || y1> 9 || y2 > 9)	return false;
 	if (x1 == x2 || y1 == y2)
 	{
 		if (IsZeroTurnLinked(x1,y1,x2,y2) || IsTwoTurnLinked(x1,y1,x2,y2))		return true;
	 }
	else{
		if (IsOneTurnLinked(x1,y1,x2,y2) || IsTwoTurnLinked(x1,y1,x2,y2))		return true;
	}
	return false;
 }
 
 int Choose_type ()
 {
 	printf("请选择你要进行的操作:1,开始游戏  2,结束游戏\n");
 	int op;
 	scanf("%d",&op);
 	if (op == 1)
 	{
 		printf("\n请选择游戏模式:1、基本模式  2、休闲模式  3、关卡模式\n");
		int ops;
		scanf ("%d",&ops);
		if (ops == 1)	return 1;
		if (ops == 2)	return 2;
		if (ops == 3)
		{
			printf("\n请选择你选择的关卡3-16:");
			int opsd;
			scanf ("%d",&opsd);
			return opsd;
		}
	 }
 	if (op == 2)	return 0;
 }
 
void Creat_datas (int fol)
 {
 	int tmpDatas[80] = {0}; // 定义一个临时数组用于存放
 	int PicNum[] = {3,4,5,1,2,7,9,6,8,44,78,12,90,33,34};
	int Count = 0,i, j, d = 0,Pic,tem,t;
	Pic = 8 * 10 / (fol + 9 );
	for(j=0; j < 80 ; j++)
	{
		tmpDatas[j] = PicNum[d];
		Count++;
		if (Count == Pic )
		{
			d++; 
			Count = 0;	
		}
	}
	d = 80;
	for(j=1;j < HEIGHT - 1;j++)
		for (i = 1;i < WIDTH - 1; i++)
		{
			t = rand() % d;					//Fisher-Yates Shuffle 
			tem = tmpDatas[t];
			tmpDatas[t] = tmpDatas[d -1];
			tmpDatas[d - 1] = tem;
			datas[j][i] = tmpDatas[d -1];
			d--;
		}
}



bool IsHLinked(int x1,int y1,int x2,int y2)			//横向是否连接
{
	int minY,maxY;
	if (x1 != x2)		return false;
	if (y1 < y2){
		minY = y1;
		maxY = y2;
	}
	else{
		minY = y2;
		maxY = y1;
	} 
	if (maxY - minY == 1)	return true;
	for ( int i = minY +1; i < maxY ; i++) //从左到右检查中间的点是不是空的
	{
		if (datas[x1][i] != 0)		return false;
	}
	return true;
}

bool IsVLinked(int x1,int y1,int x2,int y2)		//纵向是否连接
{
	int minX,maxX;
	if (y1 != y2)		return false;
	if (x1 < x2){
		minX = x1;
		maxX = x2;
	}
	else{
		minX = x2;
		maxX = x1;
	}
	if (maxX - minX == 1)	return true; 
	for ( int i = minX +1; i < maxX ; i++) 
	{
		if (datas[i][y1] != 0)		return false;
	}
	return true;
}



bool IsZeroTurnLinked(int x1,int y1,int x2, int y2)			//不转折时判断
{
	if (IsHLinked(x1, y1, x2,y2))
	{
		return true ;
	}
	if (IsVLinked(x1, y1, x2, y2))
	{
		return true ;
	}
	return false;
}



bool IsOneTurnLinked(int x1, int y1, int x2,int y2)			//转折一次
{
	int tmpX[2] = { x1, x2 };
	int tmpY[2] = { y2, y1 };
	for (int i = 0; i < 2; i++)
		{
			if (datas[tmpX[i]][tmpY[i]] != 0)	continue;
			if (IsZeroTurnLinked( tmpX[i], tmpY[i], x1, y1) && IsZeroTurnLinked( tmpX[i], tmpY[i], x2,y2))
			{
				return true;
			}
		}
	return false;
}


bool IsTwoTurnLinked(int x1,int y1,int x2,int y2)
{
	int j, tmpX1,tmpY1,tmpX2,tmpY2;
	//纵向遍历所有点
	tmpX1 = x1;
	for ( j = 0; j < WIDTH; j++)
	{
		tmpY1 = j;
		if (j == y1)		continue; 
		if (tmpX1 == x2 && tmpY1 == y2)	continue; 		//重合
		tmpX2 = x2;
		tmpY2 = tmpY1;
		if (datas[tmpX1][tmpY1] != 0 || datas[tmpX2][tmpY2] != 0)	continue;
		if (IsZeroTurnLinked(tmpX1, tmpY1, tmpX2, tmpY2) && IsZeroTurnLinked(tmpX1, tmpY1, x1, y1) && IsZeroTurnLinked(tmpX2, tmpY2, x2, y2))
			return true;
	}
	//横向遍历所有点
	tmpY1 = y1;
	for ( j = 0; j < HEIGHT; j++)
	{
		tmpX1 = j;
		if (j == x1)		continue; 
		if (tmpY1 == y2 && tmpX1 == x2)	continue; 		//重合
		tmpY2 = y2;
		tmpX2 = tmpX1;
		if (datas[tmpX1][tmpY1] != 0 || datas[tmpX2][tmpY2] != 0)	continue;
		if (IsZeroTurnLinked(tmpX1, tmpY1, tmpX2, tmpY2) && IsZeroTurnLinked(tmpX1, tmpY1, x1, y1) && IsZeroTurnLinked(tmpX2, tmpY2, x2, y2))
		{
			return true;
		}
	}
	return false;
 }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值