(C语言贪吃蛇)16.贪吃蛇食物位置随机(完结撒花)

news2024/11/30 10:42:03

目录

前言

修改方向

修改内容

效果展示

 两个新的问题🙋

1.问题1

2.问题2

代码如下:


前言

        我们上一节实现了贪吃蛇吃食物身体节点变长,但是食物的刷新位置不是随机的,并且初始化几次后食物就刷不见了,本节我们就来解决这个问题。

修改方向

        我们这个地图格子是20X20,随机数函数不能有界限,那么我们思考方向就是随机数然后对20进行取余,那么最终得到的数字一定是在区间内的。

修改内容

void initfood()
{
    int x = rand()%20;
    int y = rand()%20;

    food.hang = x;
    food.lie = y;
}

我们之前地图下面还会打印出“by beiweiqiuAC”,我们修改一下,可以打印出食物的行和列坐标。

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 if(hasfood(hang,lie)) printw("##");
                else printw("  ");
            }
            printw("\n");
        }
        if(hang == 19)
        {
            for(lie = 0;lie < 20;lie ++)
               {
                   printw("--");
               }
               printw("\n");
               printw("by beiweiqiuAC,food.hang=%d,food.lie=%d\n",food.hang,food.lie);
        }
    }

}

效果展示

         

 两个新的问题🙋

        我们发现如果食物在地图的最上方的我们的贪吃蛇是吃不到,我们尝试解决这个问题,并且贪吃蛇可以从自己的身体中间穿过去,这很明显是不符合逻辑的,所以我们来优化这两个问题,贪吃蛇这个项目就完结了。 

1.问题1

        食物在地图的最上方,贪吃蛇就会直接撞墙死掉,原因是tail的行第一行就是0,所以只有最上面那一行不行,所以我们只需要修改让贪吃蛇在第0行的时候不死就行了:

void moveSnake()
{
    addNode();
    if(hasfood(tail->hang,tail->lie))
    {
        initfood();
    }else{
        deleNode();
    }
    

    if(tail ->hang < 0 || tail->lie == 0 || tail->hang == 20 || tail ->lie == 20)
    {
        initSnake();
    }
}
2.问题2

        贪吃蛇在运行的过程当中,贪吃蛇撞到自己的身体不会死掉,所以我们要优化这个问题,其实非常简单,我们只需要判断尾巴节点和身体节点是否重合即可。

int ifSnakeDie()
{
    struct Snake *p;
    p = head;
    if(tail ->hang < 0 || tail->lie == 0 || tail->hang == 20 || tail ->lie == 20)
    {
        return 1;
    }
    while(p ->next != NULL){
        if(p->hang == tail->hang && p -> lie == tail->lie){
            return 1;
        }
        p = p -> next;
    }
    return 0;
}

        通过遍历链表的位置再来与尾节点的位置做比较,如果相同就死掉,此时游戏的功能就齐全了。

代码如下:

#include <curses.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define UP    1
#define DOWN  -1
#define LEFT  2
#define RIGHT -2

struct Snake
{
    int hang;
    int lie;
    struct Snake * next;
};

struct Snake * head = NULL;
struct Snake * tail = NULL;
int key;
int dir;

struct Snake food;

void initfood()
{
    int x = rand()%20;
    int y = rand()%20;

    food.hang = x;
    food.lie = y;
}

void initNcurse()
{
    initscr();
    keypad(stdscr,1);
    noecho();
}

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;    
}

int hasfood(int i,int j)
{

    if(food.hang == i && food.lie == j) return 1;
    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 if(hasfood(hang,lie)) printw("##");
                else printw("  ");
            }
            printw("\n");
        }
        if(hang == 19)
        {
            for(lie = 0;lie < 20;lie ++)
               {
                   printw("--");
               }
               printw("\n");
               printw("by beiweiqiuAC,food.hang=%d,food.lie=%d\n",food.hang,food.lie);
        }
    }

}

void addNode()
{
    struct Snake * new = (struct Snake *)malloc(sizeof(struct Snake));
    
    new->next = NULL;

    switch(dir)
    {
        case UP:
            new->hang = tail->hang - 1;
            new->lie = tail->lie;
            break;
        case DOWN:
            new->hang = tail->hang + 1;
            new->lie = tail->lie;
            break;
        case LEFT:
            new->hang = tail->hang;
            new->lie = tail->lie - 1;
            break;
        case RIGHT:
            new->hang = tail->hang;
            new->lie = tail->lie + 1;
            break;
    }
    tail->next = new;
    tail = new;
}

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

    initfood();

    head = (struct Snake *)malloc(sizeof(struct Snake));
    head->hang = 1;
    head->lie = 1;
    head->next = NULL;

    tail = head;
    addNode();
    addNode();
    addNode();
    addNode();
}

