#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<windows.h>
#include<stdlib.h>
#include<conio.h>
#define _wide 51
#define _high 25
typedef struct Snake
{
int x;
int y;
struct Snake* nest;
}S;//蛇
typedef struct Food
{
int _x;
int _y;
}F;//食物
void catprint();//游戏目录
void gotoxy(int x,int y);//自定义坐标函数
void printxy(int x,int y);//打印坐标
void gameface(S* s);//游戏界面打印 25*50
F setfood(F* f);//食物的生成
void foodprint(int x,int y);//食物的打印
S* setnode(int x,int y);//节点创造
void headpush(S** s, int x, int y);//头部插入数据
void spush(S* s,int i,int j);//尾部插入一个数据
void snakeprint(S* s);//打印贪吃蛇
void snakenodeprint(int i,int j);//蛇节点的打印
void destory(S** s);//内存清理
void movesnakehead(S* s,F f);//贪吃蛇头的移动
int issnakeeatfood(S s,F f);//蛇吃食物的判断
int newfood(int key);//吃到食物后食物消失,生成新食物
void newsnake(S* s,F f);//吃到食物后蛇的变化
void addsnake(S* s);//生成蛇节点
void movesnake(S* s,int x, int y);//贪吃蛇的移动
void snakeheadprint(int x,int y);//蛇头打印
int foodinsnake(S* s,F f);//食物在蛇身上
int headtouchtail(S* s);//吃到自己
void catprint()//游戏目录
{
int i;
do
{
printf("----------------------------------\n");
printf("-----------1.start game-----------\n");
printf("-----------0.quit game------------\n");
printf("----------------------------------\n");
scanf_s("%d",&i);
if (i != 1 && i != 0)
{
printf("-----------input error,again----- \n");
continue;
}
if (i == 1)
{
system("cls");
break;
}
if (i == 0)
{
exit(0);
}
} while (1);
}
void gotoxy(int x, int y)//自定义坐标函数
{
COORD p;
p.X = x;
p.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),p);
}
void printxy(int x, int y)//打印坐标
{
gotoxy(x, y);
printf("*");
}
void gameface(S* s)//游戏界面打印 25*50
{
assert(s);
for (int i = 0; i < _wide; i+=2)
{
printxy(i,0);
}
for (int j = 1; j < _high - 1; j++)
{
printxy(0,j);
}
for (int j = 1; j < _high - 1; j++)
{
printxy(_wide-1, j);
}
for (int i = 0; i < _wide; i+=2)
{
printxy(i, _high-1);
}
snakeprint(s);
}
F setfood(F* f)//食物的生成
{
assert(f);
int x = (rand() % ((_wide-1)/2) < 4 ? 4:2*(rand() % ((_wide - 1) / 2)));
int y = (rand() % (_high - 1) <2 ? 2 : rand() % (_high - 1));
Sleep(1);
foodprint(x,y);
f->_x = x;
f->_y = y;
return *f;
}
void foodprint(int x, int y)//食物的打印
{
gotoxy(x, y);
printf("❤️");
}
S* setnode(int i, int j)//节点创造
{
S* newnode = (S*)malloc(sizeof(S));
if (newnode != NULL)
{
assert(newnode);
newnode->x = i;
newnode->y = j;
newnode->nest = NULL;
}
return newnode;
}
void headpush(S** s, int x, int y)//头部插入数据
{
assert(s);
(*s) = setnode(x, y);
}
void spush(S* s, int i, int j)//尾部插入一个数据
{
assert(s);
while (s->nest != NULL)
{
s = s->nest;
}
if (s != NULL)
{
s->nest = setnode(i, j);
}
}
void snakeprint(S* s)//打印贪吃蛇
{
assert(s);
snakeheadprint(s->x,s->y);
s = s->nest;
while (s != NULL)
{
snakenodeprint(s->x, s->y);
s = s->nest;
}
}
void snakenodeprint(int i, int j)//蛇节点的打印
{
gotoxy(i, j);
printf("💕");
}
void destory(S** s)//内存清理
{
assert(s);
assert((*s));
if ((*s) == NULL)
{
exit(-1);
}
while ((*s)->nest != NULL)
{
S* cur = (*s)->nest;
free((*s));
(*s) = NULL;
}
free((*s));
}
int newfood(int key)//吃到食物后食物消失,生成新食物
{
if (key == 0)
{
return 0;
}
else
{
return 1;
}
}
int issnakeeatfood(S s, F f)//蛇吃食物的判断
{
if (s.x == f._x && s.y == f._y)
{
return 1;
}
else
{
return 0;
}
}
void movesnakehead(S* s,F f)//贪吃蛇头的移动
{
assert(s);
char key = 'a';
while (key =='a' || key == 's' || key == 'w' || key == 'd')
{
int X = s->x;
int Y = s->y;
key = _getch();
switch (key)
{
case'a':
{
s->x-=2;
if (s->x == 0)
{
system("cls");
printf("game over");
destory(&s);
exit(-1);
}
break;
}
case's':
{
s->y++;
if (s->y == (_high-1))
{
system("cls");
printf("game over");
destory(&s);
exit(-1);
}
break;
}
case'd':
{
s->x+=2;
if (s->x == (_wide-1))
{
system("cls");
printf("game over");
destory(&s);
exit(-1);
}
break;
}
case'w':
{
s->y--;
if (s->y == 0)
{
system("cls");
printf("game over");
destory(&s);
exit(-1);
}
break;
}
case'p':
{
system("cls");
printf("quit game");
destory(&s);
exit(0);
}
}
if (headtouchtail(s))
{
system("cls");
printf("game over");
exit(-1);
}
movesnake(s, X, Y);//贪吃蛇的移动
system("cls");
if (foodinsnake(s, f))
{
newsnake(s, f);//蛇的变化
return;
}
if (newfood(issnakeeatfood((*s), f)))//蛇吃食物的判断及食物的新变化
{
newsnake(s,f);//蛇的变化
return;
}
system("cls");
gameface(s);//游戏界面打印 25*50
foodprint(f._x,f._y);//打印食物
}
}
void newsnake(S* s,F f)//吃到食物后蛇的变化
{
assert(s);
spush(s,f._x,f._y);
addsnake(s);
}
void addsnake(S* s)//生成蛇节点
{
assert(s);
while (s->nest->nest != NULL)
{
s = s->nest;
}
if (s->x - 1 == 0 && s->y + 1 == _high-1)
{
s->nest->x = s->x;
s->nest->y = s->y - 1;
}
else if (s->x + 1 == _wide-1 && s->y + 1 == _high-1)
{
s->nest->x = s->x;
s->nest->y = s->y - 1;
}
else if (s->x - 1 == 0 && s->y - 1 == 0)
{
s->nest->x = s->x + 1;
s->nest->y = s->y;
}
else if (s->x + 1 == _wide-1 && s->y - 1 == 0)
{
s->nest->x = s->x - 1;
s->nest->y = s->y;
}
else
{
s->nest->x = s->x;
s->nest->y = s->y-1;
}
}
void movesnake(S* s,int x,int y)//贪吃蛇的移动
{
while (s->nest != NULL)
{
int tmpx = s->nest->x;
int tmpy = s->nest->y;
s->nest->x = x;
s->nest->y = y;
x = tmpx;
y = tmpy;
s = s->nest;
}
}
void snakeheadprint(int x, int y)//蛇头打印
{
gotoxy(x, y);
printf("🐍");
}
int foodinsnake(S* s, F f)//食物在蛇身上
{
assert(s);
while (s != NULL)
{
if (s->x == f._x && s->y == f._y)
{
return 1;
}
s = s->nest;
}
return 0;
}
int headtouchtail(S* s)//吃到自己
{
int _x = s->x;
int _y = s->y;
s = s->nest;
while(s != NULL)
{
if (_x == s->x && _y == s->y)
{
return 1;
}
s = s->nest;
}
return 0;
}
void test()
{
F food = {0,0};
struct Snake* snake = NULL ;
headpush(&snake,2,2);//初始化贪吃蛇
catprint();//目录打印
while(1)
{
gameface(snake);//游戏界面打印 25*50
F food1 = setfood(&food);//食物的生成
movesnakehead(snake,food1);//控制贪吃蛇头的移动
}
}
int main()
{
test();
return 0;
}
函数封装已做好,大家可以拿去去体验这个游戏