上节讲解了关于贪吃蛇身体节点的显示,本节来实现显示完整的贪吃蛇身体,主要就是多个节点的关系。
多个节点如何构成一条蛇关键在于节点坐标关系
思路有了那么开始编写代码。
构建三个身体节点:
struct Snake node1 = {2,2,NULL};
struct Snake node2 = {2,3,NULL};
struct Snake node3 = {2,4,NULL};
链表的原理很简单:
node1.next = &node2;
node2.next = &node3;
那么我们如何显示呢?总不可能继续判断节点位置吧(显得有点蠢哈),这样会提高程序的时间复杂度,我们可以写一个封装函数:
int hasSnakeNode(int i,int j)
{
if(node1.hang == i && node1.lie == j)
{
return 1;
}
return 0;
}
在输出身体节点前进行判断,hang作为i输入,lie作为j输入,如果return 1则输出蛇的身体,return 0则输出空白。
加入该封装函数和判断后运行,运行结果与上节的显示结果是一样的。
我们通过函数封装的好处是可以进行多个节点的判断,我们每次经过这里都进行判断这里是不是蛇的身体节点。
我们简单对封装函数进行修改即可(类比于链表的封装与查找)
int hasSnakeNode(int i,int j)
{
struct Snake * p;
p = &node1;
while(p != NULL)
{
if(p->hang == i && p->lie == j)
{
return 1;
}
p = p -> next;
}
return 0;
}
这样我们就可以将链表里的每一项和行数列数做比较。
#include <curses.h>
struct Snake
{
int hang;
int lie;
struct Snake * next;
};
struct Snake node1 = {2,2,NULL};
struct Snake node2 = {2,3,NULL};
struct Snake node3 = {2,4,NULL};
void initNcurse()
{
initscr();
keypad(stdscr,1);
}
int hasSnakeNode(int i,int j)
{
struct Snake * p;
p = &node1;
while(p != NULL)
{
if(p->hang == i && p->lie == j)
{
return 1;
}
p = p -> next;
}
return 0;
}
void gamePic()
{
int hang;
int lie;
for(hang = 0;hang < 20;hang ++)
{
if(hang == 0)
{
for(lie = 0;lie < 20;lie ++)
{
printw("--");
}
printw("\n");
}
if(hang >= 0 && hang <= 19)
{
for(lie = 0;lie <= 20;lie ++)
{
if(lie == 0 || lie == 20) printw("|");
else if(hasSnakeNode(hang,lie)) printw("[]");
else printw(" ");
}
printw("\n");
}
if(hang == 19)
{
for(lie = 0;lie < 20;lie ++)
{
printw("--");
}
printw("\n");
printw("by beiweiqiuAC");
}
}
}
int main()
{
initNcurse();
node1.next = &node2;
node2.next = &node3;
gamePic();
getch();//防止程序退出
endwin();
return 0;
}
运行结果如图所示:
此时我们通过地址传递以及函数封装就可以显示完整的蛇身体节点了。