再写贪吃蛇--C语言

功能:

完成贪吃蛇自己找食物的功能----实现方法特别渣(和网上大神比起来根本不值一提)。

解决贪食蛇转弯--断身问题。

大概效果:

不足之处:没能解决蛇身和墙壁碰撞的问题。此外存在一个问题:程序执行一段时间之后会无故崩溃。

/*
 ============================================================================
 Name        : 0.c
 Author      : 陈致和
 Version     :
 Copyright   : 学习之用
 Description : Snake in C, Ansi-style
 ============================================================================
 */


#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>

/*全局变量*/
int flag = 1;//在初始位置绘制贪吃蛇的状态标志
int MapAndSnake[25][25] = { 0 };/*存储地图边界、贪吃蛇、食物----清零*/
int x = 0, y = 0;//食物坐标
char direction = 'A';//初始--向左
const	int nVirtKeyA = 65;/*A*/
const	int nVirtKeyD = 68;
const	int nVirtKeyS = 83;
const	int nVirtKeyW = 87;

int score;//分数
time_t mytime;//存活时间
int snakeLength = 2;//初始长度为2
time_t starttime;


typedef struct snake{
  int locationX;
  int locationY;
  struct snake *next;
}snake;
/*蛇头、蛇身指针*/
snake *phead,*pmove;
/*线程句柄*/
HANDLE threadOne;
/*函数预申明*/
void createFood();
void iniMap(int x, int y);
void reVector();
void reScore();
void exitGame();
DWORD WINAPI checkDirection(void *lpParameter);
void gamestart();
void checkCollide();

/*函数区*/
void printfmun() {
	int i, j;
	for (i = 0; i<25; i++)
	{
		for (j = 0; j<25; j++)
			printf("%d ", MapAndSnake[i][j]);
		printf("\n");
	}
}

void reScore() {
	time_t nowtime;
	time(&nowtime);
	mytime=nowtime-starttime;
	score=snakeLength*10;
	printf("当前分数为:%d\n",score);
	printf("你当前存活时间为: %d秒\n",mytime);
	printf("贪吃蛇长度:%d\n",snakeLength);
}
void exitGame() {
	printf("Game Over !");
	system("pause");
}
DWORD WINAPI checkDirection(void *lpParameter) {//按键检测函数*

			int key;
			key=getch();
			while(1){
			key=getch();
			if(key==nVirtKeyA)
			direction=(char)key;
			else if(key==nVirtKeyD)
			direction=(char)key;
			else if(key==nVirtKeyS)
			direction=(char)key;
			else if(key==nVirtKeyW)
			direction=(char)key;
			/*线程休息*/
				}



	 }
 void checkCollide(){
	if(x==phead->locationX && y==phead->locationY)//蛇头与食物正常碰撞
	{
		snakeLength++;
		switch(direction){
		  case 'A':{
		     pmove=phead;
		     phead=(snake *)malloc(sizeof(snake));
		     phead->locationX=x;
		     phead->locationY=y-1;
		     phead->next=pmove;

		    break;
		  }
		  case 'D':{
		     pmove=phead;
		     phead=(snake *)malloc(sizeof(snake));
		     phead->locationX=x;
		     phead->locationY=y+1;
		     phead->next=pmove;
		    break;
		  }
		  case 'S':{
		     pmove=phead;
		     phead=(snake *)malloc(sizeof(snake));
		     phead->locationX=x+1;
		     phead->locationY=y;
		     phead->next=pmove;
		    break;
		  }
		  case 'W':{
		     pmove=phead;
		     phead=(snake *)malloc(sizeof(snake));
		     phead->locationX=x-1;
		     phead->locationY=y;
		     phead->next=pmove;
		    break;
		  }

		}
		MapAndSnake[phead->locationX][phead->locationY]=3;

		/*检测是否碰到自己*/
		pmove=phead->next;
		while(pmove->next!=NULL)
		  {
		    if(phead->locationX==pmove->locationX &&
			phead->locationY==pmove->locationY)
		      exitGame();
		    else
		      pmove=pmove->next;
		  }
		    if(phead->locationX==pmove->locationX &&
			phead->locationY==pmove->locationY)
		      exitGame();
		    else
		      pmove=pmove->next;
		/*检测是否碰到墙壁*/
		 if(phead->locationY==24||
		     phead->locationX==24||
		     phead->locationX==0||
		     phead->locationY==0)
		exitGame();
		createFood();
	}


}
void reVector(){
				int time=100;//更新时间
							//更新二维数组值
					/*方向键*/
		    switch(direction){

						/*左右*/
						case 'A':{

						  pmove=phead;
						  phead=(snake *)malloc(sizeof(snake));
						  phead->next=pmove;
						  phead->locationX=phead->next->locationX;
						  phead->locationY=phead->next->locationY-1;

							break;
						}
						case 'D':{
						  pmove=phead;
						  phead=(snake *)malloc(sizeof(snake));
						  phead->next=pmove;
						  phead->locationX=phead->next->locationX;
						  phead->locationY=phead->next->locationY+1;

							break;
						}

						/*上下*/
						case 'S':{
							  pmove=phead;
							  phead=(snake *)malloc(sizeof(snake));
							  phead->next=pmove;
							  phead->locationX=phead->next->locationX+1;
							  phead->locationY=phead->next->locationY;
							break;
						}
						case 'W':{
						  pmove=phead;
						  phead=(snake *)malloc(sizeof(snake));
						  phead->next=pmove;
						  phead->locationX=phead->next->locationX-1;
						  phead->locationY=phead->next->locationY;
							break;
						}
					}
					MapAndSnake[phead->locationX][phead->locationY]=3;

					while(1){
					    if(pmove->next->next==NULL)
					    	  {
						MapAndSnake[pmove->next->locationX][pmove->next->locationY]=0;
						free(pmove->next->next);
					    	  pmove->next=NULL;
					    	  break;
					    		  }
					    else
					      pmove=pmove->next;

					}

					checkCollide();
					if(x!=0 && y!=0)//食物坐标不为零时刷新食物
					{
						MapAndSnake[x][y]=2;
					}
					checkRelative();
					Sleep(time);
 }

