贪食蛇-二稿

#include<stdio.h>
#include<stdlib.h>       		/*函数srand()*/ 
#include<conio.h>       		/*按钮函数getch()*/
#include<windows.h>    			/*时间间断Sleep()函数*/
#include<time.h>      			/*函数time()*/
#include<string.h>  		    /*初始化函数memset*/
void fun();          			/*主体函数*/ 
void food();        			/*随机生成食物*/ 
void Show();        			/*刷屏*/ 
void An();         				//按钮 
void Mo();          			//蛇移动 
void jie();         			//判断是否越界 
void Head(int x,int y);			//控制蛇头 
void Score();          			//得分处理 
void decoration1();   			//装饰1 
void decoration2();    			//装饰2 
char Map[100][100];             //地图 
int H,L,key,flag=0;				//H 地图高,L地图长,key按钮,flag控制不走回头路 
int time1,cas,score;            //time1 ,cas用于时间选择--难度等级,score-分数统计 
int sum=1,over=0;               //sum-蛇身长度,over 结束标志位 
int dir[4][2]={					//方向 二维数组 
{0,-1},
 {0,1},
{-1,0},
 {1,0}
};
struct Snake{					// 蛇身结构体,x对应行坐标,y对应列坐标 
	int x,y;
	int now;					//now 方向 
}Snake[10000];					
const char Sh='@';				//蛇头 const 变常量 
const char Sb='@';              //蛇身 const 变常量
const char Sf='*';              //食物 const 变常量
const char floor=' ';           //地板 const 变常量
int main()
{	
	fun();						//主体函数 
	Show();						//展示--刷屏 
	return 0;
}
void fun()
{
	int i,j;
	int hx,hy;
	printf("\t请输入H L(H*2=L):\n\t");	//自定义长宽 
		scanf("%d%d",&H,&L);
    memset(Map, floor, sizeof(Map)); 		//初始化地图 
	system("cls");							//刷屏 
	srand(time(0));							//系统时间种 种子 
	hx=rand()%H;							//蛇头随机出现 
	hy=rand()%L;
	Map[hx][hy]=Sh;							//出现蛇头 
	Snake[0].x=hx;							//蛇头结构体 -把蛇头坐标赋值 
	Snake[0].y=hy;
	food();									//产生食物 
    decoration1();							//开始界面 
	scanf("%d",&cas);						//选择难度 
	switch(cas)
	{
		case 1:time1=500;break;
		case 2:time1=300;break;
		case 3:time1=100;break;
		default:time1=300;break;
	}
	getch();
	system("cls");
    decoration2();							//界面停顿画面 
    getch();
    An();
}
void food()									//随机产生食物并保证行列坐标合法,并在把地图上显示食物 
{
	int fx,fy;
	while(1)
	{
		fx=rand()%H;
		fy=rand()%L;
		if(Map[fx][fy]==floor)
		{
			Map[fx][fy]=Sf;
			break;
		}
	}
}
void Show()									//每次画面的显示效果 
{
	int i,j;
	while(1)								//创造出无限死循环  - 当over标志位为1 -及判断蛇头自食或撞墙-跳出该循环 
	{
	
		Sleep(time1);
		An();
		Mo();
		if(over)							//跳出前显示游戏结束语 
		{
			printf("\n\t**游戏结束**\n");
			printf("\t你的成绩为:");
			Score();
			putchar('\n');
			printf(" \t   ::>_<::  \n");
			printf(" \t   ::>_<::  \n");
			getchar();						 
			getchar();
			break;
		}
		system("cls");
		decoration2();
		printf("\n\t当前蛇节数为:%6d\n",sum);		//分数显示 
		printf("\t当前分数为:");
		Score();
	
	}
}
void An()
{
		while(kbhit()!=0)				//接受按键输入--getch()函数是接受按键输入不需回车、tab键、空格等 
			key=getch();
        if((key==75&&flag!=2)||(key==77&&flag!=1)||(key==72&&flag!=4)||(key==80&&flag!=3)||sum==1)//sum==1及蛇节只有1可以折返 
        switch(key)
		{
		        case 75:Snake[0].now=0; flag=1;//左 			//本人查找时发现 75、77、72、80其实并不是方向键 所具备的ASCII码 
		                 break;	
                case 77:Snake[0].now=1; flag=2;//右 
		                 break;
                case 72:Snake[0].now=2; flag=3;//上 			//其实应该是-3275,-3277,-3272,-3280.但是转为十进制时 
		                 break;
                case 80:Snake[0].now=3;flag=4;//下 				//详细咨询http://blog.csdn.net/feilong911hao/article/details/42081967 
		                 break;
		} 	
}
void Mo()											//****核心部分**** 蛇运动 
{
	int i,x,y;
	int t=sum;
	x=Snake[0].x;									//记录蛇头的横纵坐标 
	y=Snake[0].y;									//注意  x-行标,y-列标 ,不同于数学的坐标表示 
	Map[x][y]=floor;								//把头的原有坐标  变成  地板 
	Snake[0].x=Snake[0].x+dir[Snake[0].now][0];		//更新头的坐标变化   -根据 方向 二维数组  
	Snake[0].y=Snake[0].y+dir[Snake[0].now][1];
	jie();											//判断越界--撞墙   、蛇头合法性
	Head(x,y);										//蛇头 -走的三种可能分别为 地板、食物、蛇身
	 
	if(sum==t)										//非常关键的判断 --****没有吃到食物 
	{
		for(i=1;i<sum;i++)							//记住蛇头坐标为  snake[0].x与snake[0].y 蛇头已经在MO函数表现在地图中 
		{											//所以for 从 i=1 开始 for 循环分三部分 
			if(i==1)								//第一部分--蛇尾变成地板 
				Map[Snake[i].x][Snake[i].y]=floor;
			if(i==sum-1)							//第二部分蛇头后一节 -- 变成蛇头原位置,方向 与蛇头方向一致 
			{
				Snake[i].x=x;
				Snake[i].y=y;
				Snake[i].now=Snake[0].now; 
			}
			else									//第三部分蛇身从后往前 - 一一替代 
			{
				Snake[i].x=Snake[i+1].x;
				Snake[i].y=Snake[i+1].y;
				Snake[i].now=Snake[i+1].now;
			}
			Map[Snake[i].x][Snake[i].y]=Sb;			//上面上部分分别是蛇结构体数组坐标变化别忘了还有地图显示 
		}
	}
} 
void jie()
{
	if(Snake[0].x<0||Snake[0].x>=H||Snake[0].y<0||Snake[0].y>=L)//判断越界及坐标不合法 
	{
				over=1;								//标志位over 
	}
}
void Head(int x,int y)
{
	if(Map[Snake[0].x][Snake[0].y]==floor)				//没有进食头坐标先变蛇头--Mo函数执行 --详情看上面 
	   Map[Snake[0].x][Snake[0].y]=Sh;					//Mo执行及把蛇整体向前一步 
	   
   	else if(Map[Snake[0].x][Snake[0].y]==Sf)			//吃到食物 
   	{
	    	Map[Snake[0].x][Snake[0].y]=Sh;				//地图中	从食物变化为蛇头 
	    	Snake[sum].x=x;								//蛇变长  别忘了 蛇头是 snake[0].x,~.y 蛇身加长体现在snake[sum]数组末端 
	    	Snake[sum].y=y;								//蛇头下一节 变化坐标为蛇头原坐标 
	    	Snake[sum].now=Snake[0].now;				//方向变化 
	    	Map[Snake[sum].x][Snake[sum].y]=Sb;			//地图显示的 蛇头原位置-蛇头下一节其实是变成地图了--可以看MO函数 
	    	sum++;										//sum增加  蛇节数 从数组是 0-sum-1 还需要对应 mo函数中的for( ;i<sum;);  
	    	food();										//吃完食物别忘了要创造 
    }
    else
    {
    		over=1;										//考虑自食情况 
   	}
    
}
void Score()											//以下没有技巧可言的部分不作一一解释 
{
	switch(cas)
	{
		case 1:score=(sum-1)*2;break;
		case 2:score=(sum-1)*4;break;
		case 3:score=(sum-1)*8;break;
		default:score=(sum-1)*5;break;
	}
	printf("%d\n",score);
}
void decoration1()
{
	printf("\n\n\n\n\n\n\t按任意键开始\n");
	getch();
	system("cls");
	printf("\n\n\n\n\n\t认真阅读游戏规则\n");
	printf("\t1.按←↑→↓控制贪食蛇方向移动\n");
	printf("\t2.贪食蛇若撞墙或者自食则结束游戏\n");
	printf("\t***祝游戏愉快***\n"); 
	getch();
	system("cls");
	printf("\n\n\t难度1  每吃一个食物就可加2分 \n\t难度2  每吃一个食物就可加4分\n\t难度3  每吃一个食物就可加8分\n\t若不为上面难度系数则每吃一食物就可加5分\n");
	printf("\n\t选择难度\n\t1.简单\n\t2.普通\n\t3.困难:\n\t你所选择的是:");
}
void decoration2()
{
    int i,j;
	for(i=1;i<=H/3;i++)
	    printf("\n"); 
	    printf("\n\t");
		for(i=0;i<=L/2+1;i++)
		{	   
		    printf(i==L/2+1?"■\n":"■");
		}
	for(i=0;i<H;i++)
    {
    	 printf("\t");
    	 printf("■");
         for(j=0;j<L;j++)
		 {
 			printf("%c",Map[i][j]);
 		}	
 		printf("■\n");
    }
	printf("\t");
		for(i=0;i<=L/2+1;i++)
		{	   
		    printf(i==L/2+1?"■\n":"■");
		} 
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值