实现贪吃蛇小游戏

简介: 实现贪吃蛇小游戏

实现前提是:

(1)Linux环境

(2)基于Ncurse图形库

涉及到的知识点有:

C语言基础,数据结构链表基础C变量,流程控制,函数,指针,结构体等

Linux系统编程文件编程,进程,线程,通信,第三方包等

使用ncurse的示例代码:

#include <curses.h>
 
int main()
{
    initscr();//ncurse界面的初始化函数
    printw("This is a curses window.\n"); //在ncurse模式下的
    printfgetch(); //等待用户输入,如果没有这句话,程序就退出了,看不到运行的结果,也就是看不到上面那句话
    endwin(); //程序退出,调用改函数来恢复shell终端的显示,如果没有这句话,sheLl终端字乱码,坏掉
    return 0;
}

编译nucrse程序:

ncurse上下左右键值

贪吃蛇身子节点代码示例:(链表知识)

struct Snake
{
    int row;//行坐标
    int column;//列坐标
    struct Snake *next;//下一个节点的位置
}

贪吃蛇全部代码:

#include <curses.h>
#include <time.h>
#include <stdio.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 row;
        int column;
        struct Snake *next;
};
 
struct Snake *head = NULL;
struct Snake *tail = NULL;
struct Snake food;
 
int key; //方向键值。
int dir; //方向感应。
 
void initFood()
{
        srand((unsigned)time(NULL));
        int x = rand()%15+3;
        int y = rand()%15+3;
 
        food.row    = x;
        food.column = y;
}
 
 
 
int allSnakeNode(int i,int j)
{
        struct Snake *p = NULL;
        p = head;
 
        while(p != NULL){
                if(p->row == i && p->column == j){
                        return 1;
                }
                p = p->next;
        }
        return 0;
}
 
int setFood(int i, int j)
{
 
        if(food.row==i && food.column==j)
        {
                return 1;
        }
        return 0;
}
 
void gameMap()
{
        int row;
        int column;
        move(0,0);
 
        for(row = 0;row < 20;row++){
                if(row == 0){
                        for(column = 0;column < 20;column++){
                                printw("--");
                        }
                        printw("\n");
                }
                if(row >= 0 && row <= 19){
                        for(column = 0;column <= 20;column++){
                                if(column == 0 || column == 20){
                                        printw("|");
                                }else if(allSnakeNode(row,column)){
                                        printw("[]");
                                }else if(setFood(row,column)){
                                        printw("##");
                                }
                                else{
                                        printw("  ");
                                }
                        }
                        printw("\n");
                }
                if(row == 19){
                        for(column = 0;column < 20;column++){
                                printw("--");
                        }
                        printw("\n");
                        printw("Make by ZBB,key=%d,food.row=%d,food.column=%d\n",key,food.row,food.column);
                }
        }
}
 
void addNode()
{
        struct Snake *new = (struct Snake *)malloc(sizeof(struct Snake));
        new->next = NULL;
 
        switch(dir){
                case UP:
                        new->row = tail->row-1;
                        new->column = tail->column;
                        break;
                case DOWN:
                        new->row = tail->row+1;
                        new->column = tail->column;
                        break;
                case LEFT:
                        new->row = tail->row;
                        new->column = tail->column-1;
                        break;
                case RIGHT:
                        new->row = tail->row;
                        new->column = tail->column+1;
                        break;
        }
        tail->next = new;
        tail = new;
}
 
void initSnake()
{
        struct Snake *p = NULL;
        //贪吃蛇的初始方向:右。
        dir = RIGHT;
 
        while(head != NULL){
                p = head;
                head = head->next;
                free(p);
        }
        initFood();
 
        //贪吃蛇的初始位置。
        head = (struct Snake *)malloc(sizeof(struct Snake));
        head->row = 3;
        head->column = 4;
        head->next = NULL;
 
        tail = head;
 
        //蛇的初始状态有五个节点。
        addNode();
        addNode();
        addNode();
        addNode();
}
 
//移动过程中除了要增加节点,还要删除节点。
void deleteNode()
{
        struct Snake *p = NULL;
        p = head;
        head = head->next;
 
        free(p);
}
 
int snakeDie()
{
        struct Snake *p = NULL;
        p = head;
 
        if(tail->row < 0||tail->row == 20||tail->column == 0||tail->column == 20)
        {
                return 1;
        }
 
        while(p->next != NULL){
                if(p->row == tail->row && p->column == tail->column){
                        return 1;
                }
                p = p->next;
        }
        return 0;
}
 
void moveSnake()
{
        addNode();
 
        if(setFood(tail->row,tail->column)){
                initFood();
        }else{
                deleteNode();
        }
 
        if(snakeDie())
        {
                initSnake();
        }
}
 
