消灭星星源代码(c语言实现)

15 篇文章 0 订阅
11 篇文章 0 订阅

   最近花了1天半时间用c实现了现在较火的手机游戏《消灭星星》,亲测无误,在此贴出代码以飨网友,有bug在所难免,欢迎指正!(未经本人同意不得随意转载、复制,谢谢!)

#include<stdio.h>
#include<stdlib.h> 
#define true 1
#define false 0
typedef struct node{
	int center;//本节点的值 
	int up;//相邻的上面节点的值 
	int down;//相邻的下面节点的值 
	int left;//相邻的左面节点的值 
	int right;//相邻的右面节点的值 
	int x;//x下标 
	int y;//y下标 
	int flag;//查找匹配标记,0为未查找或不匹配,1表示匹配 
}Node;
typedef Node HD[10][10];//10X10随机矩阵,其中center值介于1到5之间 
typedef Node HDStack[100];//查找栈 
enum Mode{ //node节点的方位指引,用于node节点各分量值的输出 
	mModeCenter,
	mModeUp,
	mModeDown,
	mModeLeft,
	mModeRight,
};
static int myScore = 0;//玩家游戏得分 
static int top = 100;//栈顶指针 
//static int num = 0;
static int between = 2;
static int sensorship = 54;//关卡数 
static int standardScore = 1000;
void pop(HDStack stack);//弹出栈顶元素
void push(HDStack stack,Node value);//将value压入栈顶 
Node getTop(HDStack stack);//取栈顶元素 
void init(HD hd);//初始化数组 
void parseC2UDLR(HD hd);//根据数组hd的已知center值确定up,down,left和right的值
int findInHd(HD hd,HDStack stack,int xindex,int yindex);//在数组中找出和xindex行yindex列的值相同的紧邻的连续相同数字所在位置 
void move2Replace(HD hd);//移动center分量为0的上面的数字取代0,若存在整列数字均为0,则该列数字向右各列均向左移一列 
void reZero(HD hd);//数组清零 
int hasSameNum(HD hd);//判断数组剩余非零数字中是否有连续相同的数字,用于单个关卡是否结束的判断  
void print(HD hd,Mode mode);//根据mode打印数组相应的信息 
int main(){
	printf("**********************************\n");//游戏介绍 
	printf("++++++++++++++++++++++++++++++++++\n");
	printf("+            游戏须知            +\n");
	printf("+                                +\n");
	printf("+  在矩阵中确定一个点,与该点相邻 +\n");
	printf("+  或连续相邻且值相等的点将一并  +\n");
	printf("+          消除并置换为0         +\n");
	printf("+  请在'请输入起点'处输入你想输  +\n");
	printf("+  入的合法的矩阵行号和列号      +\n");
	printf("+       (均从1开始到10结束)      +\n");
	printf("+                                +\n");
	printf("+  技巧:与所输入的点相邻或连续  +\n");
	printf("+        相邻的点越多得分越高,   +\n");
	printf("+        最后剩余的星星越少得    +\n");
	printf("+                越高            +\n");
	printf("++++++++++++++++++++++++++++++++++\n\n");
	printf("        oooooooooooo\n");
	printf("     O|| Game Start ||O\n");
	printf("        oooooooooooo\n");
	printf("----------------------------------\n");
	int cycle = 1;
	int bscore[9] = {2,5,9,14,20,27,35,44,54};
	for(cycle;cycle <= sensorship;cycle ++){//关卡循环 
		HD hd;
		int x,y,mm,remainNum = 100;
		int judge = true;
		int find = 0;
		init(hd);
		parseC2UDLR(hd);
		for(int i = 0;i < 9;i++){
			if(cycle-1 == bscore[i])
				find = 1;
		}
		if(cycle == 1)
			standardScore += 0;
		else{//确定每关目标分数 
			if(find == 1)
				standardScore += 3000;
			else
				standardScore += 2000;
			}
		print(hd,mModeCenter);
		while(judge == true){//单个关卡游戏主程 
			printf("oooooooooooooooooooooooooooooooooo\n");
			printf("|关卡:%2d目标:%6d分数:%6d|\n",cycle,standardScore,myScore);
			printf("oooooooooooooooooooooooooooooooooo\n\n");
			HDStack stack;
			int num = 0;
			//print(hd,mModeCenter);
			printf("       请输入起点:");
			scanf("%d%d",&x,&y);
			while(x > 10 || x < 1 || y > 10 || y < 1 || hd[x-1][y-1].center == 0 || (hd[x-1][y-1].center != hd[x-1][y-1].up && hd[x-1][y-1].center != hd[x-1][y-1].left && hd[x-1][y-1].center != hd[x-1][y-1].right && hd[x-1][y-1].center != hd[x-1][y-1].down)){
				printf("       请重新输入:");
				scanf("%d%d",&x,&y);                            //输入合法性检查 
			}
			num = findInHd(hd,stack,x,y);
			if(num == 1)
				num = 0;
			else
				myScore += 5*num*num;//统计得分 
			remainNum -= num;
			///print(hd,mModeCenter);
			move2Replace(hd);
			parseC2UDLR(hd); //重置 
			if(num >= 8)
				printf("\n             好!\n\n");
			if(num >= 15)
				printf("\n             酷!\n\n");
			if(num >= 18)
				printf("\n       你真是吊爆了\n           土豪\n          我们做朋友吧!\n\n");
			printf("      AAAAAAAAAAAAAAAAA\n");
			printf("      # %d连消+%d分 #\n",num,5*num*num);
			printf("      VVVVVVVVVVVVVVVVV\n\n");
			print(hd,mModeCenter);
			judge = hasSameNum(hd);// 关卡是否结束 
			if(judge == false){//统计奖励 
				if(remainNum <= 20){
					printf("\n");
					printf("	 HHHHHHHHHHHHHHHHH\n");
					printf("	 T 奖励%d分 T\n",remainNum*remainNum*5);
					myScore += remainNum*remainNum*5;
					printf("     |剩余%d颗星星|\n",remainNum);
					printf("     CCCCCCCCCCCCCCCCC\n\n");
				}else{
					printf("\n");
					printf("     HHHHHHHHHHHHHHHHH\n");
					printf("     T 奖励%d分 T\n",0);
					printf("     |剩余%d颗星星|\n",remainNum);
					printf("     CCCCCCCCCCCCCCCCC\n\n");
				}
			}
			if(myScore >= standardScore){//通过关卡 
				printf("        vvvvvvvvvvv\n");
				printf("        }恭喜通关!{\n");
				printf("        vvvvvvvvvvv\n");
			}
		}
		reZero(hd);//清零
		if(myScore < standardScore)
			printf("        通关失败!\n"); 
		else
			printf("        顺利通关!\n");
			printf("         请选择:\n");
			printf("**输入1表示继续下一关**\n**输入2表示退出游戏**\n**输入3表示重新开始游戏**\n_>\n");
		scanf("%d",&mm);
		switch(mm){//游戏进程选择 
			case 1:continue;break;
			case 2:exit(0);
			case 3:cycle--;break;
		}
		
	}
	printf("----------------------------------\n");
	return 0;
}
void init(HD hd){
	//初始化数组
	int i,j,value;
	 for(i = 0;i < 10;i++){
	 	for(j = 0;j < 10;j++){
	 		//value = 1+(int)(5.0*rand()/(RAND_MAX+1.0));
	 		value = (int)(rand()%5)+1;
	 		hd[i][j].center = value;
	 		hd[i][j].up = 0;
	 		hd[i][j].down = 0;
	 		hd[i][j].left = 0;
	 		hd[i][j].right = 0;
	 		hd[i][j].x = i;
	 		hd[i][j].y = j;
	 		hd[i][j].flag = 0;
	 	}
	 }
}
void print(HD hd,Mode mode){
	//根据打印数组相应mode的信息 
	int i,j;
	printf("    1 2 3 4 5 6 7 8 9 0\n");
	printf(" \\  - - - - - - - - - -  \\\n\n");
	for(i = 0;i < 10;i++){
		if(i == 9)
			printf("%d|  ",0);
		else
			printf("%d|  ",i+1);
		for(j = 0;j < 10;j++){
			switch(mode){
				case mModeCenter:printf("%d ",hd[i][j].center);break;
				case mModeUp:printf("%d ",hd[i][j].up);break;
				case mModeDown:printf("%d ",hd[i][j].down);break;
				case mModeLeft:printf("%d ",hd[i][j].left);break;
				case mModeRight:printf("%d ",hd[i][j].right);break;
			}
		}
		if(i == 9)
			printf(" |0\n");
		else
			printf(" |%d\n",i+1);
	}
	printf("\n \\  - - - - - - - - - -  \\\n");
	printf("    1 2 3 4 5 6 7 8 9 0\n");
}
void parseC2UDLR(HD hd){
	//根据数组hd的已知center值确定up,down,left和right的值
	int i,j;
	for(i = 0;i < 10;i++){
		for(j = 0;j < 10;j++){
			hd[i][j].flag = 0;
			if(i == 0){//上边界 
				if(j == 0){//左上角 
					hd[i][j].up = 0;
					hd[i][j].left = 0;
					hd[i][j].right = hd[i][j+1].center;
					hd[i][j].down = hd[i+1][j].center;
				}else if(j == 9){//右上角 
					hd[i][j].up = 0;
					hd[i][j].right = 0;
					hd[i][j].left = hd[i][j-1].center;
					hd[i][j].down = hd[i+1][j].center;
				}else{//去除顶点剩余上边界 
					hd[i][j].up = 0;
					hd[i][j].left = hd[i][j-1].center;
					hd[i][j].right = hd[i][j+1].center;
					hd[i][j].down = hd[i+1][j].center;	
				}
			}else if(i == 9){ //下边界 
				if(j == 0){//左下角 
					hd[i][j].up = hd[i-1][j].center;
					hd[i][j].left = 0;
					hd[i][j].right = hd[i][j+1].center;
					hd[i][j].down = 0;
				}else if(j == 9){//右下角 
					hd[i][j].up = hd[i-1][j].center;
					hd[i][j].right = 0;
					hd[i][j].left = hd[i][j-1].center;
					hd[i][j].down = 0;
				}else{//去除顶点剩余下边界 
					hd[i][j].up = hd[i-1][j].center;
					hd[i][j].left = hd[i][j-1].center;
					hd[i][j].right = hd[i][j+1].center;
					hd[i][j].down = 0;	
				}
			}else{ 
				if(j == 0){//去除顶点剩余左边界 
					hd[i][j].up = hd[i-1][j].center;
					hd[i][j].left = 0;
					hd[i][j].right = hd[i][j+1].center;
					hd[i][j].down = hd[i+1][j].center;
				}else if(j == 9){//去除顶点剩余右边界 
					hd[i][j].up = hd[i-1][j].center;
					hd[i][j].left = hd[i][j-1].center;
					hd[i][j].right = 0;
					hd[i][j].down = hd[i+1][j].center;
				}else{//去除边界剩余节点 
					hd[i][j].up = hd[i-1][j].center;
					hd[i][j].left = hd[i][j-1].center;
					hd[i][j].right = hd[i][j+1].center;
					hd[i][j].down = hd[i+1][j].center;
				}
			}
		}
	}
}
void pop(HDStack stack){
	//弹出栈顶元素 
	if(top < 100)
		stack[top++].center = 0;
	else{
		printf("The index beyond out of the boundary!");
		exit(0);
	}
}
void push(HDStack stack,Node value){
	//将value压入栈顶 ;
	if(top > 1){
		stack[--top] = value;
	}
	else{
		printf("The index below out of the boundary!");
		exit(0);
	}
} 
Node getTop(HDStack stack){
	//取栈顶元素 
	if(top > -1 && top < 101)
		return stack[top];
	else{
		printf("The stack out of the boundary!");
		exit(0);
	}
}
int findInHd(HD hd,HDStack stack,int xindex,int yindex){
//在数组中找出和xindex行yindex列的值相同的紧邻的连续相同数字所在位置 
	hd[xindex-1][yindex-1].flag = 1;
	int value = hd[xindex-1][yindex-1].center,snum = 0;
	push(stack,hd[xindex-1][yindex-1]);
	snum++;
	Node node = hd[xindex-1][yindex-1];
	if(node.up != value && node.down != value && node.left != value && node.right != value){
		//hd[getTop(stack).x][getTop(stack).y].center = 0;
		pop(stack);
		return 1 ;
	}else{
		while(top < 100){
			if(getTop(stack).up == value && hd[getTop(stack).x-1][getTop(stack).y].flag == 0){//向上查找 
					hd[getTop(stack).x-1][getTop(stack).y].flag = 1;
					push(stack,hd[getTop(stack).x-1][getTop(stack).y]);
					snum++;
			}else if(getTop(stack).left == value && hd[getTop(stack).x][getTop(stack).y-1].flag == 0){//向左查找 
					hd[getTop(stack).x][getTop(stack).y-1].flag = 1;
					push(stack,hd[getTop(stack).x][getTop(stack).y-1]);
					snum++;
			}else if(getTop(stack).right == value && hd[getTop(stack).x][getTop(stack).y+1].flag == 0){//向右查找 
					hd[getTop(stack).x][getTop(stack).y+1].flag = 1;
					push(stack,hd[getTop(stack).x][getTop(stack).y+1]);
					snum++;
			}else if(getTop(stack).down == value && hd[getTop(stack).x+1][getTop(stack).y].flag == 0){//向下查找 
					hd[getTop(stack).x+1][getTop(stack).y].flag = 1;
					push(stack,hd[getTop(stack).x+1][getTop(stack).y]);
					snum++;
			}else{//返回弹出 
				hd[getTop(stack).x][getTop(stack).y].center = 0;
				pop(stack);
			}
		}
	}
	return snum;
} 
void move2Replace(HD hd){ 
	//移动center分量为0的上面的数字取代0,若存在整列数字均为0,则该列数字向右各列均向左移一列 
	int i,j,rows = 10;
	for(j = 0;j < rows;j++){
		int real = 0;
		int emptyNum = 0;
		int value[10] = {0,0,0,0,0,0,0,0,0,0};
		for(i = 9;i >= 0;i--){//非零值归栈 
			if(hd[i][j].center != 0){
				value[real++] = hd[i][j].center;
			}else{
				emptyNum++;
			}
		}
		for(i = 0;i < 10;i++){//列重置 
			hd[i][j].center = value[9-i];
		}
		if(emptyNum == 10){//全零列消除 
			if(j < 9){
				int l = j;
				for(l;l < 9;l++){
					for(i = 0;i < 10;i++){
						hd[i][l].center = hd[i][l+1].center;
					}
				}
				j--;//回扫 
				rows--;//优化处理 
			}
			int l;
			for(l = 0;l < 10;l++){//末列置零 
				hd[l][9].center = 0;
			}
		}
	}
	return ;
} 
int hasSameNum(HD hd){
	//判断数组剩余非零数字中是否有连续相同的数字,用于单个关卡是否结束的判断 
	int rows = 10,i,j;
	do{
		for(i = 9;i >= 0;i--){
			for(j = 0;j < rows;j++){
				if(i == 9)
					if(hd[i][j].center == 0 && hd[i][j].left != 0)//第j+1列往右为空,缩短列访距,优化搜索 
						rows = j+1;
				if(hd[i][j].center != 0 && (hd[i][j].center == hd[i][j].left || hd[i][j].center == hd[i][j].right || hd[i][j].center == hd[i][j].up || hd[i][j].center == hd[i][j].down)){
					//出现连续的相邻相同数字 
					return true;
				}
			}
		}
	}while(0);
	return false;
} 
void reZero(HD hd){
	//数组清零 
	for(int i = 0;i < 10;i++){
		for(int j = 0;j < 10;j++){
			hd[i][j].center = 0;
		}
	}
	parseC2UDLR(hd);
<p>}
</p>
  • 11
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值