80行C代码实现ncurses版贪吃蛇!_mac自带 ncurses

事情是这样的,周末我在家打开电脑排查现网问题,安德森先生对这个电脑非常感兴趣,凑过来非要看看,我给他演示了sl小火车。小小和疯子也都在旁边看着。

我说这个sl小火车是一个现成的程序,然后就被小小和疯子鄙视了,她们以为这个小火车是我自己做的…搞了半天是下载的现成的东西…

我觉得我得自己做点可以玩的小东西,哪怕再简单的,只要看起来像回事就行,以挽回面子。

还是贪吃蛇最简单,这个东西以前我写过不止一版了:
https://blog.csdn.net/dog250/article/details/5303351
https://blog.csdn.net/dog250/article/details/6787135
https://blog.csdn.net/dog250/article/details/6819996

不过代码都挺长的。这次我想来个简约风格的朴素版本,这次我用ncurses来实现,代码如下:

#include <ncurses.h>
#include <stdlib.h>
#include <string.h>

#define LINES   30
#define COLS    60

int start_x = 10, start_y = 10;
int main(int argc,char* argv[])
{
    int i, j, c, head_x, head_y, tail_x, tail_y, fx, fy;
    // 四个方向矩阵
    char dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    int head_dir_index = 3, tail_dir_index = 3;
    char pad[LINES][COLS];

    initscr();
    noecho();
    keypad(stdscr, 1);
    nodelay(stdscr, 1);
    curs_set(0);

    memset(pad, 0, sizeof(pad));
    pad[start_y][start_x] = 1;
    head_x = tail_x = start_x;
    head_y = tail_y = start_y;
    srand(time(NULL));

    for (i = 0; i < LINES; i ++) {
        pad[i][0] = 1;
        pad[i][COLS - 1] = 1;
    }
    for (i = 0; i < COLS; i ++) {
        pad[0][i] = 1;
        pad[LINES - 1][i] = 1;
    }

    while (1) { // 外层循环表示一次吞食
        fx = rand()%COLS;
        fy = rand()%LINES;
        if (pad[fy][fx] == 1)
            continue;
        pad[fy][fx] = 2;

        while (c = getch()) { // 内层循环描绘吞食的过程
            // 获取蛇头的方向
            if (c == KEY_UP)
                head_dir_index = 0;
            else if (c == KEY_DOWN)
                head_dir_index = 1;
            else if (c == KEY_LEFT)
                head_dir_index = 2;
            else if (c == KEY_RIGHT)
                head_dir_index = 3;
            // 计算蛇头的位置
            head_y += dir[head_dir_index][0];
            head_x += dir[head_dir_index][1];
            if (head_y >= LINES - 1 || head_x >= COLS - 1 || head_x <= 0 || head_y <= 0 ||
                pad[head_y][head_x] == 1) {
                mvprintw(LINES/2, (COLS - 9)/2, "game over");
                refresh();
                sleep(2);
                endwin();
                exit(1);
            }
            // 吃到了食物
            if (pad[head_y][head_x] == 2) {
                pad[head_y][head_x] = 1;
                break;
            }
            pad[head_y][head_x] = 1; // 蛇头前进
            pad[tail_y][tail_x] = 0; // 蛇尾锁进

            // 获取蛇尾的方向
            if (tail_y - 1 > 0 && pad[tail_y - 1][tail_x] == 1)
                tail_dir_index = 0;
            else if (tail_y + 1 < LINES - 1 && pad[tail_y + 1][tail_x] == 1)
                tail_dir_index = 1;
            else if (tail_x - 1 > 0 && pad[tail_y][tail_x - 1] == 1)
                tail_dir_index = 2;
            else if (tail_x + 1 < COLS -1 && pad[tail_y][tail_x + 1] == 1)
                tail_dir_index = 3;
            // 计算蛇尾的位置
            tail_y += dir[tail_dir_index][0];
            tail_x += dir[tail_dir_index][1];
            // 绘制整蛇
            for (i = 0; i < LINES; i ++)
                for (j = 0; j < COLS; j ++)
                    mvprintw(i, j, pad[i][j]?"#":" ");
            refresh();
            usleep(200000);
        }
    }

    return 0;
}

代码在:https://github.com/marywangran/GluttonousSnake

我喜欢这个风格,因为它只需要gcc和libncurses就能编译和执行,完全不依赖任何GUI:

[root@localhost test]# gcc test.c -lncurses

效果如下:
在这里插入图片描述
代码思路很简单,就是 把蛇尾拿开拼到蛇头前面 以模拟蛇移动,那么问题就剩下两个:

  • 如何知道蛇尾在哪里?
  • 如何知道蛇头在哪里?

于是我维护了两个方向:

  • 蛇头方向:取决于上一次按下的方向键。
  • 蛇尾方向:取决于蛇的连接矩阵。

非常简单的思路,没有链表,没有对象,什么都没有,简约,而且非常经理。


浙江温州皮鞋湿,下雨进水不会胖。

原文链接: https://blog.csdn.net/dog250/article/details/107620992

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    80行C代码实现ncurses版贪吃蛇!_mac自带 ncurses

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/405886

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月26日 上午9:29
下一篇 2023年4月26日 上午9:29

相关推荐