以下是纯C语言实现的经典贪吃蛇游戏(控制台版),完整可直接编译运行的代码。

特点

  • Windows 控制台运行(使用 windows.hconio.h
  • WASD 控制方向(支持反向禁止)
  • 吃食物得分,蛇身变长
  • 难度选择(简单/中等/困难/魔鬼模式)
  • 速度随蛇身增长自动加快
  • 撞墙或咬到自己游戏结束
  • 可重新开始
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <conio.h>

#define frame_height 30   // 地图高度
#define frame_width 50    // 地图宽度
#define UP 'w'
#define DOWN 's'
#define LEFT 'a'
#define RIGHT 'd'

int i, j, k, sp, score;
char ch = UP, state = UP, choo, n;
int grow = 0;

struct Food {
    int x;
    int y;
} food;

struct Snake {
    int x[100];
    int y[100];
    int len;
    int speed;
} snake;

void map(void);
void update_food(void);
void move_snake(void);
int alive(void);
void get_speed(void);
void gotoxy(int x, int y);

int main() {
    do {
        score = 0;
        printf("选择难度:\n1:简单\t2:中等 3:困难\n(其他键进入魔鬼模式)\n");
        n = getch();
        switch (n) {
            case '1': sp = 300; break;
            case '2': sp = 230; break;
            case '3': sp = 180; break;
            default:
                printf("欢迎来到魔鬼难度!\n");
                sp = 120;
                break;
        }
        system("cls");
        map();
        while (1) {
            update_food();
            get_speed();
            move_snake();
            Sleep(snake.speed);
            if (!alive()) {
                break;
            }
        }
        printf("\nGame Over!\n");
        printf("1:重新开始\t2:退出");
        choo = getch();
    } while (choo == '1');
    return 0;
}

void map() {
    srand(time(NULL));
    // 生成食物
    food.x = rand() % (frame_height - 2) + 1;
    food.y = rand() % (frame_width - 2) + 1;
    gotoxy(food.x, food.y);
    printf("$");

    // 初始化蛇
    snake.x[0] = frame_height / 2;
    snake.y[0] = frame_width / 2;
    gotoxy(snake.x[0], snake.y[0]);
    printf("@");
    snake.len = 3;
    snake.speed = 200;
    for (k = 1; k < snake.len; k++) {
        snake.x[k] = snake.x[k - 1] + 1;
        snake.y[k] = snake.y[k - 1];
        gotoxy(snake.x[k], snake.y[k]);
        printf("@");
    }

    // 绘制边框
    for (j = 0; j < frame_width; j++) {
        gotoxy(0, j); printf("#");
        gotoxy(frame_height - 1, j); printf("#");
    }
    for (i = 0; i < frame_height; i++) {
        gotoxy(i, 0); printf("#");
        gotoxy(i, frame_width - 1); printf("#");
    }

    // 显示信息
    gotoxy(2, frame_width + 3);
    if (n == '1') printf("难度:简单");
    else if (n == '2') printf("难度:中等");
    else if (n == '3') printf("难度:困难");
    else printf("魔鬼难度");
    gotoxy(4, frame_width + 3); printf("上: w");
    gotoxy(6, frame_width + 3); printf("下: s");
    gotoxy(8, frame_width + 3); printf("左: a");
    gotoxy(10, frame_width + 3); printf("右: d");
    gotoxy(12, frame_width + 3); printf("得分:%d", score);
    gotoxy(28, frame_width + 3); printf("Made by 重阳");
}

void update_food() {
    if (snake.x[0] == food.x && snake.y[0] == food.y) {
        score += 10;
        gotoxy(12, frame_width + 3);
        printf("得分:%d  ", score);
        // 重新生成食物(避免与蛇身重叠)
        int flag;
        do {
            flag = 1;
            food.x = rand() % (frame_height - 2) + 1;
            food.y = rand() % (frame_width - 2) + 1;
            for (i = 0; i < snake.len; i++) {
                if (food.x == snake.x[i] && food.y == snake.y[i]) {
                    flag = 0;
                    break;
                }
            }
        } while (flag == 0);

        gotoxy(food.x, food.y);
        printf("$");
        snake.len++;
        grow = 1;
    }
}

void move_snake() {
    // 读取键盘输入(非阻塞)
    while (kbhit()) {
        ch = getch();
    }
    // 清尾巴(除非吃到食物)
    if (!grow) {
        gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]);
        printf(" ");
    }
    // 蛇身前移
    for (k = snake.len - 1; k > 0; k--) {
        snake.x[k] = snake.x[k - 1];
        snake.y[k] = snake.y[k - 1];
    }
    // 根据方向移动蛇头
    switch (ch) {
        case UP:
            if (state == DOWN) snake.x[0]++;
            else { snake.x[0]--; state = UP; }
            break;
        case DOWN:
            if (state == UP) snake.x[0]--;
            else { snake.x[0]++; state = DOWN; }
            break;
        case LEFT:
            if (state == RIGHT) snake.y[0]++;
            else { snake.y[0]--; state = LEFT; }
            break;
        case RIGHT:
            if (state == LEFT) snake.y[0]--;
            else { snake.y[0]++; state = RIGHT; }
            break;
        default:  // 保持当前方向
            if (state == UP) snake.x[0]--;
            else if (state == DOWN) snake.x[0]++;
            else if (state == LEFT) snake.y[0]--;
            else if (state == RIGHT) snake.y[0]++;
            break;
    }
    gotoxy(snake.x[0], snake.y[0]);
    printf("@");
    grow = 0;
    gotoxy(frame_height, 0);  // 光标移到底部
}

int alive() {
    // 撞墙
    if (snake.x[0] == 0 || snake.x[0] == frame_height - 1 ||
        snake.y[0] == 0 || snake.y[0] == frame_width - 1)
        return 0;
    // 咬到自己
    for (k = 1; k < snake.len; k++) {
        if (snake.x[0] == snake.x[k] && snake.y[0] == snake.y[k])
            return 0;
    }
    return 1;
}

void get_speed() {
    if (snake.len <= 6) snake.speed = sp;
    else if (snake.len <= 10) snake.speed = sp - 20;
    else if (snake.len <= 20) snake.speed = sp - 50;
    else if (snake.len <= 30) snake.speed = sp - 60;
    else snake.speed = sp - 70;
}

void gotoxy(int x, int y) {
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD cor;
    cor.X = y;
    cor.Y = x;
    SetConsoleCursorPosition(hout, cor);
}

使用方法

  1. 在 Visual Studio、Dev-C++、MinGW 或 VS Code(配置好 gcc)中新建 .c 文件,复制粘贴。
  2. 编译运行即可(Windows 系统)。
  3. 操作:WASD 控制方向,吃 $ 得分,撞墙或咬自己结束。

祝你玩得开心!如果想改成纯标准 C(无 Windows API)或增加更多功能(如存档、音效),随时告诉我,我可以帮你改版~

文章已创建 5021

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部