#include
#include
#include
#include
#include
#include
#pragma warning(disable:4996)
#define S 200
//定位坐标
void gotoxy(int x, int y)
{
COORD pos;
pos.X = x - 1;
pos.Y = y - 1;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
//蛇的一个节点
typedef struct SNAKE
{
int x; //使用横坐标
int y; //使用纵坐标
struct SNAKE *next;
}snake;
//需要的函数
void show(void); //主界面
void tail(void); //输出蛇
void game(void); //开始游戏
void esc_key(void); //按ESC键退出
void up(void); //按向上键
void down(void); //按向下键
void left(void); //按向左键
void right(void); //按向右键
void out(void); //过界
void out_tail(void); //碰到蛇身
void out_food(void); //食物
//需要的全局变量
snake *head; //蛇头
int score = 0; //分数
char game_key; //游戏接收用户输入指令
snake *p; //遍历蛇移动
snake *next_head; //蛇移动时分配新蛇头
int m, n; //食物坐标
char food = '@'; //食物图标
int main(void)
{
score = 0;
show();
tail(); //打印蛇身
game();
system("pause");
return 0;
}
//主界面
void show(void)
{
int i;
for (i = 1; i < 58; i += 2) //打印上下边框
{
gotoxy(i, 1);
printf("■");
gotoxy(i, 24);
printf("■");
}
for (i = 1; i < 24; i++) //打印左右边框
{
gotoxy(1, i);
printf("■");
gotoxy(57, i);
printf("■");
}
//打印辅助信息
gotoxy(65, 5);
printf("欢迎来到贪吃蛇!");
gotoxy(65, 10);
printf("得分:");
gotoxy(65, 15);
printf("游戏说明: 按任意开始,按回车键暂停,按ESC键退出游戏.");
gotoxy(75, 17);
printf("使用W,S,A,D键控制上下左右移动.");
gotoxy(75, 19);
printf("吃一食物得1分,不可过界,不可撞自己.");
gotoxy(65, 23);
printf("作者:完美教父");
}
//输出蛇身
void tail(void)
{
int i; //循环变量
snake *tail;
tail = (snake *)malloc(sizeof(snake)); //分配地址,定义蛇尾坐标
tail->x = 23;
tail->y = 5;
tail->next = NULL;
for (i = 1; i <= 4; i++) //遍历增加蛇头
{
head = (snake *)malloc(sizeof(snake)); //分配地址,定义一个蛇头坐标
head->next = tail; //将蛇头链接蛇尾
head->x = 23 + 2 * i; //定义蛇头X坐标
head->y = 5; //定义蛇头Y坐标
tail = head; //蛇头链接完蛇尾后,将原蛇尾赋给蛇头,以便下次循环,创建了新的蛇头坐标,它就做为蛇身使用
}
for (i = 0; i <= 4; i++) //遍历打印出蛇身
{
gotoxy(tail->x, tail->y);
printf("■");
tail = tail->next;
}
}
//开始游戏
void game(void)
{
game_key = getch();
if (game_key == 27) //当按ESC键出现退出选单
{
esc_key();
}
out_food(); //随机出现食物
while(1)
{
Sleep(S); //移动速度
gotoxy(65, 10);
printf("得分:%d", score);
if (kbhit())
{
game_key = getch();
if (game_key == 27)
{
esc_key();
}
else if (game_key == 13)
{
gotoxy(22, 22);
printf("游戏暂停,请按任意键继续!");
getch();
gotoxy(22, 22);
printf(" ");
}
else if (game_key == 'w' || game_key == 'W')
{
up();
}
else if (game_key == 's' || game_key == 'S')
{
down();
}
}
out(); //判断过界
out_tail(); //碰到蛇身
next_head = (snake *)malloc(sizeof(snake)); //分配移动时临时新蛇头
next_head->next = head; //将新蛇头的尾指向现有蛇头
next_head->x = head->x + 2; //初始化新蛇头横坐标
next_head->y = head->y; //初始化新蛇头纵坐标
head = next_head; //将head赋给新蛇头
gotoxy(head->x, head->y);
printf("■");
if (head->x == m && head->y == n) //如果吃到食物,重新输出食物,并且分数加1
{
out_food();
score++;
}
else
{
p = head;
while (p->next->next != NULL) //遍历处理向前移动时删除尾部
{
p = p->next;
}
gotoxy(p->next->x, p->next->y);
printf(" ");
free(p->next); //释放尾节点
p->next = NULL; //新尾节点next指向NULL
}
}
}
//按ESC键退出
void esc_key(void)
{
char esc_k;
//int esc_z; //返回值
gotoxy(22, 22);
printf("是否退出游戏(Y/N)!");
esc_k = getch(); //接收用户输入确认指令(Y/N)
if (esc_k == 'y' || esc_k == 'Y')
{
exit(1); //当用户按y/Y esc_z返回1
}
else if (esc_k == 'n' || esc_k == 'N')
{
gotoxy(22, 22);
printf(" ");
}
else
{
gotoxy(22, 22);
printf("输入有误,按任意键回到游戏!");
getch();
gotoxy(22, 22);
printf(" ");
}
}
//按向上键
void up(void)
{
while (1)
{
Sleep(S);
gotoxy(65, 10);
printf("得分:%d", score);
if (kbhit())
{
game_key = getch();
if (game_key == 27)
{
esc_key();
}
else if (game_key == 13)
{
gotoxy(22, 22);
printf("游戏暂停,请按任意键继续!");
getch();
gotoxy(22, 22);
printf(" ");
}
else if (game_key == 'a' || game_key == 'A')
{
left();
}
else if (game_key == 'd' || game_key == 'D')
{
right();
}
}
out();
out_tail(); //碰到蛇身
next_head = (snake *)malloc(sizeof(snake)); //分配移动时临时新蛇头
next_head->next = head; //将新蛇头的尾指向现有蛇头
next_head->x = head->x; //初始化新蛇头横坐标
next_head->y = head->y - 1; //初始化新蛇头纵坐标
head = next_head; //将head赋给新蛇头
gotoxy(head->x, head->y);
printf("■");
if (head->x == m && head->y == n)
{
out_food();
score++;
}
else
{
p = head;
while (p->next->next != NULL) //遍历处理向前移动时删除尾部
{
p = p->next;
}
gotoxy(p->next->x, p->next->y);
printf(" ");
free(p->next); //释放尾节点
p->next = NULL; //新尾节点next指向NULL
}
}
}
//按向下键
void down(void)
{
while (1)
{
Sleep(S);
gotoxy(65, 10);
printf("得分:%d", score);
if (kbhit())
{
if (kbhit())
{
game_key = getch();
if (game_key == 27)
{
esc_key();
}
else if (game_key == 13)
{
gotoxy(22, 22);
printf("游戏暂停,请按任意键继续!");
getch();
gotoxy(22, 22);
printf(" ");
}
else if (game_key == 'a' || game_key == 'A')
{
left();
}
else if (game_key == 'd' || game_key == 'D')
{
right();
}
}
}
out();
out_tail(); //碰到蛇身
next_head = (snake *)malloc(sizeof(snake)); //分配移动时临时新蛇头
next_head->next = head; //将新蛇头的尾指向现有蛇头
next_head->x = head->x; //初始化新蛇头横坐标
next_head->y = head->y + 1; //初始化新蛇头纵坐标
head = next_head; //将head赋给新蛇头
gotoxy(head->x, head->y);
printf("■");
if (head->x == m && head->y == n)
{
out_food();
score++;
}
else
{
p = head;
while (p->next->next != NULL) //遍历处理向前移动时删除尾部
{
p = p->next;
}
gotoxy(p->next->x, p->next->y);
printf(" ");
free(p->next); //释放尾节点
p->next = NULL; //新尾节点next指向NULL
}
}
}
//按向左键
void left(void)
{
while (1)
{
Sleep(S);
gotoxy(65, 10);
printf("得分:%d", score);
if (kbhit())
{
game_key = getch();
if (game_key == 27)
{
esc_key();
}
else if (game_key == 13)
{
gotoxy(22, 22);
printf("游戏暂停,请按任意键继续!");
getch();
gotoxy(22, 22);
printf(" ");
}
else if (game_key == 'w' || game_key == 'W')
{
up();
}
else if (game_key == 's' || game_key == 'S')
{
down();
}
}
out(); //过界
out_tail(); //碰到蛇身
next_head = (snake *)malloc(sizeof(snake)); //分配移动时临时新蛇头
next_head->next = head; //将新蛇头的尾指向现有蛇头
next_head->x = head->x - 2; //初始化新蛇头横坐标
next_head->y = head->y; //初始化新蛇头纵坐标
head = next_head; //将head赋给新蛇头
gotoxy(head->x, head->y);
printf("■");
if (head->x == m && head->y == n)
{
out_food();
score++;
}
else
{
p = head;
while (p->next->next != NULL) //遍历处理向前移动时删除尾部
{
p = p->next;
}
gotoxy(p->next->x, p->next->y);
printf(" ");
free(p->next); //释放尾节点
p->next = NULL; //新尾节点next指向NULL
}
}
}
//按向右键
void right(void)
{
while (1)
{
Sleep(S);
gotoxy(65, 10);
printf("得分:%d", score);
if (kbhit())
{
game_key = getch();
if (game_key == 27)
{
esc_key();
}
else if (game_key == 13)
{
gotoxy(22, 22);
printf("游戏暂停,请按任意键继续!");
getch();
gotoxy(22, 22);
printf(" ");
}
else if (game_key == 'w' || game_key == 'W')
{
up();
}
else if (game_key == 's' || game_key == 'S')
{
down();
}
}
out(); //过界
out_tail(); //碰到蛇身
next_head = (snake *)malloc(sizeof(snake)); //分配移动时临时新蛇头
next_head->next = head; //将新蛇头的尾指向现有蛇头
next_head->x = head->x + 2; //初始化新蛇头横坐标
next_head->y = head->y; //初始化新蛇头纵坐标
head = next_head; //将head赋给新蛇头
gotoxy(head->x, head->y);
printf("■");
if (head->x == m && head->y == n)
{
out_food();
score++;
}
else
{
p = head;
while (p->next->next != NULL) //遍历处理向前移动时删除尾部
{
p = p->next;
}
gotoxy(p->next->x, p->next->y);
printf(" ");
free(p->next); //释放尾节点
p->next = NULL; //新尾节点next指向NULL
}
}
}
//过界
void out(void)
{
if (head->x == 57 || head->x == 1 || head->y ==1 || head->y == 24)
{
gotoxy(22, 22);
printf("过界了!!!按任意键重新游戏!");
getch();
system("cls");
main();
}
}
//碰到蛇身
void out_tail(void)
{
snake *p;
p = head;
while (p->next != NULL)
{
if (head->x == p->next->x && head->y == p->next->y)
{
gotoxy(22, 22);
printf("碰到蛇身!!!按任意键重新游戏");
getch();
system("cls");
main();
}
p = p->next;
}
}
//食物
void out_food(void)
{
snake *p;
p = head;
m = rand() % 52 + 4;
n = rand() % 20 + 4;
if (m % 2 == 0)
{
m += 1;
}
while (p->next != NULL)
{
if (p->x == m && p->y == n)
{
out_food();
}
p = p->next;
}
gotoxy(m, n);
printf("%c", food);
}