(C语言贪吃蛇)13.实现贪吃蛇四方向的移动

news2024/10/4 9:45:31

目录

前言

原代码预览

解决方法⚠️

运行效果

总结


前言

        我们上节通过Linux线程实现了两个while(1)同时运行,这样就可以一边控制方向一遍刷新出贪吃蛇的身体节点了。本节我们就来实现贪吃蛇四方向的移动。

(此图片为最终效果) 

原代码预览

        我们之前的代码是通过moveSnake()函数实现贪吃蛇的移动的:

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

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

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

int key;

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,%d\n",key);
        }
    }

}

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

void moveSnake()
{
    addNode();
    deleNode();

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

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

void* changeDir()
{
    while (1)
        {
            key = getch();
            switch (key)
            {
            case 0402:
                    printw("DOWN\n");
                    break;
            case 0403:
                    printw("UP\n");
                    break;
            case 0404:
                    printw("LEFT\n");
                    break;
            case 0405:
                    printw("RIGHT\n");
                    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;
}

那么我们详细看一下moveSnake()函数:

void moveSnake()
{
    addNode();
    deleNode();

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

可以很明显的看出主要是由addNode()deleNode()两个函数控制。

解决方法⚠️

那我们有没有办法使这两个函数更智能呢?

(新节点的行和列坐标要根据方向来确定)那么我们来定义出方向的全局变量 。

#define UP    1
#define DOWN  2
#define LEFT  3
#define RIGHT 4
int dir;

并且我们在初始化贪吃蛇的时候加上初始方向(initsnake())。

下面为修改后的initSnake()函数

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

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

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

         上文可以知道,我们显示贪吃蛇的节点,改变贪吃蛇的节点是通过addNode()deleNode()两个函数,那么我们只需要在addNode()增加上下一节点位置的判断即可

        在贪吃蛇移动的过程中只有四种情况,上下左右,所以简单的switch()语句就可以满足我们的要求。

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

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

于此同时我们也需要修改changeDir()函数:

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

运行效果

        该文件默认命名为snake11.c

打开终端输入以下指令编译该文件:

gcc snake11.c -lcurses

系统会默认生成一个名为“a.out”的可执行文件,输入以下指令执行该程序:

./a.out 

运行效果一🌧️:

运行效果二🍇:

运行效果三✅: 

总结

        我们本节实现了贪吃蛇四方向移动,按住上下左右四个键就会做出相同的反馈,是我们想要的效果😘。

 

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

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

相关文章

6.模拟电子技术——共集电极,共基极,多极放大电路

写在前面 这个是第六次的笔记&#xff0c;祝大家学习愉快 笔记部分 1.共集电极放大电路 首先&#xff0c;我们再复习一遍组态判断&#xff1a;基极进&#xff0c;发射极出&#xff0c;说明是共集电极放大电路。可能读者已经知道一些结论&#xff0c;先抛开这些&#xff0c;我…

Kubernetes-环境篇-02-ubuntu开发环境搭建

1、ubuntu基础环境 # 更新apt软件源 sudo apt update# 安装git sudo apt install git# 安装python3 sudo apt install -y python3 python3-pip# 安装vim sudo apt install vim2、安装go 2.1 下载go安装包 wget https://golang.google.cn/dl/go1.23.2.linux-amd64.tar.gz2.2 …

第十二届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)(第一套)

一.题目分析 &#xff08;1&#xff09;.题目 &#xff08;2&#xff09;.题目分析 1.串口功能分析 a.串口接收车辆出入信息&#xff1a;通过查询车库的车判断车辆是进入/出去 b.串口输出计费信息&#xff1a;输出编号&#xff0c;时长和费用 c.计算停车时长是难点&#x…

深度学习-----------------机器翻译与数据集

目录 机器翻译与数据集下载和预处理数据集预处理步骤词元化词汇表该部分总代码 固定长度阶段或填充该部分总代码 转换成小批量数据集用于训练训练模型总代码 机器翻译与数据集 import os import torch from d2l import torch as d2l下载和预处理数据集 #save d2l.DATA_HUB[fr…

被字节恶心到了

字节 日常逛 xhs 看到一篇吐槽贴&#xff0c;表示被公司恶心到了&#xff1a; 这位网友表示&#xff0c;最近是公司举办了 Q2 和 H1 的优秀员工表彰&#xff0c;自己的 1&#xff08;直属领导&#xff09;评上了&#xff0c;但仔细一看&#xff0c;1 获奖的所有产出都是自己的&…

sql注入第7关(学习记录)

看到这里好像和前面的不一样了&#xff0c;多了个use outfile 先输入个符号&#xff0c;看报错&#xff0c;还是得看别人的教程&#xff0c;通过查找&#xff0c;好像要通过图片来进行注入&#xff0c;ok呀&#xff0c;又是新的方式&#xff0c; 首先我们需要知道他的闭合方式…

uniapp+Android智慧居家养老服务平台 0fjae微信小程序

目录 项目介绍支持以下技术栈&#xff1a;具体实现截图HBuilderXuniappmysql数据库与主流编程语言java类核心代码部分展示登录的业务流程的顺序是&#xff1a;数据库设计性能分析操作可行性技术可行性系统安全性数据完整性软件测试详细视频演示源码获取方式 项目介绍 老年人 登…

算法 | 鹈鹕算法POA-Transformer-LSTM多变量回归预测

&#x1f525; 内容介绍 近年来&#xff0c;随着大数据时代的到来和计算能力的飞速提升&#xff0c;对复杂系统进行精确预测的需求日益增长。多变量时间序列预测作为一项关键技术&#xff0c;广泛应用于金融、能源、交通等诸多领域。传统的预测方法&#xff0c;例如ARIMA和多元…

Prometheus Metrics和PromQL的使用

Metrics 官方解释是 Metrics are numerical measurements in layperson terms. (通俗地讲&#xff0c;Metrics就是数字测量) Prometheus fundamentally stores all data as time series &#xff08;Prometheus把所有数据都存储为时间序列&#xff09; Every time series is u…

《PMI-PBA认证与商业分析实战精析》第6章 跟踪与监督

第6章 跟踪与监督 本章主要内容包括&#xff1a; 跟踪 关系与依赖性 批准需求 基线化已批准需求 使用跟踪矩阵来监督需求 需求生命周期 管理需求变更 本章涵盖的考试重点&#xff1a; 跟踪与监督的六项活动 跟踪与监督六项活动的可交付成果及活动间的关系 跟踪的定义…

指南:Linux常用的操作命令!!!

引言: 操作系统是软件的一类。 主要作用是协助用户调度硬件工作&#xff0c;充当用户和计算机硬件之间的桥梁。 尽管图形化是大多数人使用计算机的第一选择&#xff0c;但是在Linux操作系统上多数都是使用的&#xff1a;命令行在开发中&#xff0c;使用命令行形式&#xff0c…

【有啥问啥】联邦学习(Federated Learning, FL):保护隐私的分布式机器学习

联邦学习&#xff08;Federated Learning, FL&#xff09;&#xff1a;保护隐私的分布式机器学习 联邦学习&#xff08;Federated Learning, FL&#xff09;作为一种前沿的分布式机器学习技术&#xff0c;正逐步成为解决数据隐私保护与模型性能提升之间矛盾的关键方案。以下是…

HTTP Cookie与Session

目录 一. 引入Cookie 1.1 定义 1.2 工作原理 1.3 分类 二. 认识Cookie 三. 测试Cookie 五. 引入Session 六. 测试Session 这篇博客&#xff0c;我们来看看Cookie与Session&#xff0c;内容干货满满。 一. 引入Cookie 1.1 定义 HTTP Cookie&…

幂等性及技术解决方案

目录 定义幂等性 为什么需要幂等性幂等性设计注意事项幂等性的范围分布式锁解决幂等性 设计 延伸阅读 定义幂等性 简单地说&#xff0c;我们可以多次执行幂等运算而不改变结果或者使用相同的输入参数中被调用多次&#xff0c;则不具有额外效果的操作&#xff0c;也就是多次执…

使用pytdx获取历史股票行情

使用pytdx获取历史股票行情 先看效果pytdx基础获取历史股票行情将历史数据存入数据库 先看效果 获取从2010年01月01日-2024年09月30日的股票数据 pytdx基础 https://blog.csdn.net/firexiaHouse/article/details/142687052?spm1001.2014.3001.5501 获取历史股票行情 def …

C++11--智能指针

引入 为什么需要智能指针&#xff1f; 在介绍异常时&#xff0c;遇到以下场景&#xff0c;处理异常就会比较棘手&#xff1a; void Func() {int* arr1 new int[10];int* arr2 new int[20];int* arr3 new int[30];// ...delete[] arr1;delete[] arr2;delete[] arr3; }这里…

一文吃透 SpringBoot (从入门到精通)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

15分钟学 Python 第35天 :Python 爬虫入门(一)

Day 35 : Python 爬虫简介 1.1 什么是爬虫&#xff1f; 网页爬虫&#xff08;Web Crawler&#xff09;是自动访问互联网并提取所需信息的程序。爬虫的主要功能是模拟用户通过浏览器访问网页的操作&#xff0c;从而实现对网页内容的批量访问与信息提取。它们广泛应用于数据收集…

【IPv6】IPv6地址格式及地址分类(组播、单播、任播)整理

IPv6地址格式 IPv6 地址从 IPv4 地址的 32 bits 扩展到 128 bits&#xff0c;IPv6 地址的表示、书写方式也从 IPv4 的点分十进制&#xff0c;修改16进制的冒号分割 IPv4 点分格式(.) 192.168.11.11 IPv6 冒号分割(:) 2408:8459:3032:0000:0000:0000:0001:a9fd IPv6 的规范…

平面电磁波的电场能量磁场能量密度相等,注意电场能量公式也没有复数形式(和坡印廷类似)

1、电场能量密度和磁场能量密度相等(实数场算的) 下面是电场能量密度和磁场能量密度的公式&#xff0c;注意这可不是坡印廷定理。且电场能量密度没有复数表达式&#xff0c;即不是把E和D换成复数形式就行的。注意&#xff0c;一个矢量可以转化为复数形式&#xff0c;两个矢量做…