实现贪吃蛇小游戏

简介: 实现贪吃蛇小游戏

实现前提是:

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

代码编译:

效果示例:

相关文章
|
测试技术 uml 容器
UML之包图(Package Diagram)
UML之包图(Package Diagram)
657 1
|
6月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于贝叶斯优化的自适应马尔科夫链蒙特卡洛(Adaptive-MCMC)算法matlab仿真
本项目基于贝叶斯优化的自适应马尔科夫链蒙特卡洛(Adaptive-MCMC)算法,实现MATLAB仿真,并对比Kawasaki sampler、IMExpert、IMUnif和IMBayesOpt四种方法。核心在于利用历史采样信息动态调整MCMC参数,以高效探索复杂概率分布。完整程序在MATLAB2022A上运行,展示T1-T7结果,无水印。该算法结合贝叶斯优化与MCMC技术,通过代理模型和采集函数优化采样效率。
|
程序员 API C语言
超详细实现【贪吃蛇】(1)
超详细实现【贪吃蛇】(1)
159 2
|
JavaScript 前端开发 API
JS案例:前端Iframe及Worker通信解决思路
JS案例:前端Iframe及Worker通信解决思路
272 0
|
安全 前端开发 区块链
元宇宙的智能合约有哪些实际应用案例
在元宇宙中,智能合约驱动着多种应用:土地(如Decentraland的Parcel)交易透明安全;智能物品如广告牌,展示互动内容受合约控制;虚拟商品买卖自动化;游戏资产和奖励通过合约发行与管理;租赁协议及数字身份权限由合约保障。这些应用增强了互动体验并确保了交易安全。
|
11月前
|
Serverless 数据安全/隐私保护 前端开发
大模型代码能力体验报告之贪吃蛇小游戏《一》:Claude.ai篇 - 生成、预览和快速部署的serverless一条龙
本文介绍了通过Claude.ai生成并优化Web版贪吃蛇游戏的过程,展示了其强大的代码生成功能及用户友好的界面设计。从初始版本的快速生成到根据用户反馈调整游戏速度,再到提供多种实用工具如文件管理、版本控制和一键部署,Claude.ai不仅是一个代码助手,更像是一个全面的serverless开发平台。文中还呼吁国内厂商关注此类技术的发展。
479 2
|
10月前
|
SQL 关系型数据库 数据库连接
"Nacos 2.1.0版本数据库配置写入难题破解攻略:一步步教你排查连接、权限和配置问题,重启服务轻松解决!"
【10月更文挑战第23天】在使用Nacos 2.1.0版本时,可能会遇到无法将配置信息写入数据库的问题。本文将引导你逐步解决这一问题,包括检查数据库连接、用户权限、Nacos配置文件,并提供示例代码和详细步骤。通过这些方法,你可以有效解决配置写入失败的问题。
512 0
|
弹性计算 供应链 并行计算
阿里云ECS包年包月、按量付费、抢占式实例、节省计划和预留实例券付费类型详细说明
阿里云服务器计费多样化:包年包月适合长期服务,预付费且划算;按量付费适合短期项目,后付费、按小时结算;抢占式实例享折扣但可能被释放,适合无状态任务;预留实例券抵扣按量付费账单;节省计划提供承诺使用量的折扣,适用于资源用量稳定或周期性变化的业务。
444 0
|
算法 安全 数据安全/隐私保护
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析(一)
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析
1087 0