Cool_Breeze 发表于 2020-8-27 18:29:07

C 语言贪吃蛇

本帖最后由 Cool_Breeze 于 2020-8-27 20:34 编辑

# 思路来自(知乎 id = int)int
https://zhuanlan.zhihu.com/p/104575319
# 还有些功能没有写!

/*
@ BY COOL_BREEZE
@ 2020-08-27
*/


#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#include<windows.h>

#define HIGHT 30
#define WIDTH 100

// dos窗口显示模式
#define MODE(X, Y) "MODE CON COLS="#X" LINES="#Y
#define HAD (GetStdHandle(STD_OUTPUT_HANDLE))

// 蛇的结构体开辟内存空间
#define CALLSNAKE ((SNAKEP)malloc(sizeof(SNAKEV)))

void hidecursor(void); // 改变光标的显示方式
void gotoxy_print(int x, int y, char icon); // 移动光标到指定位置打印图标
void __init__(void); // 初始化边框
void create_snake(void); // 生成蛇
void move_snake(void); // 移动蛇
void create_food(void); // 生成食物
void get_keyborad_input(void); // 获取键盘值
int hit_the_wall(void); // 蛇撞墙
void game_method(void);

typedef struct SNAKE
{
        int x;
        int y;
        struct SNAKE* next;
} SNAKEV, *SNAKEP;

SNAKEP SNAKE_HEAD; //蛇头
SNAKEP SNAKE_FOOD; //食物

//蛇前进的方向
#define U 0X48 // 上
#define D 0X50 // 下
#define L 0X4B // 左
#define R 0X4D // 右
#define S 0X7F // 空格 暂停

char DIRECTION = L; // 默认蛇往左边移动
char HEAD_ICON = 0XF;
char BODY_ICON = 0XB;
char FOOD_ICON = 0X24;
char NULL_ICON = 0X20;

int main(void)
{
        system(MODE(130, 30));
        system("title 贪吃蛇游戏");
        game_method();
        hidecursor();
        __init__();
        SNAKE_FOOD = CALLSNAKE;
        create_snake();
        create_food();
        int ser; // 延迟
        while(1)
        {
                ser = 0;
                move_snake();
                if (kbhit()) // 检查键盘是否被按下,非阻塞的 (相当于多线程)
                {
                        get_keyborad_input();
                        Sleep(20);
                        ser = 1;
                }
                if (hit_the_wall())
                {
                        gotoxy_print((WIDTH-8) / 2, HIGHT / 2, NULL_ICON);
                        printf("游戏结束");
                        system("pause >nul");
                        break;
                }
                if (ser)
                        Sleep(10);
                else Sleep(200);
        }
        return 0;
       
}

void hidecursor(void)
{
        CONSOLE_CURSOR_INFO show = {1, 0};
        SetConsoleCursorInfo(HAD, &show);
}

void gotoxy_print(int x, int y, char icon)
{
        COORD poin = {x, y}; // 结构体
        SetConsoleCursorPosition(HAD, poin); // 跳转到窗口指定位置
        printf("%c", icon);
}

void game_method(void)
{
        gotoxy_print(WIDTH + 5, HIGHT/2-7, NULL_ICON);
        printf("DATE 2020-08-27");
        gotoxy_print(WIDTH + 5, HIGHT/2-6, NULL_ICON);
        printf("BY COOL_BREEZE");
        gotoxy_print(WIDTH + 5, HIGHT/2-4, NULL_ICON);
        printf("空格 暂停");
        gotoxy_print(WIDTH + 5, HIGHT/2-3, NULL_ICON);
        printf("向上 ↑");
        gotoxy_print(WIDTH + 5, HIGHT/2-2, NULL_ICON);
        printf("向下 ↓");
        gotoxy_print(WIDTH + 5, HIGHT/2-1, NULL_ICON);
        printf("向左 ←");
        gotoxy_print(WIDTH + 5, HIGHT/2, NULL_ICON);
        printf("向右 →");
}

void __init__(void)
{
        int i = 0;
        gotoxy_print(0, 0, 0X1); // 角落1
        gotoxy_print(WIDTH-1, 0, 0X2); // 角落2
        for (i=1; i<WIDTH-1; i++) // 上下边框
        {
                gotoxy_print(i, 0, 0X6);
                gotoxy_print(i, HIGHT-1, 0X6);
        }
        for (i=1;i<HIGHT-1; i++) // 左右边框
        {
                gotoxy_print(0, i, 0X5);
                gotoxy_print(WIDTH-1, i, 0X5);
        }
        gotoxy_print(0, HIGHT-1, 0X3); // 角落3
        gotoxy_print(WIDTH-1, HIGHT-1, 0X4); // 角落4
}

