贪吃蛇源码

这个贪吃蛇和俄罗斯方块当时一块写的,纯兴趣使然。完成之后自我感觉蛮好。我想,这就是让我在开始踏上编程之路时坚持的动力吧!

#include <stdio.h>
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
using namespace std;

#define MAXLEN 24
int score=0;

struct snake{
	//static int length;
	int x;
	int y;
	struct snake *p;
}*psn,*head;

struct Food
{
	int x,y;
}*pfo;

void gotoxy(int x,int y)
{
	COORD pos;
	pos.X=x*2;
	pos.Y=y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}

void color(int a)//颜色函数
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}

/*******初始化蛇******/

void creatsnake()
{
	psn=(struct snake*)malloc(sizeof(struct snake));
	head=psn;
	psn->x=3;
	psn->y=MAXLEN/2;
	//psn->length=1;
	psn->p=NULL;
	gotoxy(psn->x,psn->y);
	color(0x0A);
	cout<<"●"<<endl;

	struct snake* ps=(struct snake*)malloc(sizeof(struct snake));
	ps=(struct snake*)malloc(sizeof(struct snake));
	ps->x=2;
	ps->y=MAXLEN/2;
	ps->p=NULL;
	gotoxy(ps->x,ps->y);
	cout<<"●"<<endl;
	psn->p=ps;

	struct snake* ps1=(struct snake*)malloc(sizeof(struct snake));
	ps1=(struct snake*)malloc(sizeof(struct snake));
	ps1->x=1;
	ps1->y=MAXLEN/2;
	ps1->p=NULL;
	gotoxy(ps1->x,ps1->y);
	cout<<"●"<<endl;
	gotoxy(0,MAXLEN);
	color(0x07);
	ps->p=ps1;
}

/********初始化食物界面*********/

void creatfood(struct snake *p)		//食物不能在蛇的身体内部出现
{
	struct snake *tmp;
	srand(time(NULL));
	pfo=(struct Food*)malloc(sizeof(struct Food));
lab:	
	tmp=p;
	pfo->x=rand()%(MAXLEN-2)+1;
	pfo->y=rand()%(MAXLEN-2)+1;
	for (;tmp->p!=NULL;tmp=tmp->p)		//保证食物不会出现在蛇身体上
	{
		if(tmp->x==pfo->x&&tmp->y==pfo->y)
		{
			goto lab;
		}
	}

	gotoxy(pfo->x,pfo->y);
	color(0x0A);
	cout<<"★"<<endl;
	gotoxy(0,MAXLEN);
	color(0x07);
}

int IsEat(struct snake *p,struct Food *fo)
{
	if (p->x==fo->x&&p->y==fo->y)
	{
		return 1;
	}
	else
		return 0;
}

int IsAlive(struct snake *p)
{
	struct snake *tmp=p;
	if (p->x==0||p->x==(MAXLEN-1)||p->y==0||p->y==(MAXLEN-1))		//撞墙死亡
	{
		return 0;
	}
	else
		for (tmp=tmp->p;tmp->p!=NULL;tmp=tmp->p)					//撞到自己身体死亡
		{
			if(tmp->x==p->x&&tmp->y==p->y)
			{
				return 0;
			}
		}
		return 1;
}

void showscore()
{
	gotoxy(25,5);
	color(0x0A);
	cout<<"成绩:"<<score;
	gotoxy(0,MAXLEN);
}

void inter()
{
	int i,j;
	for (i=1;i<=MAXLEN;i++)
	{
		for (j=1;j<=MAXLEN;j++)
		{
			if ((i==1)||i==MAXLEN||(j==1)||j==MAXLEN)
			{
				//a[i][j]=1;
				cout<<"■";
			}
			else
				cout<<"  ";
				//cout<<"□";
				//a[i][j]=0;
		}
		cout<<endl;
	}
	creatsnake();
	creatfood(head);

	gotoxy(MAXLEN+2,3);
	color(0x0e);
	printf("按0自动行走或解除暂停");
	gotoxy(MAXLEN+3,4);
	printf("按上下左右控制方向");
	gotoxy(MAXLEN+4,5);
	printf("按其他任意键暂停");
	gotoxy(MAXLEN+6,MAXLEN/4+1);
	printf("score:%d",score);
	//cout<<"score:"<<score;		//为什么cout在此无法输出?
/*
	gotoxy(MAXLEN+2,MAXLEN/4+5);
	printf("按数字1—9选择难度等级");*/
	gotoxy(0,MAXLEN);
	color(0x07);

}

