(C语言贪吃蛇)9.贪吃蛇撞墙找死

目录

游戏说明​

1.撞墙死翘翘的情况

2.如何解决初始化问题

封装函数initSnake();

注意事项

解决方法

总结

 效果演示


游戏说明

玩家通过上下左右按键来控制小蛇的移动,我们之前的内容完成了小蛇每按下一次右键小蛇便向右移动一格,但是玩贪吃蛇一定会出现撞墙的情况,结果就是死掉,那么如何用代码实现呢?

1.撞墙死翘翘的情况

撞墙的情况一般发生在蛇移动以后,即moveSnake(),那么我们只需要在移动以后做一下判断:

if(tail ->hang == 0 || tail->lie == 0 || tail->hang == 20 || tail ->lie == 20){initSnake();}

在这个贪吃蛇游戏中,游戏里的贪吃蛇头其实是“tail”,每moveSnake()一次​​​​​​​蛇做上面的判断。

tail -> hang == 0 判断贪吃蛇是否撞到上墙

tail -> lie == 0 判断贪吃蛇是否撞到左墙

tail -> hang == 20 判断贪吃蛇是否撞到下墙

tail -> lie == lie 判断贪吃蛇是否撞到右墙

那么如果确实撞墙了应该怎么做呢,当然是游戏重新开始,那么游戏如何重新开始呢?

2.如何解决初始化问题
封装函数initSnake();

我们之前封装了初始化游戏的函数initSnake();

void initSnake(){head = (struct Snake *)malloc(sizeof(struct Snake));head->hang = 2;head->lie = 2;head->next = NULL;tail = head;addNode();addNode();addNode();
}

 作用就是初始化蛇身。

注意事项

我们在撞墙的时候,实际上这个蛇的链表是存在的,但是你重新调用initSnake()实际上是开辟新的地址空间,然后给新的地址空间去赋值,创建出新的链表,那么旧的链表怎么办呢?

如果不释放内存可能会造成空间的浪费,甚至造成内存的泄漏。​​​​​​​

不切实际的讲,这个游戏你一直玩,不释放内存,总有一天内存会被你撑爆。

解决方法

每一次初始化蛇身的时候都要把内存清理掉,看看是如何操作的。

在initSnake()中每次判断:

 while(head != NULL){free(head);head = head -> next;}

如果这个head != NULL  我们就遍历这个链表

 但是我们发现如果在这里free(head)的话下面就会出现问题:head都被你free掉了,下面的:

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

head->hang = 2;

head->lie = 2;

head->next = NULL;

该如何执行呢? 

所以我们定义一个临时的变量p;

使用p来存放head变量,然后让head指向head的下一位,之后释放掉p的内存。

struct Snake * p;while(head != NULL){p = head;head = head -> next;free(p);}

当然我们不能忘了,在初始化的时候,head和tail我们尽量都赋上初值NULL

struct Snake * head = NULL;
struct Snake * tail = NULL;

这样做的主要目的是防止head和tail变成野指针的状态。

总结

完善后的代码:

