简单贪吃蛇

snack.h

#ifndef __SNAKE_H__
#define __SNAKE_H__

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

enum Direction
{
   UP = 1,
   DOWN,
   LEFT,
   RIGHT

};

enum GameStatus
{
   OK,//正常运行
   NORMAL_END,//正常结束
   KILL_BY_WALL,//撞墙
   KILL_BY_SELF//咬到自己

};

#define WALL "■"
#define FOOD "●"

#define INIT_X 20
#define INIT_Y 10
typedef struct SnakeNode
{
   int x;
   int y;
   struct SnakeNode* next;
}SnakeNode,*pSnakeNode;

typedef struct Snake
{
  pSnakeNode _psnake;//维护蛇身的指针
  pSnakeNode _pFood;//维护食物的位置
  int _TotaiScore; //总分数
  int _AddScore; //增加的分数
  int _SleepTime; //休眠时间
  enum Direction _Dir;
  enum GameStatus _Status;
}
Snake,*pSnake;

void WelcomeToGame();
void CreateMap();
void initSnake(pSnake ps);
void CreateFood(pSnake ps);
void GameStart(pSnake ps);
void SetPos(int x, int y);
void GameRun(pSnake ps);
void GameEnd(pSnake ps);
void SnakeMove(pSnake ps);
void PrintHelpInfo();
void KillByWall();
void KillBySelf();






#endif //__SNAKE_H__

snack.c

#include "snake.h"

void WelcomeToGame()
{
   
    SetPos(38,15);
	printf("欢迎来到贪吃蛇小游戏");
	SetPos(38,28);
	system("pause"); //暂停界面
    system("cls"); //清屏
	SetPos(20,15);
	printf("用↑.↓.←.→分别控制蛇的移动, F1为加速键, F2为减速键");
	SetPos(38,28);
	system("pause"); 
    system("cls");

}
void SetPos(int x, int y)
{
	COORD pos = {0};
	HANDLE handle = 0;
	handle = GetStdHandle (STD_OUTPUT_HANDLE );
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle,pos);
}
void CreateMap()
{
   int i = 0;
   //上 
   for(i=0 ; i<=58; i+=2)   
	   printf(WALL);  
   //下
   SetPos(0,26);
   for(i=0 ; i<=58; i+=2)	   
	   printf(WALL);       
   //左
   for(i=1 ; i<=25; i++)
   {
	   SetPos(0,i);
	   printf(WALL);      
   }
   //右
   for(i=1 ; i<=25; i++)
   {
	   SetPos(58,i);
	   printf(WALL);
       
   }
}
pSnakeNode BuySnakeNode()
{
	pSnakeNode  p; 
	p = (pSnakeNode)malloc(sizeof(SnakeNode));
	if(p == NULL)
	{
	   printf("申请失败\n");
	   return NULL;
	}
	else
		return p;
   
}

void initSnake(pSnake ps)
{
   pSnakeNode cur = NULL;
   int i = 0;
   cur = BuySnakeNode();
   cur->x  = INIT_X;
   cur->y  = INIT_Y;
   cur->next = NULL;
  //蛇身初始长度为5
   for(i=1;i<5;i++)
   {
     ps->_psnake = BuySnakeNode();
	 ps->_psnake ->next = cur;
	 ps->_psnake ->x = INIT_X+2*i;
	 ps->_psnake ->y = INIT_Y;
	 cur = ps->_psnake;
   }

   while(cur)
   {
      SetPos(cur->x ,cur->y );
	  printf(FOOD);
	  cur = cur->next;
   }
     SetPos(38,27);
	 
}
void CreateFood(pSnake ps)
{
  pSnakeNode pFood = NULL; //维护食物的节点
  pSnakeNode cur = NULL; //指向蛇头节点
  pFood = BuySnakeNode();
  cur = ps->_psnake;
  do{//产生的x坐标应该为2的倍数,这样才可能和蛇头坐标对齐
	  pFood->x = rand()%55+2;
      
  }while(pFood->x %2 != 0);
  pFood->y = rand()%25+1;

  while(cur != NULL)
  {
	  if(cur->x  == pFood->x && cur->y == pFood->y)
	  {
		  CreateFood(ps);
	      return;
	  }
	  else
		  cur = cur->next;
 }

  ps->_pFood = pFood;
  SetPos(pFood->x ,pFood->y);
  printf(FOOD); 
  Sleep(100);
  SetPos(38,27);
}

void Pause()
{
  while(1)
  {
    Sleep(100);
	if(GetAsyncKeyState(VK_SPACE))
	{
	break;
	}
  }

}
void KillByWall(pSnake ps)
{	
	//上
	if(ps->_psnake->y == 0)
		ps->_Status = KILL_BY_WALL;
	//下
	if(ps->_psnake->y == 26)
		ps->_Status = KILL_BY_WALL;
	//左
	if(ps->_psnake->x == 0 )
		ps->_Status = KILL_BY_WALL;
	//右
	if(ps->_psnake->x == 58)
		ps->_Status = KILL_BY_WALL;
	
}
void KillBySelf(pSnake ps)
{
   pSnakeNode cur = NULL;
   cur = ps->_psnake;
   while(cur->next)
   {
   if(ps->_psnake->x == cur->next->x && ps->_psnake->y == cur->next->y)
    {
	  ps->_Status = KILL_BY_SELF;
    }
      cur = cur->next;
   }
  
}

