C语言实现贪吃蛇demo13贪吃蛇撞墙找死来结束游戏.c

//承上启下
//C语言基础,数据结构链表基础,C变量,流程控制,函数,指针,结构体等。
//Linux系统编程,文件编程,进程,线程,通信,第三方包等。
#include <curses.h>
#include <stdlib.h>
#include <pthread.h>
#define UP    1
#define DOWN  2
#define LEFT  3
#define RIGHT 4

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(); // 初始化curses库
    keypad(stdscr, 1); // 启用键盘输入
}

int hasSnakeNode(int i, int j) // 判断坐标(i, 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) // 判断坐标(i, 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("Bylonghaiyang, 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);
    }
    head = (struct Snake *)malloc(sizeof(struct Snake));
    head->hang = 2;
    head->lie = 2;
    head->next = NULL;
    tail = head;
    addNode(); // 增加初始长度的贪吃蛇身体节点
    addNode();
    addNode();
}

void deleNode() // 删除贪吃蛇的身体节点
{
    struct Snake *p;
    p = head;
    head = head->next;
    free(p);
}

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

void* refreshJieMian() // 刷新界面的线程
{
    while (1) {
        moveSnake();
        gamePic();
        refresh();
        usleep(100000); // 暂停100毫秒
    }
}

void* changeDir() // 监听用户输入的线程
{
    while (1) {
        key = getch();
        switch (key) {
            case KEY_DOWN:
                dir = DOWN;
                break;
            case KEY_UP:
                dir = UP;
                break;
            case KEY_LEFT:
                dir = LEFT;
                break;
            case KEY_RIGHT:
                dir = RIGHT;
                break;
        }
    }
}

int main()
{   
    pthread_t t1;
    pthread_t t2;

    initNcurse();
    initSnake();
	initFood();
    gamePic();
    pthread_create(&t1, NULL, refreshJieMian, NULL); // 创建界面刷新线程
    pthread_create(&t2, NULL, changeDir, NULL); // 创建用户输入监听线程
    while (1);
    getch();
    endwin(); // 结束curses模式
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值