void deleNode()
{
 // struct Snake * p;
 // p = head;
    head = head ->next;
 // free(p);
}

int ifSnakeDie()
{
    struct Snake *p;
    p = head;
    if(tail ->hang < 0 || tail->lie == 0 || tail->hang == 20 || tail ->lie == 20)
    {
        return 1;
    }
    while(p ->next != NULL){
        if(p->hang == tail->hang && p -> lie == tail->lie){
            return 1;
        }
        p = p -> next;
    }
    return 0;
}

void moveSnake()
{
    addNode();
    if(hasfood(tail->hang,tail->lie))
    {
        initfood();
    }else{
        deleNode();
    }
    

    if(ifSnakeDie())
    {
        initSnake();
    }
}

void* refreshJieMian()
{
    while(1)
        {
            moveSnake();
            gamePic();
            refresh();
            usleep(100000);
        }
}

void turn(int direction)
{
    
    if(abs(dir) != abs(direction))
    {
        dir = direction;
    }
}

void* changeDir()
{
    while (1)
        {
            key = getch();
            switch (key)
            {
            case 0402:
                    turn(DOWN);
                    break;
            case 0403:
                    turn(UP);
                    break;
            case 0404:
                    turn(LEFT);
                    break;
            case 0405:
                    turn(RIGHT);
                    break;
            }
        }
}


int main()
{
    pthread_t t1;
    pthread_t t2;
    
    initNcurse();

    initSnake();

    gamePic();
    pthread_create( &t1, NULL,refreshJieMian, NULL);
    pthread_create( &t2, NULL, changeDir, NULL);
    
    while(1);
    getch();//防止程序退出
    endwin();
    return 0;
}

效果展示:

C语言贪吃蛇效果展示

       

 此时,我们的C语言贪吃蛇项目就已经完成了「完结散花🌹🌹🌹」

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

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

相关文章

【Linux】进程地址空间、环境变量:从理论到实践(三)

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 &#x1f680; 前言一&#xff1a;&#x1f525; 环境变量 &#x1f95d; 基本概念&#x1f95d; 常见环境变量&#x1f95d; 查看环境变量方法 二&#xff1a;&#x1f525; 测试 &…

Stable Diffusion绘画 | 插件-Deforum:动态视频生成(中篇)

本篇文章重点讲解参数最多的 关键帧 模块。 「动画模式」选择「3D」&#xff1a; 下方「运动」Tab 会有一系列参数&#xff1a; 以下4个参数&#xff0c;只有「动画模式」选择「2D」才会生效&#xff0c;可忽略&#xff1a; 运动 平移 X 让镜头左右移动&#xff1a; 大于0&a…

JavaSE——面向对象练习题

1.对象数组排序 定义一个Person类{name,age,job}&#xff0c;初始化Person对象数组&#xff0c;有3个person对象&#xff0c;并按照age从小到大进行冒泡排序&#xff1b;再按照name的长度从小到大进行选择排序。 public class HomeWork01 {public static void main(String[] a…

基于spring boot的篮球论坛系统

作者&#xff1a;计算机搬砖家 开发技术&#xff1a;SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;Java精选实战项…

基于拥堵模型的轻量级平台公交室内情况监控系统

论文标题&#xff1a;Bus Indoor Situation Monitoring System Based on Congestion Model Using Lightweight Platform 作者信息&#xff1a;Dong Hyun Kim, Yun Seob Kim, 和 Jong Deok Kim* 所属机构&#xff1a;Pusan National University, Department of Computer Scienc…

Linux·环境变量与进程地址空间

1. 命令行参数 各位可能见过main函数也是有参数的&#xff0c;只是我们平时写的代码都比较简单&#xff0c;用不到main函数的参数&#xff0c;下面我们看一下main函数的参数是什么又是怎么用的 我们看这样一段代码 其编译运行后的效果是这样的 我们将main函数后面的那两个参数叫…

排序算法剖析

文章目录 排序算法浅谈参考资料评价指标可视化工具概览 插入排序折半插入排序希尔排序冒泡排序快速排序简单选择排序堆排序归并排序基数排序 排序算法浅谈 参考资料 数据结构与算法 评价指标 稳定性&#xff1a;两个相同的关键字排序过后相对位置不发生变化时间复杂度空间复…

MyBatisPlus——学习笔记

MyBatisPlus 一、导入依赖 <!-- MyBatisPlus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><!-- MySql --><de…

C++基础(7)——STL简介及string类