void GameRun(pSnake ps)
{
	PrintHelpInfo();
 do
 {
   if(GetAsyncKeyState(VK_UP) && ps->_Dir != DOWN)
   {
	   ps->_Dir = UP;
   }
   if(GetAsyncKeyState(VK_DOWN) && ps->_Dir != UP)
   {
	   ps->_Dir = DOWN;
   } 
   if(GetAsyncKeyState(VK_LEFT) && ps->_Dir != RIGHT)
   {
	   ps->_Dir = LEFT;
   } 
   if(GetAsyncKeyState(VK_RIGHT) && ps->_Dir != LEFT)
   {
	   ps->_Dir = RIGHT;
   }
   if(GetAsyncKeyState(VK_SPACE))
   {
	 //暂停游戏
	   Pause();
   }
   if(GetAsyncKeyState(VK_ESCAPE))
   {
	  //结束游戏
	   ps->_Status = NORMAL_END;
   }
   if(GetAsyncKeyState(VK_F1))
   {
	   //加速
	   if(ps->_SleepTime >=40)
	   {
	   ps->_SleepTime -= 20;
	   ps->_AddScore += 2;
	   }
   }
   if(GetAsyncKeyState(VK_F2) )
   {
	  //减速
	   if(ps->_SleepTime <=300)
	   {
	   ps->_SleepTime += 20;
	   ps->_AddScore -= 2;
	   }
	   if(ps->_SleepTime > 300)
	   ps->_AddScore = 1;
   }
  Sleep(ps->_SleepTime);
  SnakeMove(ps);
  KillByWall(ps);
  KillBySelf(ps);
 }while(ps->_Status == OK);
   
}
int NextHasFood(pSnakeNode pn , pSnakeNode pf)
{
	return ((pn->x == pf->x) &&(pn->y == pf->y));

}
void NoFood( pSnake ps,pSnakeNode pn)
{
   pSnakeNode cur = NULL;
   pn->next = ps->_psnake;
   ps->_psnake  = pn; 
   //处理尾节点
   cur = ps->_psnake;
   while(cur->next->next)
   {
	   cur = cur->next;
   }
   SetPos(cur->next->x ,cur->next->y);
   printf(" ");
   free(cur->next);
   cur->next = NULL; 
   //打印新加入的节点
   SetPos(ps->_psnake->x,ps->_psnake->y);
   printf(FOOD);
}
void EatFood(pSnake ps,pSnakeNode pn)
{
   pn->next = ps->_psnake;
   ps->_psnake = pn;
   //打印新加的节点
   SetPos(ps->_psnake->x ,ps->_psnake->y);
   printf(FOOD);
   ps->_TotaiScore += ps->_AddScore;
   //创建新食物
   CreateFood(ps);

}
void SnakeMove(pSnake ps)  
{
	pSnakeNode pNextNode = BuySnakeNode();
	SetPos(60,10);
	printf("总分:%d ",ps->_TotaiScore);
	SetPos(60,11);
	printf("一个食物增加的分数:%d ",ps->_AddScore);
	switch(ps->_Dir)
	{
	case UP:{
		pNextNode->x = ps->_psnake->x;
		pNextNode->y = ps->_psnake->y-1;
		if(NextHasFood(pNextNode,ps->_pFood))
		{
			EatFood(ps,pNextNode);
		}
		else
		{
		    NoFood(ps,pNextNode);
		}

	}
	break;
	case DOWN:{
		pNextNode->x = ps->_psnake->x;
		pNextNode->y = ps->_psnake->y+1;
		if(NextHasFood(pNextNode,ps->_pFood))
		{
			EatFood(ps,pNextNode);
		}
		else
		{
		    NoFood(ps,pNextNode);
		}

	}
	break;
	case LEFT:{
		pNextNode->x = ps->_psnake->x-2;
		pNextNode->y = ps->_psnake->y;
		if(NextHasFood(pNextNode,ps->_pFood))
		{
			EatFood(ps,pNextNode);
		}
		else
		{
		    NoFood(ps,pNextNode);
		}

	}
	break;
	case RIGHT:{
		pNextNode->x = ps->_psnake->x+2;
		pNextNode->y = ps->_psnake->y;
		if(NextHasFood(pNextNode,ps->_pFood))
		{
			EatFood(ps,pNextNode);
		}
		else
		{
		    NoFood(ps,pNextNode);
		}

	}
	break;
	}

}
void PrintHelpInfo()
{
   SetPos(60,13);
   printf("用↑.↓.←.→分别控制蛇的移动");
   SetPos(60,14);
   printf("F1为加速键");
   SetPos(60,15);
   printf("F2为减速键");
   SetPos(60,16);
   printf("ESC为退出键");


}
void GameStart(pSnake ps)
{
	
	srand((unsigned int)time(NULL));
    system("mode con cols=100 lines=30");//设置窗口大小
    WelcomeToGame();
	CreateMap();
    initSnake(ps);
    CreateFood(ps);
    ps->_SleepTime = 200;
	ps->_TotaiScore  = 0;
    ps->_Dir = RIGHT;
	ps->_Status = OK;
	ps->_AddScore = 10;

}
void GameEnd(pSnake ps)
{
	pSnakeNode del = NULL;
	if(ps->_Status ==  NORMAL_END)
	{
	 SetPos(25,14);
	 printf("游戏结束");
	 SetPos(38,28);
	}
	if(ps->_Status == KILL_BY_SELF)
	{
	 SetPos(25,14);
	 printf("很遗憾,蛇咬死了自己");
	 SetPos(38,28);
	}
	else if(ps->_Status == KILL_BY_WALL)
	{
	 SetPos(25,14);
	 printf("很遗憾,蛇撞墙了");
	 SetPos(38,28);
	}
	while(ps->_psnake!=NULL)
	{
		del = ps->_psnake;
		ps->_psnake = ps->_psnake->next;
		free(del);
		del = NULL;
	}
}




test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "snake.h"

void test()
{	 
	 Snake p = {0};	 
	 GameStart(&p); 
 	 GameRun(&p);
	 GameEnd(&p);
	 
}

int main()
{
	test();
	return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值