鱼C论坛

 找回密码
 立即注册
查看: 2200|回复: 5

[技术交流] C 语言贪吃蛇

[复制链接]
发表于 2020-8-27 18:29:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 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)
{
        SNAKEP  temp;
        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;
}

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-27 21:29:27 | 显示全部楼层
看贴回帖是个好习惯
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-27 21:33:37 | 显示全部楼层
weiter 发表于 2020-8-27 21:29
看贴回帖是个好习惯

程序哪里逻辑不对!卡卡的!难搞了!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-27 21:34:04 | 显示全部楼层
Cool_Breeze 发表于 2020-8-27 21:33
程序哪里逻辑不对!卡卡的!难搞了!

我是学Python的……只是路过
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-3 07:20:16 | 显示全部楼层
复制下来 留着学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-5-18 05:58:36 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-13 14:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表