#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
#include <easyx.h>
#define up 72
#define down 80
#define lift 75
#define right 77
int move = 72;
typedef struct ac
{
int x;
int y;
struct ac* next;
}LinkList;
LinkList* createLink();//创建链表
void create_food(int* position);//添加食物
void create(LinkList* head, int* end);//创建主角
LinkList* changeLink(LinkList* head, int* end, int nodemun);//根据运动情况,改变链表数据
void add_node(LinkList *head,int *nodemun,int *end);//吃到食物后添加节点
void print_score_grade(int nodemun, int grade);//打印等级和分数
void chose_speed(int nodemun);//根据等级选择蛇的移动速度
void create_map();//创建地图
void graph_thinks();
int check(LinkList *head,int nodemun);//检查游戏的运行的正确性
//==============================================================
LinkList* createLink()
{
LinkList* head;
head = (LinkList*)malloc(sizeof(struct ac));
if (head == NULL)
exit(0);
head->x = 250;
head->y = 250;
head->next = NULL;
return head;
}
void create_food(int* position)
{
int x, y;
srand(time(NULL));//种子
x = rand() % 49;//随机数确定食物位置
y = rand() % 39;
position[0] = x * 10;
position[1] = y * 10;
setfillcolor(RGB(0, 255, 255));//打印食物
solidrectangle(position[0], position[1], position[0] + 10, position[1] + 10);
}
void create(LinkList * head, int* end)
{
LinkList* p;
p = head;
setfillcolor(RGB(0, 255, 255));
while (p->next != NULL)
{
solidrectangle(p->x, p->y, p->x + 10, p->y + 10);
p = p->next;
}
solidrectangle(p->x, p->y, p->x + 10, p->y + 10);
if (end != NULL)//抹去上一个的蛇尾
{
setfillcolor(BLACK);
solidrectangle(end[0], end[1], end[0] + 10, end[1] + 10);
}
}
LinkList* changeLink(LinkList * head, int* end, int nodemun)
{
int i;
LinkList* new_node;
LinkList* current;
LinkList* p;
new_node = (LinkList *)malloc(sizeof(struct ac));
if (new_node == NULL)
exit(0);
current = head;
new_node->next = head;
while (current->next != NULL)//寻找蛇尾
{
current = current->next;
}
switch (move)//添加新的头节点,删除尾节点
{
case up:
new_node->x = head->x;
new_node->y = head->y - 10;
end[0] = current->x;
end[1] = current->y;
free(current);
current = NULL;
break;
case down:
new_node->x = head->x;
new_node->y = head->y + 10;
end[0] = current->x;
end[1] = current->y;
free(current);
current = NULL;
break;
case right:
new_node->x = head->x + 10;
new_node->y = head->y;
end[0] = current->x;
end[1] = current->y;
free(current);
current = NULL;
break;
case lift:
new_node->x = head->x - 10;
new_node->y = head->y;
end[0] = current->x;
end[1] = current->y;
free(current);
current = NULL;
break;
}
p = new_node;
for (i = 1; i < nodemun; i++)//寻找新的蛇尾
{
p = p->next;
}
p->next = NULL;//将新的尾节点指向NULL
return new_node;//返回新的头节点
}
void add_node(LinkList * head, int* nodemun,int *end)
{
int i = 1;
int tail[2], sec_tail[2];
LinkList* current;
LinkList* new_node;
new_node = (LinkList *)malloc(sizeof(struct ac));
if (new_node == NULL)
exit(0);
current = head;
if (*nodemun >1)//蛇有两个节点及以上
{
while (current->next != NULL)
{
if (i == *nodemun - 1)//寻找倒数第二个节点,并保存其值
{
sec_tail[0] = current->x;
sec_tail[1] = current->y;
current = current->next;
}
else
{
i++;
current = current->next;
}
}
tail[0] = current->x;
tail[1] = current->y;
//根据蛇尾运动方向添加节点
if (tail[0] > sec_tail[0])
{
end[0] = end[0] + 10;
new_node->x = current->x + 10;
new_node->y = current->y;
}
if (tail[0] < sec_tail[0])
{
end[0] = end[0] - 10;
new_node->x = current->x - 10;
new_node->y = current->y;
}
if (tail[1] > sec_tail[1])
{
end[1] = end[1] + 10;
new_node->x = current->x;
new_node->y = current->y + 10;
}
if (tail[1] < sec_tail[1])
{
end[1] = end[1] - 10;
new_node->x = current->x;
new_node->y = current->y - 10;
}
}
if (*nodemun == 1)//蛇只有一个节点
{
switch (move)
{
case up:
end[1] = end[1] + 10;
new_node->x = current->x;
new_node->y = current->y + 10; break;
case down:
end[1] = end[1] - 10;
new_node->x = current->x;
new_node->y = current->y - 10; break;
case right:
end[0] = end[0] - 10;
new_node->x = current->x - 10;
new_node->y = current->y; break;
case lift:
end[0] = end[0] + 10;
new_node->x = current->x + 10;
new_node->y = current->y; break;
}
}
new_node->next = NULL;
current->next = new_node;
*nodemun = *nodemun+1;
}
void print_score_grade(int nodemun,int grade)
{
wchar_t ch[5];//宽字节
wchar_t ch2[2];
setbkmode(TRANSPARENT);//设置背景模式
settextcolor(RGB(0, 255, 255));
settextstyle(20, 0, _T("宋体"));
setfillcolor(BLACK);
solidrectangle(580, 150, 700, 170);
solidrectangle(580, 100, 700, 120);
swprintf(ch,5, _T("%d"), nodemun *10-10);
swprintf(ch2, 2, _T("%d"), grade);
outtextxy(580, 150, ch);
outtextxy(580, 100, ch2);
}
void chose_speed(int nodemun)
{
switch (nodemun / 15)
{
case 0:Sleep(300); break;
case 1:Sleep(250); break;
case 2:Sleep(200); break;
case 3:Sleep(150); break;
case 4:Sleep(100); break;
default:Sleep(100);
}
}
void create_map()
{
//绘图
initgraph(850, 400);
setfillcolor(BLACK);
solidrectangle(0, 0, 850, 400);
//LOGFONT f;
//gettextstyle(&f); // 获取当前字体设置
//f.lfHeight = 48; // 设置字体高度为 48
//_tcscpy(f.lfFaceName, _T("黑体")); // 设置字体为“黑体”(高版本 VC 推荐使用 _tcscpy_s 函数)
//f.lfQuality = ANTIALIASED_QUALITY; // 设置输出效果为抗锯齿
//settextstyle(&f); // 设置字体样式
setbkmode(TRANSPARENT);//设置背景模式
settextcolor(RGB(0, 255, 255));
settextstyle(20, 0, _T("宋体"));
outtextxy(250, 150, _T("wlecome to play the game!"));
outtextxy(50, 350, _T("Press any key to continue..."));
system("pause");
solidrectangle(0, 0, 850, 400);
setlinecolor(RGB(0, 255, 255));
line(500, 0, 500, 400);
outtextxy(520, 150, _T("Score:"));
outtextxy(520, 100, _T("Grade:"));
outtextxy(505, 300, _T("the game is created by jack shi"));
}
void graph_thinks(int nodemun)
{
wchar_t ch[5];
setfillcolor(BLACK);
solidrectangle(0, 0, 850, 400);
setbkmode(TRANSPARENT);//设置背景模式
settextcolor(RGB(0, 255, 255));
settextstyle(40, 0, _T("宋体"));
outtextxy(300, 100, _T(" game over!"));
outtextxy(200, 200, _T(" your grade : points"));
swprintf(ch, 5, _T("%d"), nodemun * 10 - 10);
outtextxy(470,200,ch);
}
int check(LinkList *head,int nodemun)
{
int i;
LinkList* current;
if (nodemun >= 5)//蛇有5个节点以上
{
current = head->next->next->next->next;//current指向第5个节点
for (i = 5; i <= nodemun; i++)//判断蛇是否吃到自己
{
if (head->x == current->x && head->y == current->y)
{
return 0;
}
current = current->next;
i++;
}
}
if (head->x < 0 || head->x>490 || head->y < 0 || head->y>390)//判断蛇身是否超出游戏界面
return 0;
return 1;
}
void main()
{
int kb;
LinkList* head;
int end[2];//存取蛇尾坐标
int position[2];//存取食物位置
int nodemun = 1;//蛇的长度
create_map();
//=============================
head = createLink();
create_food(position);
print_score_grade(nodemun,nodemun/15+1);
while (1)//游戏中
{
create(head, end);
chose_speed(nodemun);//选择速度
if (_kbhit())//获取鼠标操作
{
_getch();
kb = _getch();
//不能向当前蛇头移动方向的反方向运动
if (!(kb == up && move == down || kb == down && move == up || kb == right && move == lift || kb == lift && move == right))
move = kb;
}
head = changeLink(head, end, nodemun);//根据蛇的移动改变链表
if (check(head,nodemun) == 0)//合法性检测
break;
if (head->x == position[0] && head->y == position[1])//判断是否吃到食物
{
add_node(head, &nodemun,end);//吃到食物,添加新节点
print_score_grade(nodemun,nodemun/15+1);//打印等级和分数
create_food(position);//创建新食物
}
}
graph_thinks(nodemun);
system("pause");
closegraph();
}