嵌入式学习第15、16、17天

本文介绍了一个使用C语言和Ncurses库实现的贪吃蛇游戏。游戏包含地图边界、食物生成、蛇身碰撞检测等功能,通过键盘方向键控制蛇的移动。代码中详细展示了如何初始化游戏状态、处理用户输入、更新游戏状态以及绘制游戏画面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c语言综合之基于Ncurses的贪吃蛇

1.运行结果演示
在这里插入图片描述

2.游戏代码

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

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

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

struct Food {
    int hang;
    int lie;
};

int dir = 0;
struct Snake *head = NULL;
struct Snake *tail = NULL;
struct Food *food = NULL;

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

int hasEat() {
    if (tail->hang == food->hang && tail->lie == food->lie) {
        return 1;
    }
    return 0;
}

void addNode(int con) {
    struct Snake *node = (struct Snake *)malloc(sizeof(struct Snake));
    switch (con) {
        case RIGHT: {
            node->hang = tail->hang;
            node->lie = tail->lie + 1;
            break;
        }
        case UP: {
            node->hang = tail->hang - 1;
            node->lie = tail->lie;
            break;
        }
        case LEFT: {
            node->hang = tail->hang;
            node->lie = tail->lie - 1;
            break;
        }
        case DOWN: {
            node->hang = tail->hang + 1;
            node->lie = tail->lie;
            break;
        }
    }
    node->next = NULL;

    tail->next = node;
    tail = node;
}

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

void initFood() {
    food = (struct Food *)malloc(sizeof(struct Food));
    food->hang = rand() % 18 + 1;
    food->lie = rand() % 18 + 1;
}

void initCurses() {
    initscr();
    keypad(stdscr, 1);
}

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

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

int hasNode(int hang, int lie) {
    struct Snake *p = head;
    while (p) {
        if (p->hang == hang && p->lie == lie) {
            return 1;
        }
        p = p->next;
    }
    return 0;
}

int hasFood(int hang, int lie) {
    if (food->hang == hang && food->lie == lie) {
        return 1;
    }
    return 0;
}

int initMap() {
    int hang;
    int lie;
    move(0, 0);

    for (hang = 0; hang < 20; hang++) {
        if (hang == 0 || hang == 19) {
            for (lie = 0; lie < 20; lie++) {
                printw("--");
            }
            printw("\n");
        } else {
            for (lie = 0; lie <= 20; lie++) {
                if (lie == 0 || lie == 20) {
                    printw("|");
                } else if (hasNode(hang, lie)) {
                    printw("[]");
                } else if (hasFood(hang, lie)) {
                    printw("##");
                } else {
                    printw("  ");
                }
            }
            printw("\n");
        }
    }
}

void moveSnake() {
    addNode(dir);
    delHead();
    if (hasDie()) {
        destory_snake();
        initSnake();
        dir = RIGHT;
    } else if (hasEat()) {
        addNode(dir);
        initFood();
    }
}

void *getCon() {
    int c;
    while (1) {
        c = getch();
        switch (c) {
            case KEY_DOWN: {
                if (abs(dir) != abs(DOWN)) {
                    dir = DOWN;
                }
                break;
            }
            case KEY_UP: {
                if (abs(dir) != abs(UP)) {
                    dir = UP;
                }
                break;
            }
            case KEY_RIGHT: {
                if (abs(dir) != abs(RIGHT)) {
                    dir = RIGHT;
                }
                break;
            }
            case KEY_LEFT: {
                if (abs(dir) != abs(LEFT)) {
                    dir = LEFT;
                }
                break;
            }
        }
    }
}
void *Game() {
    while (1) {
        moveSnake();
        initMap();
        usleep(100000);
        refresh();
    }
}

int main() {
    pthread_t th1;
    pthread_t th2;

    initCurses();
    initSnake();
    initFood();
    initMap();
    pthread_create(&th1, NULL, Game, NULL);
    pthread_create(&th2, NULL, getCon, NULL);
    while (1) {
    }
    getch();
    endwin();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值