void checkRelative(){/*检测贪吃蛇与食物位置关系。。*/
  int relativeX,relativeY;
  relativeX=phead->locationX-x;relativeY=phead->locationY-y;
  if(relativeX>0){/*食物在蛇上方*/
      if(relativeY>0){/*食物在蛇左方*/
	  if(direction=='S'){
	      direction='A';
	  }
	  else
	    direction='W';
      }else if(relativeY<0){/*食物在蛇右方*/
	  if(direction=='S'){
	      direction='D';
	  }
	  else
	    direction='W';
      }else if(relativeY==0){/*食物和蛇一条线*/
	  if(x==1){/*躲避墙壁*/
	      direction='D';
	  }
	  else
	    direction='W';
      }
  }else if(relativeX<0){
      if(relativeY>0){
	  if(direction=='W'){
	      direction='A';
	  }
	  else
	    direction='S';
      }else if(relativeY<0){
	  if(direction=='W'){
	      direction='D';
	  }
	  else
	    direction='S';
      }else if(relativeY==0){
	      if(x==23){/*躲避墙壁*/
		  direction='A';
	      }
	      else
		direction='S';
      }

  }else if(relativeX==0){/*躲避墙壁*/
      if(relativeY>0){
	  if(y==1){
	      direction='S';
	  }
	  else
	    direction='A';
      }else if(relativeY<0){
	      if(y==23){
		  direction='W';
	      }
	      else
		direction='D';
      }else if(relativeY==0){
	  /*nothing*/
      }
  }
}
void createFood() {
													 /*随机产生食物坐标*/
int high = 23, low = 1;
srand(time(NULL));
x = rand() % (high - low + 1) + low;
y = rand() % (high - low + 1) + low;

	if(flag==1){
		iniMap(x, y);
		flag=0;
	}
	pmove=phead;
	while(1){

	    if(pmove->next!=NULL)
	       {
		if(pmove->locationX==x &&

	       	    	pmove->locationY==y)
	       	    	      {
	       		return createFood();
	       	    	      }
		 if(pmove->next->locationX==x &&
			pmove->next->locationY==y)
			return createFood();
	    	      pmove=pmove->next;
	       }
	     else
	       break;
	}



}
void iniMap(int x, int y) {

	/*初始化二维数组*/
	int i, j;
	for (i = 0; i<25; i++)
		for (j = 0; j<25; j++)
		{
			if (i == 0 || i == 24)
				MapAndSnake[i][j] = 1;
			else if (i>0 && i<25)
				if (j == 0 || j == 24)
					MapAndSnake[i][j] = 1;/*填充地图边界*/
				else if (x == i && y == j)
					MapAndSnake[x][y] = 2;/*填入食物*/
				else if (i == 23)
					if (j == 20 || j == 21)
						MapAndSnake[i][j] = 3;
		}
	/*生成蛇身*/
	  /*蛇头*/
	pmove=(snake *)malloc(sizeof(snake));
	phead=pmove;
	phead->locationX=23;
	phead->locationY=20;
	/*蛇尾*/
	pmove=(snake *)malloc(sizeof(snake));
	pmove->locationX=23;
	pmove->locationY=21;
	phead->next=pmove;
	pmove->next=NULL;

}





void gamestart( ) {//绘制地图、食物、贪吃蛇

	int i, j;
	while(1){
	    for (i = 0; i<25; i++)
	{
		for (j = 0; j<25; j++)
		{
			if (MapAndSnake[i][j] == 1
				 ||MapAndSnake[i][j] == 3)
				printf("■");
			else if(MapAndSnake[i][j] == 2)
			    printf("●");
			else
			    printf("  ");
		}
		printf("\n");
	}
	reScore();
	reVector();
	system("cls");//
	}
}
void welcome(){
      printf("                                欢迎来到贪吃蛇!!\n");
      system("pause");

}
int main() {
	welcome();
	/**键盘按键检测线程*/
	DWORD ThreadId;
	INT parameter;
	threadOne = CreateThread(NULL,
								0,
					checkDirection,
					¶meter,
						0,
					&ThreadId);
	/**/
	time(&starttime);
	createFood();
	gamestart();
	getchar();
	return 0;
}


posted @ 2020-01-14 19:35  秋风不识春  阅读(121)  评论(0编辑  收藏  举报