void swap(int *a,int *b)
{
	int tmp=*a;
	*a=*b;
	*b=tmp;
}

void up()
{	
	int frontx,fronty,laterx,latery;
	frontx=psn->x;
	fronty=psn->y-1;
	for(;psn->p!=NULL;psn=psn->p)		//bug:少循环了一次
	{
		laterx=psn->x;
		latery=psn->y;
		psn->x=frontx;
		psn->y=fronty;
		swap(&laterx,&frontx);
		swap(&latery,&fronty);
		gotoxy(psn->x,psn->y);
		color(0x0A);
		cout<<"●"<<endl;
	}
	{
		laterx=psn->x;
		latery=psn->y;
		psn->x=frontx;
		psn->y=fronty;
		swap(&laterx,&frontx);
		swap(&latery,&fronty);
		gotoxy(psn->x,psn->y);
		color(0x0A);
		cout<<"●"<<endl;
	}
	if (IsEat(head,pfo))
	{
		struct snake *tmp=(struct snake*)malloc(sizeof(struct snake));
		psn->p=tmp;
		tmp->x=frontx;
		tmp->y=fronty;
		tmp->p=NULL;
		//free tmp;
	}
	else if (psn->p==NULL)
	{
		gotoxy(frontx,fronty);
		color(0x07);
		cout<<"  "<<endl;
		//cout<<""<<endl;
	}
	psn=head;
	gotoxy(0,MAXLEN);
}

void down()
{
	int frontx,fronty,laterx,latery;
	frontx=psn->x;
	fronty=psn->y+1;
	for(;psn->p!=NULL;psn=psn->p)		//bug:少循环了一次
	{
		laterx=psn->x;
		latery=psn->y;
		psn->x=frontx;
		psn->y=fronty;
		swap(&laterx,&frontx);
		swap(&latery,&fronty);
		gotoxy(psn->x,psn->y);
		color(0x0A);
		cout<<"●"<<endl;
	}
	{
		laterx=psn->x;
		latery=psn->y;
		psn->x=frontx;
		psn->y=fronty;
		swap(&laterx,&frontx);
		swap(&latery,&fronty);
		gotoxy(psn->x,psn->y);
		color(0x0A);
		cout<<"●"<<endl;
	}
	if (IsEat(head,pfo))
	{
		struct snake *tmp=(struct snake*)malloc(sizeof(struct snake));
		psn->p=tmp;
		tmp->x=frontx;
		tmp->y=fronty;
		tmp->p=NULL;
		//free tmp;
	}
	else if (psn->p==NULL)
	{
		gotoxy(frontx,fronty);
		color(0x07);
		cout<<"  "<<endl;
		//cout<<"□"<<endl;
	}
	psn=head;
	gotoxy(0,MAXLEN);
}

void left()
{	
	int frontx,fronty,laterx,latery;
	frontx=psn->x-1;
	fronty=psn->y;
	for(;psn->p!=NULL;psn=psn->p)		//bug:少循环了一次
	{
		laterx=psn->x;
		latery=psn->y;
		psn->x=frontx;
		psn->y=fronty;
		swap(&laterx,&frontx);
		swap(&latery,&fronty);
		gotoxy(psn->x,psn->y);
		color(0x0A);
		cout<<"●"<<endl;
	}
	{
		laterx=psn->x;
		latery=psn->y;
		psn->x=frontx;
		psn->y=fronty;
		swap(&laterx,&frontx);
		swap(&latery,&fronty);
		gotoxy(psn->x,psn->y);
		color(0x0A);
		cout<<"●"<<endl;
	}
	if (IsEat(head,pfo))
	{
		struct snake *tmp=(struct snake*)malloc(sizeof(struct snake));
		psn->p=tmp;
		tmp->x=frontx;
		tmp->y=fronty;
		tmp->p=NULL;
		//free tmp;
	}
	else if (psn->p==NULL)
	{
		gotoxy(frontx,fronty);
		color(0x07);
		cout<<"  "<<endl;
		//cout<<"□"<<endl;
	}
	psn=head;
		gotoxy(0,MAXLEN);
}

