main.c
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "list.h"
#include "func.h"
#include
int main()
{
int i;
//初始化界面
initscr();
//关闭回显
noecho();
//把光标置为不可见
curs_set(0);
Snake *p = NULL;
Snake *q = NULL;
Main_Window(); //贪吃蛇区域:79*24 (y>=6 && y<=29 ; x>=1 && x<= 79)
Snake *snake_list = Inin_Snake(); //初始化贪吃蛇与食物
//创建线程去执行函数 Get_Cmd
pthread_t pid;
pthread_create(&pid, NULL, Get_Cmd, NULL);
while(1) //贪吃蛇行进
{
switch(Walk_Falg)
{
case UP:
Snake_Walk_UP(snake_list);
break;
case DOWN:
Snake_Walk_DOWN(snake_list);
break;
case LEFT:
Snake_Walk_LEFT(snake_list);
break;
case RIGHT:
Snake_Walk_RIGHT(snake_list);
break;
default:
break;
}
//每次移动之后,判断游戏是否结束
if(Is_GameOver(snake_list))
{
break;
}
refresh(); //刷新界面
usleep(500*1000); //延时一段时间 : 速度调节
}
//游戏结束,处理(输出一句提示语句: GAME_OVER!!!)
endwin();
//关闭界面
return 0;
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
func.c
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "func.h"
void Main_Window() //主界面
{
mvprintw(0, 0, "*********************************************************************************");
mvprintw(1, 21, "Welcome to Eating Sneak !!!");
mvprintw(3, 1, "Using time: ");
mvprintw(3, 26, "Get grade: ");
mvprintw(3, 51, "Diffcult: ");
mvprintw(5, 0, "*********************************************************************************");
int i;
for(i=0; i<30; i++)
{
mvprintw(i, 0, "*");
mvprintw(i, 80, "*");
}
mvprintw(30, 0, "*********************************************************************************");
refresh();
}
bool Get_Food(Snake *list)
{
//获取随机值赋值给 My_Food
MyFood.x = (rand() % 79) + 1 ;
MyFood.y = (rand() % 24) + 6 ;
Snake *p = list;
while(p != NULL)
{
if(MyFood.x == p->x && MyFood.y == p->y) //食物刷新在蛇身上,不符合要求
{
return false;
}
p = p->next;
}
return true;
}
void Show_Food()
{
mvprintw(MyFood.y, MyFood.x, "$");
}
Snake * Inin_Snake() //初始化贪吃蛇与食物,返回链表头的地址
{
Walk_Falg = UP; //默认行进方向向上
Snake *snake_list = Init_List();//初始化贪吃蛇
Snake *node = NULL; //防止野指针
/* for(i=0; i<4; i++)
{
node = Create_Node(24-i, 25);
Insert_Node(snake_list, node);
} */
while(Get_Food(snake_list) == 0); //食物刷新
Show_Food();
//把这条链表显示在界面上
Show_Snake(snake_list);
return snake_list;
}
void Snake_Walk_UP(Snake *snake_list) //贪吃蛇往上走
{
if(MyFood.x == snake_list->x && MyFood.y == (snake_list->y-1)) //判断食物是否被吃:判断蛇头运动会不会跟食物重叠
{
//1,新建一个链表节点,将当前蛇头的坐标信息,放入这个节点
Snake *node = Create_Node(snake_list->x, snake_list->y);
//2,把新的链表节点 头插法,插入链表
Insert_Node(snake_list, node);
//3,蛇头往上运动一格
snake_list->y--;
//4,把新的链表显示出来
Show_Snake(snake_list);
//5,刷新食物
while(Get_Food(snake_list) == 0); //食物刷新
Show_Food();
}
else //没吃到食物
{
if(snake_list->next != NULL)
{
//1,断开最后一个节点,用指针p指向它
Snake * p = snake_list;
while(p->next != NULL)
{
p = p->next; //找出最后一个节点 p
}
p->prev->next = NULL; //切断最后一个节点
mvprintw(p->y, p->x, " ");
//2,将链表头的坐标信息赋值给最后一个节点
p->x = snake_list->x;
p->y = snake_list->y;
//3,头插法插入节点 p 到 链表
Insert_Node(snake_list, p);
}
//清除走过的痕迹
mvprintw(snake_list->y, snake_list->x, " ");
//4,改变头结点的位置
snake_list->y--;
Show_Snake(snake_list); //将改变后的位置显示到界面上
}
}
void Snake_Walk_DOWN(Snake *snake_list) //贪吃蛇往下走
{
if(MyFood.x == snake_list->x && MyFood.y == (snake_list->y+1)) //判断食物是否被吃:判断蛇头运动会不会跟食物重叠
{
//1,新建一个链表节点,将当前蛇头的坐标信息,放入这个节点
Snake *node = Create_Node(snake_list->x, snake_list->y);
//2,把新的链表节点 头插法,插入链表
Insert_Node(snake_list, node);
//3,蛇头往上运动一格
snake_list->y++;
//4,把新的链表显示出来
Show_Snake(snake_list);
//5,刷新食物
while(Get_Food(snake_list) == 0); //食物刷新
Show_Food();
}
else //没吃到食物
{
if(snake_list->next != NULL)
{
//1,断开最后一个节点,用指针p指向它
Snake * p = snake_list;
while(p->next != NULL)
{
p = p->next; //找出最后一个节点 p
}
p->prev->next = NULL; //切断最后一个节点
mvprintw(p->y, p->x, " ");
//2,将链表头的坐标信息赋值给最后一个节点
p->x = snake_list->x;
p->y = snake_list->y;
//3,头插法插入节点 p 到 链表
Insert_Node(snake_list, p);
}
//清除走过的痕迹
mvprintw(snake_list->y, snake_list->x, " ");
//4,改变头结点的位置
snake_list->y++;
Show_Snake(snake_list); //将改变后的位置显示到界面上
}
}
void Snake_Walk_LEFT(Snake *snake_list) //贪吃蛇往下走
{
if(MyFood.x == (snake_list->x-1) && MyFood.y == (snake_list->y)) //判断食物是否被吃:判断蛇头运动会不会跟食物重叠
{
//1,新建一个链表节点,将当前蛇头的坐标信息,放入这个节点
Snake *node = Create_Node(snake_list->x, snake_list->y);
//2,把新的链表节点 头插法,插入链表
Insert_Node(snake_list, node);
//3,蛇头往左运动一格
snake_list->x--;
//4,把新的链表显示出来
Show_Snake(snake_list);
//5,刷新食物
while(Get_Food(snake_list) == 0); //食物刷新
Show_Food();
}
else //没吃到食物
{
if(snake_list->next != NULL)
{
//1,断开最后一个节点,用指针p指向它
Snake * p = snake_list;
while(p->next != NULL)
{
p = p->next; //找出最后一个节点 p
}
p->prev->next = NULL; //切断最后一个节点
mvprintw(p->y, p->x, " ");
//2,将链表头的坐标信息赋值给最后一个节点
p->x = snake_list->x;
p->y = snake_list->y;
//3,头插法插入节点 p 到 链表
Insert_Node(snake_list, p);
}
//清除走过的痕迹
mvprintw(snake_list->y, snake_list->x, " ");
//4,改变头结点的位置
snake_list->x--;
Show_Snake(snake_list); //将改变后的位置显示到界面上
}
}
void Snake_Walk_RIGHT(Snake *snake_list) //贪吃蛇往右走
{
if(MyFood.x == (snake_list->x+1) && MyFood.y == snake_list->y) //判断食物是否被吃:判断蛇头运动会不会跟食物重叠
{
//1,新建一个链表节点,将当前蛇头的坐标信息,放入这个节点
Snake *node = Create_Node(snake_list->x, snake_list->y);
//2,把新的链表节点头插法,插入链表
Insert_Node(snake_list, node);
//3,蛇头往右运动一格
snake_list->x++;
//4,把新的链表显示出来
Show_Snake(snake_list);
//5,刷新食物
while(Get_Food(snake_list) == 0); //食物刷新
Show_Food();
}
else //没吃到食物
{
if(snake_list->next != NULL)
{
//1,断开最后一个节点,用指针p指向它
Snake * p = snake_list;
while(p->next != NULL)
{
p = p->next; //找出最后一个节点 p
}
p->prev->next = NULL; //切断最后一个节点
mvprintw(p->y, p->x, " ");
//2,将链表头的坐标信息赋值给最后一个节点
p->x = snake_list->x;
p->y = snake_list->y;
//3,头插法插入节点 p 到 链表
Insert_Node(snake_list, p);
}
//清除走过的痕迹
mvprintw(snake_list->y, snake_list->x, " ");
//4,改变头结点的位置
snake_list->x++;
Show_Snake(snake_list); //将改变后的位置显示到界面上
}
}
bool Is_GameOver(Snake *snake_list) //判断游戏是否结束,如果结束返回真 true ,否则返回假 false
{
if(snake_list->x == 1 || snake_list->x == 79 || snake_list->y == 6 || snake_list->y == 29)
{
return true;
}
else
{
Snake *p = snake_list->next;
if(p == NULL)
{
return false;
}
while(p != NULL)
{
if(snake_list->x == p->x && snake_list->y == p->y)
{
return true;
}
p = p->next;
}
return false;
}
}
//设计一个循环获取获取键盘数据的函数
void *Get_Cmd(void *arg)
{
int ch;
while(1)
{
//获取字符,并且判断
ch = getch();
if(ch == 'w') //改变方向,将方向变成向上
{
if(Walk_Falg == DOWN)
{
Walk_Falg = DOWN;
}
else
{
Walk_Falg = UP;
}
}
else if(ch == 'a')
{
if(Walk_Falg == RIGHT)
{
Walk_Falg = RIGHT;
}
else
{
Walk_Falg = LEFT;
}
}
else if(ch == 's')
{
if(Walk_Falg == UP)
{
Walk_Falg = UP;
}
else
{
Walk_Falg = DOWN;
}
}
else if(ch == 'd')
{
if(Walk_Falg == LEFT)
{
Walk_Falg = LEFT;
}
else
{
Walk_Falg = RIGHT;
}
}
}
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
list.c
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "list.h" // #include
//1,创建链表
Snake * Init_List()
{
//1)申请一片空间给链表头节点 malloc (从内存的堆空间申请内存)
Snake *list = (Snake *)malloc(sizeof(Snake));
if(list == NULL)
{
perror("malloc failed");
return NULL;
}
//2)对链表头结点中的内容进行赋值
list->x = 20;
list->y = 25; //初始化蛇头位置
list->next = NULL;
list->prev = NULL;
//3,返回这个链表节点的地址
return list;
}
//2,创建链表节点 (传参数:坐标)
Snake * Create_Node(int x, int y)
{
//1)申请一片空间给链表节点 malloc
Snake *node = (Snake *)malloc(sizeof(Snake));
if(node == NULL)
{
perror("malloc node failed");
return NULL;
}
//2)对链表头结点中的内容进行赋值
node->x = x;
node->y = y;
node->next = NULL;
node->prev = NULL;
//3)返回链表节点
return node;
}
//3,链表节点插入链表 (头插法)
void Insert_Node(Snake *list, Snake *newnode)
{
if(list->next == NULL) //只有一个节点的链表
{
list->next = newnode;
newnode->prev = list;
}
else
{
newnode->next = list->next;
list->next = newnode;
newnode->prev = list;
newnode->next->prev = newnode;
}
}
//4,遍历链表
void Show_Snake(Snake *list)
{
Snake *p = list->next;
mvprintw(list->y, list->x, "@");
while(p != NULL)
{
//printf("(%d,%d)\n", p->x, p->y);
mvprintw(p->y, p->x, "O");
p = p->next;
}
refresh();
}
//5,删除链表
void Delete_List(Snake *list)
{
//1,删除每一个节点
Snake *p = list;
Snake *q = p;
while(p != NULL)
{
q = p;
p = p->next;
free(q); //释放q指针指向的节点
}
}
----------------------------------------------------------------------------------
要求
1,游戏可以实现难度选择2,游戏[size=15.3333px]正常运行,无明显bug3, 游戏屮[size=15.3333px]显示游戏时间,获取分数4,当游戏获取分数达到一定分数值之后,自动增加游戏难度。5,界面美观,游戏结束,输出一句提示语句: GAME_OVER!!!
我来回答