zoukankan      html  css  js  c++  java
  • 再写贪吃蛇--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("
    ");
    	}
    }
    
    void reScore() {
    	time_t nowtime;
    	time(&nowtime);
    	mytime=nowtime-starttime;
    	score=snakeLength*10;
    	printf("当前分数为:%d
    ",score);
    	printf("你当前存活时间为: %d秒
    ",mytime);
    	printf("贪吃蛇长度:%d
    ",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("
    ");
    	}
    	reScore();
    	reVector();
    	system("cls");//
    	}
    }
    void welcome(){
          printf("                                欢迎来到贪吃蛇!!
    ");
          system("pause");
    
    }
    int main() {
    	welcome();
    	/**键盘按键检测线程*/
    	DWORD ThreadId;
    	INT parameter;
    	threadOne = CreateThread(NULL,
    								0,
    					checkDirection,
    					¶meter,
    						0,
    					&ThreadId);
    	/**/
    	time(&starttime);
    	createFood();
    	gamestart();
    	getchar();
    	return 0;
    }
    
    

  • 相关阅读:
    单例模式的三种写法
    ASP.NET如何下载大文件
    字符串是引用类型
    SQL 事务隔离级别
    Sql Server 锁
    设非主键为聚集索引
    C#如何使用SqlCacheDependency
    简易系统后台架构
    matlab cross 3*1 向量叉乘
    Matlab求齐次方程的解
  • 原文地址:https://www.cnblogs.com/deciduousmap/p/12193730.html
Copyright © 2011-2022 走看看