简易贪吃蛇

 看到别的学校大一同学的期末作业是贪吃蛇,我也斗胆尝试自己code一个简易版娱乐一下。

我采用的是链表(主要是刚学链表想试试手),其实也可以用数组(参考其他大佬)。

总的来说代码难度不是很大,都是入门时学的内容(我这个蒟蒻能完成,大家也一定可以)。主要的困惑点在于对光标控制,这超出了我的知识范畴,所以搜了一些资料,从一无所知到大体明白(也算有进步吧)

以下代码能够实现贪吃蛇的主要操作,但是也还有可以优化的地方。

可能的的优化方向:

1、加减速

2、穿墙

3、随机生成超级奖励

4、界面优化等

---------------------------------------------------------分割线---------------------------------------------------------------

更新版来啦!已实现上述优化欢迎体验!

#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<math.h>
#include<stdbool.h>
#include<string.h>
#include<time.h>/*用于调用 time_t time(time_t *seconds)函数。
				返回自纪元 Epoch(1970-01-01 00:00:00 UTC)起经过的时间*/
#include<conio.h>/*用于调用int getch(void)函数,返回从控制台读取的一个字符。
				就本程序而言用于获得键盘的上下左右键信息来指导蛇的移动*/


#define chance 10		//触发big食物
#define minspeed 100
#define shang 72		//上键对应的getch()值为22472
#define you 77			//右键对应的getch()值为22477
#define xia 80			//下键对应的getch()值为22480
#define zuo 75			//左键对应的getch()值为22475
#define space 32		//空格键对应的getch()值为22432
#define Ecs 27			//退出键对应的getch()值为22427
#define f1 59
#define f2 60

struct Snake//链表储存蛇蛇信息
{
	int x;
	int y;
	struct Snake *next;
};
struct Food//储存食物的位置
{
	int x;
	int y;
};
int border_X=26;		//确定图的横向边界
int border_Y=15;	//确定图的纵向边界
struct Food food;
struct Snake *head,*tail;
int state=shang;//记录用户按下的键
int score=0;//总得分
int score_small=10;//每个$食物的得分
int score_big=50;
int addscore=0;
int endgamereason=0;//endgamereason=1表示撞墙而亡	endgamereason=2表示我吃我自己	endgamereason=3表示我自己玩不下去了要退出
int sleeptime=300;

void welcome(void);
void gamecircle(void);//游戏主体
void Pos(int x,int y);//光标定位
void initgraph(void);//初始化界面
void createfood(void);//生成食物
void createfood_small(void);
void createfood_big(void);
void initsnake(void);//初始化蛇蛇
void endgame(void);//结束游戏
void reachborder(void);//判断蛇蛇是否到达边界
bool biteself(int x,int y);//判断蛇蛇是否咬自己
void movesnake(void);//蛇蛇动起来
void Pause(void);//暂停
void color(int i);
void colorchoose(void);