void create_snake(void)
{
        int i = 0,x = (WIDTH-6) / 2, y = HIGHT / 2; //在中心创建蛇
        SNAKEP phead, pend;
        for (; i<6; i++) // 蛇默认长度为6
        {
                pend = CALLSNAKE;
                if (!i)
                {
                        SNAKE_HEAD = phead = pend;
                        pend->x = x;
                        pend->y = y;
                        gotoxy_print(SNAKE_HEAD->x, SNAKE_HEAD->y, HEAD_ICON);
                }
                else
                {
                        phead->next = pend;
                        pend->x = x + i; // 蛇身体在头右方
                        pend->y = y;
                        gotoxy_print(pend->x, pend->y, BODY_ICON);
                        phead = pend;
                }
        }
        pend->next = NULL;
}

void move_snake(void)
{
        SNAKEP head = CALLSNAKE; // 蛇新的头部
        switch (DIRECTION)
        {
                case U:
                                head->x = SNAKE_HEAD->x;
                                head->y = SNAKE_HEAD->y - 1;
                                break;
                case D:
                                head->x = SNAKE_HEAD->x;
                                head->y = SNAKE_HEAD->y + 1;
                                break;
                case L:
                                head->x = SNAKE_HEAD->x - 1;
                                head->y = SNAKE_HEAD->y;
                                break;
                case R:
                                head->x = SNAKE_HEAD->x + 1;
                                head->y = SNAKE_HEAD->y;
                                break;
                case S:
                                system("pause >nul");
                                break;
        }
        head->next = SNAKE_HEAD; // 旧头部连接新头部 使旧头部成为身体
        SNAKE_HEAD = head; // 获取头部
        if (SNAKE_HEAD->x == SNAKE_FOOD->x && SNAKE_HEAD->y == SNAKE_FOOD->y) // 检查蛇是否吃到食物
        {
                while (head) // 吃到了食物蛇蛇尾不需要释放
                {
                        if (head == SNAKE_HEAD)
                                gotoxy_print(SNAKE_HEAD->x, SNAKE_HEAD->y, HEAD_ICON);
                        else
                                gotoxy_print(head->x, head->y, BODY_ICON);
                        head = head->next;
                }
                create_food();
        }
        else
        {
                while (head->next->next) // 没吃到食物释放掉蛇尾
                {
                        if (head == SNAKE_HEAD)
                                gotoxy_print(SNAKE_HEAD->x, SNAKE_HEAD->y, HEAD_ICON);
                        else
                                gotoxy_print(head->x, head->y, BODY_ICON);
                        head = head->next;
                }
                gotoxy_print(head->next->x, head->next->y, NULL_ICON);
                free(head->next);
                head->next = NULL;
        }
}

void create_food(void)
{
        SNAKEPtemp;
        while (1)
        {
                srand(time(NULL)); // 获取新种子 生成新的随机数
                SNAKE_FOOD->x = rand() % (WIDTH - 2) + 1; // 确保坐标只会出现在表格内(不包括表格)
                SNAKE_FOOD->y = rand() % (HIGHT - 2) + 1; // 确保坐标只会出现在表格内(不包括表格)
                temp = SNAKE_HEAD;
                while(temp) // 食物落在蛇身上重新获取
                {
                        if (temp->x == SNAKE_FOOD->x && temp->y == SNAKE_FOOD->y)
                                continue;
                        else
                        {
                                gotoxy_print(SNAKE_FOOD->x, SNAKE_FOOD->y, FOOD_ICON);
                                break;
                        }
                }
                break;
        }
}

void get_keyborad_input(void)
{
        int key = 0;
    while (1)
    {
      key = getch();
      if (key == 224) // 键盘方向键需要获取两次
      {
            key = getch();
            if (key == U ||\
                key == D ||\
                key == L ||\
                key == R)
            {
                    DIRECTION = key;
                    break;
                        }
            else continue;
      }
    }
}

int hit_the_wall(void)
{
        if (SNAKE_HEAD->x == 0 || SNAKE_HEAD->x == WIDTH-1 ||\
                SNAKE_HEAD->y == 0 || SNAKE_HEAD->y == HIGHT-1 )
                return 1;
        return 0;
}

weiter 发表于 2020-8-27 21:29:27

看贴回帖是个好习惯{:10_254:}

Cool_Breeze 发表于 2020-8-27 21:33:37

weiter 发表于 2020-8-27 21:29
看贴回帖是个好习惯

程序哪里逻辑不对!卡卡的!难搞了!

weiter 发表于 2020-8-27 21:34:04

Cool_Breeze 发表于 2020-8-27 21:33
程序哪里逻辑不对!卡卡的!难搞了!

我是学Python的……只是路过{:10_266:}

zxcbcv 发表于 2020-9-3 07:20:16

复制下来 留着学习{:5_105:}

龙舞九天 发表于 2021-5-18 05:58:36

{:5_95:}
页: [1]
查看完整版本: C 语言贪吃蛇