目录 1.STL简介 1.1什么是 1.2STL的历史版本 1.3STL的六大组件 ​编辑 1.4有用的网址 2.string类 2.1string的多种定义方式 2.2string的插入 2.2.1尾插&#xff08;push_back&#xff09; 2.2.2insert插入 2.3拼接&#xff08;append&#xff09; 2.4删除 2.4.1尾…

CoRL 2024 麻省理工学院提出T3触觉Transformer,打破触觉感知的壁垒,重塑未来机器人

在智能机器人领域&#xff0c;触觉感知的研究正逐渐成为关注的焦点。然而&#xff0c;如何让机器人通过触觉更智能地感知和操作&#xff0c;依然是一个未解决的挑战。基于相机的触觉感知是一种通过在软弹性体下嵌入相机来捕获与环境的细粒度交互的感知方法&#xff0c;是最流行…

Java报错输出的信息究竟是什么?

Java报错输出的信息究竟是什么&#xff1f; 本篇会带大家了解一下java运行时报错输出的信息内容&#xff0c;简单学习一下虚拟机内存中Java虚拟机栈的工作方式以及栈帧中所存储的信息内容 异常信息 当你的程序运行报错时&#xff0c;你是否会好奇打印出来的那一大坨红色的究竟…

搜索引擎相关的一段实习经历

0 前言 就是跟搜索相关的一段经历。主要工作就是建立倒排索引库相关的一些简单内容。 又翻到了以前的工作&#xff0c;权作纪念。 就是简单的封装cpp的库供python语言调用。 反正就是很多版本问题等等吧各种鬼问题。 我感觉这个思路可能还是待考证。 跨语言的调用我感觉还是不…

泛型编程--模板【C++提升】(特化、类属、参数包的展开、static、模板机制、重载......你想知道的全都有)

更多精彩内容..... &#x1f389;❤️播主の主页✨&#x1f618; Stark、-CSDN博客 本文所在专栏&#xff1a; C系列语法知识_Stark、的博客-CSDN博客 其它专栏&#xff1a; 数据结构与算法_Stark、的博客-CSDN博客 C系列项目实战_Stark、的博客-CSDN博客 座右铭&#xff1a;梦…

Java中的while和do...while循环

while和do...while循环 while循环基本语法执行流程注意事项练习 do...while循环基本语法说明流程图练习 while循环 基本语法 循环变量初始化; while(循环条件){循环体&#xff08;语句&#xff09;;循环变量迭代; }1&#xff09;while循环也有四要素&#xff1a;循环变量初始…

【JNI】普通类型的基本使用

简单使用 在上一期我们介绍了JNI的基本使用&#xff0c;这里简单介绍一下普通类型 HelloJNI.java&#xff1a;这里计算两个整型数的平均值&#xff0c;返回值类型为double public class HelloJNI { static {System.loadLibrary("hello"); }private native String …

electron-builder 首次执行报错问题解决

假日想研究一下 react electron 的使用&#xff0c;结果发现首次打包疯狂报错&#xff0c;研究了一下之后才发现是第一次的话 electron-builder 会从外面下载依赖包到我们系统中&#xff0c;由于某种力量导致压缩包无法下载或者是下载过慢导致失败&#xff0c;要解决其实也简单…

认知战认知作战:2024年9月30日中国股市大涨背景下的认知战分析报告

认知战认知作战&#xff1a;2024年9月30日中国股市大涨背景下的认知战分析报告 关键词&#xff1a;认知战, 中国股市, 信息操纵, 心理战, 技术战, 信息监管, 投资者素养, 国际合作, 法律法规, 协同作战, 谣言澄清, 市场情绪,认知作战,新质生产力,人类命运共同体,认知战,认知域…

《Linux从小白到高手》理论篇:深入理解Linux的计划任务/定时任务

值此国庆佳节&#xff0c;深宅家中&#xff0c;闲来无事&#xff0c;就多写几篇博文。本篇详细深入介绍Linux的计划任务/定时计划。 Linux的计划任务 在很多时候为了自动化管理系统&#xff0c;我们都会用到计划任务&#xff0c;比如关机&#xff0c;重启&#xff0c;备份之类…

二叉树--堆

1.二叉树的顺序结构 普通的二叉树是不适合用数组来存储的&#xff0c;因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结 构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储&#xff0c;需要注意的是这里的堆和操作系统 虚拟进程地址空间中的堆是两…

CSP-J Day 4 模拟赛补题报告

姓名&#xff1a;王胤皓&#xff0c;校区&#xff1a;和谐校区&#xff0c;考试时间&#xff1a; 2024 2024 2024 年 10 10 10 月 4 4 4 日 9 : 00 : 00 9:00:00 9:00:00~ 12 : 30 : 00 12:30:00 12:30:00&#xff0c;学号&#xff1a; S 07738 S07738 S07738 请关注作者的…