c语言第一个小游戏:贪吃蛇小游戏03

我们为贪吃蛇的节点设置为一个结构体,构成贪吃蛇的身子的话我们使用链表,链表的每一个节点是一个结构体

显示贪吃蛇身子的一个节点

我们这边node就表示一个蛇的身体 就是一小节

输出结果如下

显示贪吃蛇完整身子

效果如下

代码实现

这个hasSnakeNode(hang,lie)这个函数就是来判断当前这个坐标是否为蛇的身子的坐标,坐标带进去,如果符合return 1;那么返回1 到地图这里 1 的话就是ture 使hasSnakeNode这个函数生效,然后打印[ ]蛇身。那么函数封装的好处就是在于我们可以进行多个节点的判断

宏观的看,每个坐标都会进入到hasSnakeNode(hang,lie)进行判断,如果行列坐标等于蛇身子的行列坐标,那么就返回1 我们会去想p的下一项是哪里操作的 请看main函数node1.next=&next2,这个是关键,才能遍历链表,暂时是静态的写链表,下一次我们用动态添加的方法进行添加节点

代码

#include <curses.h>

struct snack{

int hang;

int lie;

struct snack *next;

};

struct snack node1 = {2,2,NULL};

struct snack node2 = {2,3,NULL};

struct snack node3 = {2,4,NULL};

void initgame()

{

initscr();

keypad(stdscr,1);

}

int hasSnackNode(int i,int j)

{

struct snack *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(hasSnackNode(hang,lie)){

printw("[]");

}

else{

printw(" ");

}

}

printw("\n");

}

if(hang == 19){

for(lie=0;lie<20;lie++){

printw("--");

}

printw("\n");

}

}

printw("by shijintao");

}

int main()

{

initgame();

node1.next = &node2;

node2.next = &node3;

gamepic();

getch();

endwin();

return 0;

}

但是这个太土了我们要进行优化

我们用封装函数的方法

显示贪吃蛇完整身子

优化代码

#include <curses.h>

#include <stdlib.h>

struct snake{

int hang;

int lie;

struct snake *next;

};

struct snake *head;//全局变量

struct snake *tail;//全局变量

void initgame()

{

initscr();

keypad(stdscr,1);

}

int hasSnakeNode(int i,int j)

{

struct snake *p;

p = head; //现在头节点是head 不是node1了 而且这个head是通过initSnake影响的,因为head是全局变量,所以可以使用head

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 shijintao");

}

void addNode()

{

struct snake *new;

new =(struct snake *)malloc(sizeof(struct snake));

new->hang=tail->hang; //最先开始tail的值等于head

new->lie=tail->lie+1;

tail->next = new;

tail = new;//每次改变tail的值

new->next = NULL;

}

void initSnake()

{

head = (struct snake *)malloc(sizeof(struct snake));

head->hang=2;

head->lie=2;

head->next=NULL;

tail = head;

addNode();

}

int main()

{

initgame();

initSnake();

gamepic();

getch();

endwin();

return 0;

}

代码优化的点:

将原先死板添加的,变成动态的添加节点,并进行封装,减少代码冗余

void initSnake()

{

head = (struct snake *)malloc(sizeof(struct snake));

head->hang=2;//这些都是设置初始值

head->lie=2;

head->next=NULL;

tail = head;//蛇的初始状态头节点也是尾节点

addNode(); //如果你不加这个的话 蛇的身子就只有一个,我觉得加一个也就是比较好看

}

void addNode()

{

struct snake *new;

new =(struct snake *)malloc(sizeof(struct snake));

new->hang=tail->hang; //这个只是单纯的向右边加入,不考虑方向,以后回头来看不要被误导

new->lie=tail->lie+1;

tail->next = new;

tail = new;//可以这样想每次新节点插入后这个tail的值(行和列)都会回到最上方全局变量的地方然后,tail的值是不会被刷新的,是一直被影响的,被上一个节点影响,随后保存信息,因为他是全局变量

new->next = NULL;

}

initSnake()这个函数直接就是把蛇的头节点,也就是蛇的初始位置,hang、lie 都默认的设置好,就像我们玩贪吃蛇初始有个蛇停在那边,这个函数就是这个作用。

这两个函数搭配使用组成了蛇的身子,我们都说用动态创建链表要用到指针,且链表都是有头节点和尾节点,为了不容易出现错误 我们将头指针和尾指针设置为全局变量。

头节点是指针,我们需要为指针赋予一个内存空间,因为后面我们需要在尾点后方插入新的节点,那么我们需要将新节点每次开辟一个空间。

最先开始尾节点就是头节点

addNode是添加新节点到尾节点后边

我们将添加新节点,还有初始化贪吃蛇的行列,封装成了函数,直接调用函数即可在尾部添加新节点

相关推荐
Jasmine_llq12 小时前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
学嵌入式的小杨同学12 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
Re.不晚13 小时前
Java入门17——异常
java·开发语言
爱吃rabbit的mq13 小时前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
精彩极了吧13 小时前
C语言基本语法-自定义类型:结构体&联合体&枚举
c语言·开发语言·枚举·结构体·内存对齐·位段·联合
(❁´◡`❁)Jimmy(❁´◡`❁)13 小时前
Exgcd 学习笔记
笔记·学习·算法
YYuCChi14 小时前
代码随想录算法训练营第三十七天 | 52.携带研究材料(卡码网)、518.零钱兑换||、377.组合总和IV、57.爬楼梯(卡码网)
算法·动态规划
南极星100514 小时前
蓝桥杯JAVA--启蒙之路(十)class版本 模块
java·开发语言
baidu_2474386114 小时前
Android ViewModel定时任务
android·开发语言·javascript
Dev7z14 小时前
基于 MATLAB 的铣削切削力建模与仿真
开发语言·matlab