void* refreshWindow()
{
        while(1)
        {
                moveSnake();
                gameMap();
                refresh();
                usleep(105000);
        }
}
 
void turn(int direction)
{
        if(abs(dir) != abs(direction))
        {
                dir =direction;
        }
}
 
void* changeDir()
{
        while(1)
        {
                key = getch();
                switch(key)
                {
                        //这四个为ncurses自带的表示方向的宏。
                        case KEY_DOWN:
                                turn(DOWN);
                                break;
                        case KEY_UP:
                                turn(UP);
                                break;
                        case KEY_LEFT:
                                turn(LEFT);
                                break;
                        case KEY_RIGHT:
                                turn(RIGHT);
                                break;
                }
        }
}
 
int main()
{
        pthread_t t1;
        pthread_t t2;
    
    //三行代码初始化游戏。
        initscr();
        keypad(stdscr,1); 
        noecho();
 
        initSnake();
        gameMap();
 
        pthread_create(&t1,NULL,refreshWindow,NULL);
        pthread_create(&t2,NULL,changeDir,NULL);
        while(1);
 
        getch();
        endwin();
        return 0;
}

代码编译:

效果示例:

相关文章
|
9月前
|
机器学习/深度学习 自然语言处理 算法
小红书:通过商品标签API自动生成内容标签,优化社区推荐算法
小红书通过商品标签API自动生成内容标签,提升推荐系统精准度与用户体验。流程包括API集成、标签生成算法与推荐优化,实现高效率、智能化内容匹配,助力社交电商发展。
|
人工智能 供应链 监控
数字孪生与农业:精准农业的发展趋势
数字孪生技术正逐步渗透到农业生产的各个环节,通过创建物理实体的数字副本,实现对实体状态的精确模拟和预测。在农业领域,这一技术的应用正引领着精准农业的发展趋势,包括智慧栽培、环境智能控制、精准农业管理和农业供应链优化等方面,为农业生产的智能化、高效化和可持续发展提供了强大的技术支持。
|
9月前
|
存储 数据挖掘 Windows
服务器数据恢复—RAIDZ上层ZFS文件系统数据恢复案例
一台服务器有32块硬盘,采用Windows操作系统。 服务器在正常运行的时候突然变得不可用。没有异常断电、进水、异常操作、机房不稳定等外部因素。服务器管理员重启服务器,但是服务器无法进入系统。管理员联系北亚企安数据恢复工程师要求恢复服务器数据。
|
机器学习/深度学习 计算机视觉
《深度剖析:残差连接如何攻克深度卷积神经网络的梯度与退化难题》
残差连接通过引入“短路”连接,解决了深度卷积神经网络(CNN)中随层数增加而出现的梯度消失和退化问题。它使网络学习输入与输出之间的残差,而非直接映射,从而加速训练、提高性能,并允许网络学习更复杂的特征。这一设计显著提升了深度学习在图像识别等领域的应用效果。
852 13
|
安全 前端开发 区块链
元宇宙的智能合约有哪些实际应用案例
在元宇宙中,智能合约驱动着多种应用:土地(如Decentraland的Parcel)交易透明安全;智能物品如广告牌,展示互动内容受合约控制;虚拟商品买卖自动化;游戏资产和奖励通过合约发行与管理;租赁协议及数字身份权限由合约保障。这些应用增强了互动体验并确保了交易安全。
|
存储 安全 芯片
U盘在电脑上读不出来怎么办?6个方法帮你修复U盘
平时在存储和传输数据的时候,我们经常会使用到U盘这种存储设备。U盘容量大,使用方便且便于携带,很受欢迎。 然而,在日常使用中,有时候会遇到U盘插入电脑后无法被电脑识别或读取的情况。这会让人感到困扰,因为我们无法访问U盘里的文件。遇到这种情况该怎么办呢?今天的内容会讨论一下U盘无法读取的症状、分析一下常见原因并且提供6个方法帮你修复U盘。
|
网络协议 Ubuntu Linux
在Linux中,如何将本地80端口的请求转发到8080端口,当前主机IP为192.168.16.1,其中本地网卡eth0。
在Linux中,如何将本地80端口的请求转发到8080端口,当前主机IP为192.168.16.1,其中本地网卡eth0。
|
人工智能 自然语言处理 搜索推荐
通义大模型落地手机芯片!离线环境可流畅运行多轮AI对话
通义大模型落地手机芯片!离线环境可流畅运行多轮AI对话
680 0
|
机器学习/深度学习 自然语言处理 算法
LangChain 构建问题之AgentExecutor的定义如何解决
LangChain 构建问题之AgentExecutor的定义如何解决
729 0
|
算法 安全 数据安全/隐私保护
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析(一)
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析
1579 0