先将代码写一下后边有空我会再加一些注释与图解:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#define FOOD "□"
#define program warning (disable:4013) //#pragram warning(disable:4786)
void SetPos(int x, int y) //光标设置位置
{
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//在msdn中查找
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(hOutput, pos);
}
void CreateMap(void) //贪吃蛇的边框 横向的
{
int i;
SetPos(0, 0);
for (i = 0; i < 58; i += 2){
SetPos(i, 0);
printf(FOOD); //setpos 在MSDN上查找
SetPos(i,26);
printf(FOOD);
}
for (i = 1; i < 26; i++)
{
SetPos(0, i);
printf(FOOD);
SetPos(56, i);
printf(FOOD);
}
}
//蛇的身体节点
typedef struct node_{
int x;
int y;
struct node_ *next; //蛇的下一个节点
} SnakeNode, *pSnakeNode;
enum DIRECTION{UP,LEFT,RIGHT,DOWN}; //枚举上下左右
enum GAME_STATUS{ //枚举蛇的状态
OK, //正常
KILL_BY_SELF, //咬死自己
KILL_BY_WALL, //撞死自己
KILL_NORMAL //正常死亡
};
typedef struct Snake{
pSnakeNode _pSnake; //维护整条蛇
pSnakeNode _pFood; //食物
enum DIRECTION _Dir; //蛇的运动方向
int _SleepTime; //每走一步休息的时间
enum GAME_STATUS _Status; //游戏状态
} Snake, *pSnake;
#define INIT_X 24
#define INIT_Y 5
void InitSnake(pSnake ps)
{
pSnakeNode cur = NULL;
cur = malloc(sizeof(SnakeNode));
cur->x = INIT_X;
cur->y = INIT_Y;
cur->next = NULL;
for (int i = 1; i <=4; i++) //链表的头插法
{
ps->_pSnake = malloc(sizeof(SnakeNode));
ps->_pSnake->next = cur;
ps->_pSnake->x = INIT_X + 2 * i;
ps->_pSnake->y = INIT_Y;
cur = ps->_pSnake;
}
while (cur!=NULL)
{
SetPos(cur->x, cur->y);
printf(FOOD);
cur = cur->next;
}
// printf("\n");
ps->_Dir = RIGHT;
ps->_SleepTime = 100; //贪吃蛇的速度
ps->_Status = OK; //食物比较特殊
}
void CreatFood(pSnake ps) //食物单独定义
{
pSnakeNode pFood = NULL;
pSnakeNode cur = NULL;
pFood = malloc(sizeof(SnakeNode));
Again:
cur = ps->_pSnake;
do
{
pFood->x = rand() % 53 + 2;
} while (pFood->x%2!=0);
pFood->y = rand() % 25 + 1;
while (cur!=NULL)
{
if (cur->x == pFood->x&&cur->y == pFood->y)
goto Again;
cur = cur->next;
}
SetPos(pFood->x, pFood->y);
printf(FOOD);
ps->_pFood = pFood;
}
void Welcome(void)
{
system("mode con: cols=100 lines=30"); //改变黑框的尺寸
SetPos(20, 5);
printf("欢迎来到狗子贪吃蛇");
SetPos(20, 10);
printf("↑,↓,←,→控制方向\n");
system("pause");
system("cls"); //简写
}
void GameStart(pSnake ps)
{
Welcome();
srand(time(NULL)); //随机数的种子
CreateMap();
InitSnake(ps);
CreatFood(ps); //CreatFood
}
int NextHasFood(pSnakeNode psn,pSnake ps)
{
return psn->x == ps->_pFood->x&&
psn->y == ps->_pFood->y;
}
void EatFood(pSnakeNode psn, pSnake ps) //蛇吃食物的过程
{
pSnakeNode cur = NULL;
psn->next = ps->_pSnake;
ps->_pSnake = psn;
cur = ps->_pSnake;
while (cur!=NULL)
{
SetPos(cur->x, cur->y);
printf(FOOD);
cur = cur->next;
}
CreatFood(ps);
}
void NoFood(pSnakeNode psn, pSnake ps) //没有食物
{
//pSnakeNode cur = ps->_pSnake;
//psn->next = ps->_pSnake;
//ps->_pSnake = psn;
//cur = ps->_pSnake;
pSnakeNode cur = psn;
psn->next = ps->_pSnake;
ps->_pSnake = psn;
while (cur->next->next!=NULL)
{
SetPos(cur->x, cur->y);
printf(FOOD);
cur = cur->next;
}
SetPos(cur->next->x, cur->next->y);
printf(" "); //此处要注意是两个空格 一个占两个字节
free(cur->next);
cur->next = NULL;
}
void SnakeMove(pSnake ps) //蛇的移动
{
pSnakeNode nextNode = malloc(sizeof(SnakeNode));
nextNode->x = ps->_pSnake->x;
nextNode->y = ps->_pSnake->y;
switch (ps->_Dir)
{
case UP:
nextNode->y -= 1;
break;
case DOWN:
nextNode->y += 1;
break;
case LEFT:
nextNode->x -= 2;
break;
case RIGHT:
nextNode->x += 2;
break;
default:
break;
}
if (NextHasFood(nextNode, ps))
EatFood(nextNode, ps);
else
NoFood(nextNode, ps);
}
int KillByWall(pSnake ps) //判断撞墙
{
if (ps->_pSnake->x == 0 || ps->_pSnake->x == 56||
ps->_pSnake->y==0||ps->_pSnake->y==26){
ps->_Status = KILL_BY_WALL;
return 1;
}
return 0;
}
int KillBySelf(pSnake ps) //多等号 //判断咬死自己
{
pSnakeNode cur = ps->_pSnake->next;
while (cur!=NULL)
{
if (cur->x==ps->_pSnake->x&&cur->y==ps->_pSnake->y)
{
ps->_Status = KILL_BY_SELF;
return 1;
}
cur = cur->next;
}
return 0;
}
void GameRun(pSnake ps) //此处要用一个函数将键盘上的按键输入进去
{
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;
SnakeMove(ps);
//if(KillByWall(ps)==1)
// break;
//if (KillBySelf(ps) == 1)
// break;
KillByWall(ps);
KillBySelf(ps);
Sleep(ps->_SleepTime);
} while (ps->_Status==OK);
if (ps->_Status == KILL_BY_SELF)
{
printf("你要咬了自己\n");
}
else if (ps->_Status == KILL_BY_WALL){
printf("你撞墙了\n");
}
}
int main(void)
{
Snake s;
GameStart(&s);
GameRun(&s);
//while (1)
//{
// SnakeMove(&s);
// Sleep(1000);
//}
//printf("\n");
system("pause");
return 0;
}