#include <curses.h>
#include <stdlib.h>struct Snake
{int hang;int lie;struct Snake * next;
};struct Snake * head = NULL;
struct Snake * tail = NULL;void initNcurse()
{initscr();keypad(stdscr,1);
}int hasSnakeNode(int i,int j)
{struct Snake * p;p = head;while(p != NULL){if(p->hang == i && p->lie == j){return 1;}p = p -> next;}return 0;    
}void gamePic()
{int hang;int lie;move(0,0);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");}}}void addNode()
{struct Snake * new = (struct Snake *)malloc(sizeof(struct Snake));new->hang = head->hang;new->lie = tail->lie+1;new->next = NULL;tail->next = new;tail = new;}void initSnake(){struct Snake * p;while(head != NULL){p = head;head = head -> next;free(p);}head = (struct Snake *)malloc(sizeof(struct Snake));head->hang = 2;head->lie = 2;head->next = NULL;tail = head;addNode();addNode();addNode();
}void deleNode()
{// struct Snake * p;// p = head;head = head ->next;// free(p);
}void moveSnake()
{addNode();deleNode();if(tail ->hang == 0 || tail->lie == 0 || tail->hang == 20 || tail ->lie == 20){initSnake();}
}int main()
{int con;initNcurse();initSnake();gamePic();while(1){con = getch();if(con == KEY_RIGHT){moveSnake();gamePic();}}getch();//防止程序退出endwin();return 0;
}

默认该文件为snake8.c

我们打开终端,加入以下指令编译该文件:

gcc snake8.c -lcurses

系统默认生成的可执行文件为a.out,在终端环节下执行该文件

./a.out 

 效果演示

此时,我们的贪吃蛇来到了墙的最右边,我们按下右键贪吃蛇向右移动

撞到了墙,初始化,游戏重新开始


        好啦,关于本节讲解贪吃蛇向右移动撞墙死掉并且释放内存的内容就到这里,希望本期博客能对你有所帮助。同时发现错误请多多指正!​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1554852.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

vue-live2d看板娘集成方案设计使用教程

文章目录 前言v1.1.x版本&#xff1a;vue集成看板娘&#xff08;暂不使用&#xff0c;在v1.2.x已替换&#xff09;集成看板娘实现看板娘拖拽效果方案资源备份存储 当前最新调研&#xff1a;2024.10.2开源方案1&#xff1a;OhMyLive2D&#xff08;推荐&#xff09;开源方案2&…

Spring Boot中线程池使用

说明&#xff1a;在一些场景&#xff0c;如导入数据&#xff0c;批量插入数据库&#xff0c;使用常规方法&#xff0c;需要等待较长时间&#xff0c;而使用线程池可以提高效率。本文介绍如何在Spring Boot中使用线程池来批量插入数据。 搭建环境 首先&#xff0c;创建一个Spr…

Agent 概念学习

Agent 概念学习 什么是 Agent OpenAI的研究员 Lilian 写过一篇博客:《 LLM Powered Autonomous Agents》&#xff0c;将 Agents 定义为&#xff1a;LLM memory planning skills tool use&#xff0c;即大语言模型、记忆、任务规划、工具使用的集合。 Overview of a LLM-…

多模态—图文匹配

可能最近大家已经发现了chatgpt可以根据自己的描述生成图片&#xff0c;其实这就是一个图文匹配的问题&#xff0c;可以理解为这是一个多模态的问题。 在模型训练时我们需要N个图片和N个文本对进行训练&#xff0c;文本通过text encoder形成文本语义向量&#xff0c;text enco…

930/105每日一题

算法 1 4,2,9,11, 4, 2,4 2,4,9 42 4 24 9 2&#xff08;0&#xff09; 4&#xff08;1&#xff09; 9&#xff08;2&#xff09; 11&#xff08;3&#xff09; 11&#xff08;0&#xff09;11&#xff08;1&#xff09; 9&#xff08;2&#xff09; 11&#xff08;3&#xf…

C++之多态篇(超详细版)

1.多态概念 多态就是多种形态&#xff0c;表示去完成某个行为时&#xff0c;当不同的人去完成时会有不同的形态&#xff0c;举个例子在车站买票&#xff0c;可以分为学生票&#xff0c;普通票&#xff0c;军人票&#xff0c;每种票的价格是不一样的&#xff0c;当你是不同的身…

C语言 | Leetcode C语言题解之第457题环形数组是否存在循环

题目&#xff1a; 题解&#xff1a; int next(int* nums, int numsSize, int cur) {return ((cur nums[cur]) % numsSize numsSize) % numsSize; // 保证返回值在 [0,n) 中 }bool circularArrayLoop(int* nums, int numsSize) {for (int i 0; i < numsSize; i) {if (!n…

C++ | Leetcode C++题解之第456题132模式

题目&#xff1a; 题解&#xff1a; class Solution { public:bool find132pattern(vector<int>& nums) {int n nums.size();vector<int> candidate_i {nums[0]};vector<int> candidate_j {nums[0]};for (int k 1; k < n; k) {auto it_i upper_…

Ubuntu24.04远程开机

近来在几台机器上鼓捣linux桌面&#xff0c;顺便研究一下远程唤醒主机。 本篇介绍Ubuntu系统的远程唤醒&#xff0c;Windows系统的唤醒可搜索相关资料。 依赖 有远程唤醒功能的路由器&#xff08;当前一般都带这个功能&#xff09;有线连接主机&#xff08;无线连接有兴趣朋友…

信息安全工程师(33)访问控制概述

前言 访问控制是信息安全领域中至关重要的一个环节&#xff0c;它提供了一套方法&#xff0c;旨在限制用户对某些信息项或资源的访问权限&#xff0c;从而保护系统和数据的安全。 一、定义与目的 定义&#xff1a;访问控制是给出一套方法&#xff0c;将系统中的所有功能和数据…

【JAVA开源】基于Vue和SpringBoot的宠物咖啡馆平台

本文项目编号 T 064 &#xff0c;文末自助获取源码 \color{red}{T064&#xff0c;文末自助获取源码} T064&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

仿RabbitMQ实现消息队列三种主题的调试及源码

文章目录 开源仓库和项目上线广播交换模式下的测试直接交换模式下的测试主题交换模式下的测试 开源仓库和项目上线 本项目已开源到下面链接下的仓库当中 仿RabbitMQ实现消息队列 广播交换模式下的测试 消费者客户端 在进行不同测试下&#xff0c;消费者客户端只需要改变交换机…

基于SpringBoot+Vue+MySQL的中医院问诊系统

系统展示 用户前台界面 管理员后台界面 医生后台界面 系统背景 随着信息技术的迅猛发展和医疗服务需求的不断增加&#xff0c;传统的中医院问诊流程已经无法满足患者和医院的需求。纸质病历不仅占用大量存储空间&#xff0c;而且容易丢失和损坏&#xff0c;同时难以实现信息的快…

Acwing 背包问题

背包问题 首先&#xff0c;什么是背包问题&#xff1f; 给定N个物品和一个容量为V的背包&#xff0c;每个物品有体积和价值两种属性&#xff0c;在一些限制条件下&#xff0c;将一些物品放入背包&#xff0c;使得在不超过背包体积的情况下&#xff0c;能够得到的最大价值。根据…

【redis学习篇1】redis基本常用命令

目录 redis存储数据的模式 常用基本命令 一、set 二、keys pattern keys 字符串当中携带问号 keys 字符串当中携带*号 keys 【^字母】 keys * 三、exists 四、del 五、expire 5.1 ttl命令 5.2key删除策略 5.2.1惰性删除 5.2.2定期删除 六、type key的数据类型…

Windows安全加固详解

一、补丁管理 使用适当的命令或工具&#xff0c;检查系统中是否有未安装的更新补丁。 Systeminfo 尝试手动安装一个系统更新补丁。 • 下载适当的补丁文件。 • 打开命令提示符或PowerShell&#xff0c;并运行 wusa.exe <patch_file_name>.msu。 二、账号管…

Pikachu-Sql-Inject - 暴力破解

之前的破解&#xff0c;一般都需要 information_schema.schemata 、 information_schema.tables 、information_schema.columns 的权限&#xff0c;如果没有权限&#xff0c;就需要暴力破解&#xff1b; 如构造payload ,这个 abc 表就是我们要确定是否存在的表 vince and ex…

GPTQ vs AWQ vs GGUF(GGML) 速览和 GGUF 文件命名规范

简单介绍一下四者的区别。 参考链接&#xff1a;GPTQ - 2210.17323 | AWQ - 2306.00978 | GGML | GGUF - docs | What is GGUF and GGML? 文章目录 GPTQ vs AWQ vs GGUF&#xff08;GGML&#xff09; 速览GGUF 文件命名GGUF 文件结构文件名解析答案 附录GGUF 文件命名GGUF 文件…

Pandas基础学习

导入 导入pandas一般是这样导入的 import pandas as pdSeries 创建 s1 pd.Series([5, 17, 3, 26, 31])注意Series的第一个字母要大写&#xff0c;表明这其实是Series类的构建函数, 返回的是Series类的实例 获得元素或者索引 单独获得元素 s1.values单独获得索引值 s…

Flink 03 | 数据流基本操作

Flink数据流结构 DataStream 转换 通常我们需要分析的业务数据可能存在如下问题&#xff1a; 数据中包含一些我们不需要的数据 数据格式不方面分析 因此我们需要对原始数据流进行加工&#xff0c;比如过滤、转换等操作才可以进行数据分析。 “ Flink DataStream 转换主要作…