void right()
{
	int frontx,fronty,laterx,latery;
	frontx=psn->x+1;
	fronty=psn->y;
	for(;psn->p!=NULL;psn=psn->p)		//bug:少循环了一次
	{
		laterx=psn->x;
		latery=psn->y;
		psn->x=frontx;
		psn->y=fronty;
		swap(&laterx,&frontx);
		swap(&latery,&fronty);
		gotoxy(psn->x,psn->y);
		color(0x0A);
		cout<<"●"<<endl;
	}
	{
		laterx=psn->x;
		latery=psn->y;
		psn->x=frontx;
		psn->y=fronty;
		swap(&laterx,&frontx);
		swap(&latery,&fronty);
		gotoxy(psn->x,psn->y);
		color(0x0A);
		cout<<"●"<<endl;
	}
	if (IsEat(head,pfo))
	{
		struct snake *tmp=(struct snake*)malloc(sizeof(struct snake));
		psn->p=tmp;
		tmp->x=frontx;
		tmp->y=fronty;
		tmp->p=NULL;
		//free tmp;
	}
	else if (psn->p==NULL)
	{
		gotoxy(frontx,fronty);
		color(0x07);
		cout<<"  "<<endl;
		//cout<<"□"<<endl;
	}
	psn=head;
	gotoxy(0,MAXLEN);
}

void autoeat(struct snake *p,struct Food *pfo)		//蛇自动去吃食物 (递归)(迷宫问题)
{
/*
	Stack S;
	InitStack(&S);*/
	struct snake* tmp=p->p;
	if (tmp->x==p->x&&tmp->y==p->y)
	{
		return;
	}
	if (p->x<pfo->x)
	{
		right();
	}
	else
		if (p->x>pfo->x)
		{
			left();
		}
		else
			if (p->y<pfo->y)
			{
				down();
			}
			else
				if (p->y>pfo->y)
				{
					up();
				}

/*
	struct snake* tmp=p->p;
	if (tmp->x==p->x&&tmp->y==p->y)
	{
		return;
	}
	if (p->x<pfo->x)
	{
		right();
	}
	else
		if (p->x>pfo->x)
		{
			left();
		}
	if (p->y<pfo->y)
	{
		down();
	}
	else
		if (p->y>pfo->y)
		{
			up();
		}*/

	//autoeat();
}

int main()
{
	system("cls");
	inter();
	gotoxy(0,24);
	int ch,tmp=0,v=1/*v:速度*/;
	//	v=getch();
	//	v=v-'0';
	while (true)
	{
		if(kbhit())
		{
			ch=getch();			//键盘方向键的键值是双字节的,所以要重复一次
			if(ch==224)
			{
				ch=getch();		
			}				
			if((tmp=='w'&&ch=='s')||(tmp=='s'&&ch=='w')||(tmp=='a'&&ch=='d')||(tmp=='d'&&ch=='a'))
			{
				ch=tmp;
			}
			tmp=ch;
		}
		switch (ch)
		{
		case '0':autoeat(head,pfo);break;
		case 72:up();break;
		case 80:down();break;
		case 75:left();break;
		case 77:right();break;
		default: break;
		}
		Sleep(300-score*2);
/*
		switch(v)
		{
		case 1:Sleep(400-score*1);break;
		case 2:Sleep(350-score*1);break;
		case 3:Sleep(300-score*1);break;
		case 4:Sleep(250-score*1);break;
		case 5:Sleep(200-score*1);break;
		case 6:Sleep(150-score*1);break;
		case 7:Sleep(100-score*1);break;
		case 8:Sleep(50*score*1);break;
		case 9:Sleep(1);break;
		default:break;
		}*/
		if (!IsAlive(head))
		{
			MessageBox(NULL,"Game Over!","提示",MB_OK);
			break;
		}
		if(IsEat(head,pfo))
		{
			score+=3;
			creatfood(head);
			gotoxy(MAXLEN+6+3,MAXLEN/4+1);
			color(0x0A);
			printf("%d",score);
			gotoxy(0,MAXLEN);
			color(0x07);
		}

	}
	return 0;
}