void colorchoose(void)
{
	system("cls");
	int key;
	int i;
	Pos(border_X/2-5,border_Y/2-5);
	printf("请选择你想用的颜色吧(按下对应键即可):");
	for(i=1;i<=15;i++)
	{
		color(i);
		Pos(border_X/2+7,border_Y/2-4+i);
		printf("%c:Hello world!",i+96);
	}
	while(1)
	{
		if(_kbhit())
		{
			key=getch();
			switch (key) 
			{
				case 97:
					color(1);
					break;
				case 98:
					color(2);
					break;
				case 99:
					color(3);
					break;
				case 100:
					color(4);
					break;
				case 101:
					color(5);
					break;
				case 102:
					color(6);
					break;
				case 103:
					color(7);
					break;
				case 104:
					color(8);
					break;
				case 105:
					color(9);
					break;
				case 106:
					color(10);
					break;
				case 107:
					color(11);
					break;
				case 108:
					color(12);
					break;
				case 109:
					color(13);
					break;
				case 110:
					color(14);
					break;
				case 111:
					color(15);
					break;
				default:
					break;
			}
			
		}
		if(key>=97&&key<=111) break;
	}
	system("cls");
}
void welcome(void)
{
	Pos(border_X/2,border_Y/2+1);
	printf("欢迎来到pqy的贪吃蛇小游戏");
	Pos(border_X/2+2,border_Y/2+3);
	printf("请按SPACE键开始游戏吧!");
	int key;
	while(1)
	{
		if(_kbhit())
		{
			key=getch();
			if(key==32)
			{
				system("cls");
				Pos(border_X/2+10,border_Y/2+1);
				printf("请选择地图");
				Pos(border_X/2,border_Y/2+3);
				printf("1、小型地图	2、大型地图");
				while(1)
				{
					if(_kbhit())
					{
						
						key=getch();
						if(key==49)
						{
							colorchoose();
							border_X=26;
							border_Y=15;
							system("cls");
							system("mode con cols=55 lines=23");
							initgraph();
							initsnake();
							return ;
						}
						else if(key==50)
						{
							colorchoose();
							border_X=104;
							border_Y=45;
							system("cls");
							system("mode con cols=133 lines=50");
							initgraph();
							initsnake();
							return ;
						}
						else continue;
					}
				}
				/*
				initgraph();
				initsnake();
				break;
				*/
			}
		}
		else continue;
	}
	
}
void Pos(int x,int y)
{
    HANDLE hOut;
    COORD pos;
    pos.X=x;
    pos.Y=y;
    hOut=GetStdHandle(STD_OUTPUT_HANDLE);		//句柄
    SetConsoleCursorPosition(hOut,pos);		//确定光标位置
}
void initgraph(void)
{
	for(short i=1;i<border_Y;i++)
	{
		Pos(0,i);printf("■");
		Pos(border_X,i);printf("■");
	}
	for(short i=0;i<=border_X;i++)
	{
		Pos(i,0);
		printf("■");
		Pos(i,border_Y);
		printf("■");
	}
	Pos(0,border_Y+1);
	printf("请用上下左右键控制蛇蛇的运动方向");
	Pos(0,border_Y+2);
	printf("可以按F1键使蛇蛇加速 可以按F2键使蛇蛇减速");
	Pos(0,border_Y+3);
	printf("可以双击Esc退出游戏 可以双击space暂停游戏");
	Pos(0,border_Y+4);
	printf("开始游戏吧!");
}
void createfood(void)
{
	srand((unsigned)time(NULL));  //用时间作为种子刻意让rand() 产生的随机数随机化。
	int judge=rand()%chance;
	if(judge==6) createfood_big(),addscore=score_big;
	else createfood_small(),addscore=score_small;
}
void createfood_big(void)
{
	srand((unsigned)time(NULL));  //用时间作为种子刻意让rand() 产生的随机数随机化。
	while(1)
	{
		food.x=rand()%border_X;
		while(food.x<=1||food.x>=border_X-1) food.x=rand()%border_X;
		food.y=rand()%border_Y;
		while(food.y<=1||food.y>=border_Y-1) food.y=rand()%border_Y;
		struct Snake *p=head;
		int judge=0;
		while(p!=NULL)
		{
			if(p->x==food.x&&p->y==food.y)
			{
				judge=1;break;
			}
			p=p->next;
		}
		if(judge==0) 
		{
			Pos(food.x,food.y);
			printf("¥");
			return ;
		}
		else continue;
	}
}
void createfood_small(void)
{
	srand((unsigned)time(NULL));  //用时间作为种子刻意让rand() 产生的随机数随机化。
	while(1)
	{
		food.x=rand()%border_X;
		while(food.x<=1||food.x>=border_X-1) food.x=rand()%border_X;
		food.y=rand()%border_Y;
		while(food.y<=1||food.y>=border_Y-1) food.y=rand()%border_Y;
		struct Snake *p=head;
		int judge=0;
		while(p!=NULL)
		{
			if(p->x==food.x&&p->y==food.y)
			{
				judge=1;break;
			}
			p=p->next;
		}
		if(judge==0) 
		{
			Pos(food.x,food.y);
			printf("$");
			return ;
		}
		else continue;
	}
}
void initsnake(void)
{
	head=(struct Snake*)malloc(sizeof(struct Snake));
	head->x=border_X/2;
	head->y=border_Y/2;
	head->next=NULL;
	struct Snake* p;
	p=(struct Snake*)malloc(sizeof(struct Snake));
	p->x=border_X/2;
	p->y=border_Y/2+1;
	p->next=NULL;
	head->next=p;
	
	struct Snake *q=head;
	Pos(q->x,q->y);
	printf("*");
	q=q->next;
	while(q!=NULL)
	{
		Pos(q->x,q->y);
		printf("*");
		q=q->next;
	}
	createfood();
}
void endgame(void)
{
	system("cls");
	if(endgamereason==1)
	{
		Pos(border_X/2+1,border_Y/2-1);
		printf("你成功撞墙而亡!");
		Pos(border_X/2+1,border_Y/2+1);
		printf("你最终的得分是:%d",score);
		exit(0);
	}
	else if(endgamereason==2)
	{
		Pos(border_X/2+1,border_Y/2-1);
		printf("你成功把自己吃掉了!");
		Pos(border_X/2+1,border_Y/2+1);
		printf("你最终的得分是:%d",score);
		exit(0);
	}
	else if(endgamereason==3)
	{
		Pos(border_X/2+1,border_Y/2-1);
		printf("自己玩不下去就别玩。。。");
		Pos(border_X/2+1,border_Y/2+1);
		printf("你最终的得分是:%d",score);
		exit(0);
	}
} 
void reachborder(void)
{
	if(head->x==0||head->x==border_X||head->y==0||head->y==border_Y)
	{
		endgamereason=1;
		endgame();
	}
}
bool biteself(int x,int y)
{
	struct Snake *p=head;
	while(p!=NULL)
	{
		if(p->x==x&&p->y==y)
		{
			return true;
		}
		else p=p->next;
	}
	return false;
}
void movesnake(void)
{
	reachborder();
	struct Snake *newnode;
	newnode=(struct Snake*)malloc(sizeof(struct Snake));
	if(state==shang)
	{
		if(biteself(head->x,head->y-1))
		{
			endgamereason=2;endgame();
		}
		if(head->x==food.x&&head->y-1==food.y)
		{
			newnode->x=head->x;
			newnode->y=head->y-1;
			newnode->next=head;
			head=newnode;
			score+=addscore;
			struct Snake *p=head;
			while(p!=NULL)
			{
				Pos(p->x,p->y);
				printf("*");
				p=p->next;
			}
			createfood();
		}
		else
		{
			newnode->x=head->x;
  			newnode->y=head->y-1;
  			newnode->next=head;
  			head=newnode;
  			struct Snake *p=head;
  			while(p->next->next!=NULL)
  			{
  				Pos(p->x,p->y);
  				printf("*");
  				p=p->next;
  			}
  			Pos(p->next->x,p->next->y);
  		   	printf(" ");
  		   	free(p->next);
  		   	p->next=NULL;
		}
	}
	else if(state==you)
	{
		if(biteself(head->x+1,head->y))
		{
			endgamereason=2;endgame();
		}
		if(head->x+1==food.x&&head->y==food.y)
		{
			newnode->x=head->x+1;
			newnode->y=head->y;
			newnode->next=head;
			head=newnode;
			score+=addscore;
			struct Snake *p=head;
			while(p!=NULL)
			{
				Pos(p->x,p->y);
				printf("*");
				p=p->next;
			}
			createfood();
		}
		else
		{
			newnode->x=head->x+1;
  			newnode->y=head->y;
  			newnode->next=head;
  			head=newnode;
  			struct Snake *p=head;
  			while(p->next->next!=NULL)
  			{
  				Pos(p->x,p->y);
  				printf("*");
  				p=p->next;
  			}
  			Pos(p->next->x,p->next->y);
  		   	printf(" ");
  		   	free(p->next);
  		   	p->next=NULL;
		}
	}
	else if(state==xia)
	{
		if(biteself(head->x,head->y+1))
		{
			endgamereason=2;endgame();
		}
		if(head->x==food.x&&head->y+1==food.y)
		{
			newnode->x=head->x;
			newnode->y=head->y+1;
			newnode->next=head;
			head=newnode;
			score+=addscore;
			struct Snake *p=head;
			while(p!=NULL)
			{
				Pos(p->x,p->y);
				printf("*");
				p=p->next;
			}
			createfood();
		}
		else
		{
			newnode->x=head->x;
  			newnode->y=head->y+1;
  			newnode->next=head;
  			head=newnode;
  			struct Snake *p=head;
  			while(p->next->next!=NULL)
  			{
  				Pos(p->x,p->y);
  				printf("*");
  				p=p->next;
  			}
  			Pos(p->next->x,p->next->y);
  		   	printf(" ");
  		   	free(p->next);
  		   	p->next=NULL;
		}
	}
	else if(state==zuo)
	{
		if(biteself(head->x-1,head->y))
		{
			endgamereason=2;endgame();
		}
		if(head->x-1==food.x&&head->y==food.y)
		{
			newnode->x=head->x-1;
			newnode->y=head->y;
			newnode->next=head;
			head=newnode;
			score+=addscore;
			struct Snake *p=head;
			while(p!=NULL)
			{
				Pos(p->x,p->y);
				printf("*");
				p=p->next;
			}
			createfood();
		}
		else
		{
			newnode->x=head->x-1;
  			newnode->y=head->y;
  			newnode->next=head;
  			head=newnode;
  			struct Snake *p=head;
  			while(p->next->next!=NULL)
  			{
  				Pos(p->x,p->y);
  				printf("*");
  				p=p->next;
  			}
		 	Pos(p->next->x,p->next->y);
		   	printf(" ");
		   	free(p->next);
		   	p->next=NULL;
		}
	}
}
void Pause(void)
{
	int newstate;
	while(1)
	{
		Pos(border_X+2,border_Y/2+2);
		printf("暂停中,请双击SPACE继续游戏");
		
		Sleep(300);
		if(_kbhit())
		{
			newstate=getch();
			if(newstate==32) 
			{
				Pos(border_X+2,border_Y/2+2);
				printf("                           ");
				return;
			}
		}
	}
}
void gamecircle(void)
{
	int newstate;
	while(1)
	{
		Pos(border_X+2,border_Y/2-2);
		time_t cur_time;
		time(&cur_time);
		printf("%s",ctime(&cur_time));
		Pos(border_X+2,border_Y/2-1);
		printf("你现在的得分是:%d",score);
		Pos(border_X+2,border_Y/2);
		printf("每吃一个$的得分:%03d",score_small);
		Pos(border_X+2,border_Y/2+1);
		printf("每吃一个Y的得分:%03d",score_big);
		Sleep(sleeptime);
		if(_kbhit())//如果用户使用了键盘就会进入if语句之中,对所按键进行进一步处理
		{
			newstate=getch();//这个会保存224
			newstate=getch();
			if(newstate==shang&&state!=xia)
			{
				state=shang;
			}
			else if(newstate==xia&&state!=shang)
			{
				state=xia;
			}
			else if(newstate==zuo&&state!=you)
			{
				state=zuo;
			}
			else if(newstate==you&&state!=zuo)
			{
				state=you;
			}
			else if(newstate==space)
			{
				Pause();
			}
			else if(newstate==Ecs)
			{
				endgamereason=3;
				endgame();
			}
			else if(newstate==f1)//加速
			{
				if(sleeptime>100)
				{
					sleeptime-=20;
					score_small+=1;
					score_big+=2;
					Pos(border_X+2,border_Y/2+2);
					printf("蛇蛇速度+1 $得分+1 ¥得分+2");
				}
				else
				{
					Pos(border_X+2,border_Y/2+2);
					printf("已经是最快速度啦!");
				}
			}
			else if(newstate==f2)//减速
			{
				if(sleeptime<500)
				{
					sleeptime+=20;
					score_small=score_small-1;
					score_big-=2;
					Pos(border_X+2,border_Y/2+2);
					printf("蛇蛇速度-1 $得分-1 ¥得分-2");
				}
				else
				{
					Pos(border_X+2,border_Y/2+2);
					printf("已经是最慢速度啦!");
				}
			}
		}
		movesnake();
		//Sleep(200);
	}
}
void color(int i)
{
	if (0 <= i && i <= 15)
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), i);
	else return;
}
int main()
{
	system("mode con cols=55 lines=23");//设定黑框框大小
	welcome();
	gamecircle();
	system("pause>nul");//不要出现“按任意键继续。。。”这句话
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值