贪吃蛇游戏源码(VS编译环境)

贪吃蛇游戏源码(VS编译环境)

🥕个人主页:开敲🍉

🔥所属专栏:C语言🍓

🌼文章目录🌼

1. Snake.h 头文件

2. Snake.c 源文件

3. Test.c 头文件

1. Snake.h 头文件

#include <windows.h>
#include <stdio.h>
#include <stdbool.h>
#include <locale.h>
#include <time.h>


#define INIT_COLS 40
#define INIT_LINES 10

#define WALL L'■'
#define SNAKE_BODY L'●'
#define FOOD L'★'


//蛇的方向
enum SnakeDirection
{
    UP = 1,
    DOWN,
    LEFT,
    RIGHT
};


//游戏状态
enum GameStatus
{
    OK,
    KILL_BY_WALL,
    KILL_BY_SELF,
    END_NORMAL,
    PAUSE
};

//贪吃蛇蛇身的节点
typedef struct SnakeNode
{
    int x;
    int y;
    struct SnakeNode* next;

}SnakeNode;

//贪吃蛇的信息
typedef struct Snake
{
    SnakeNode* snake;//指向蛇头的指针
    SnakeNode* pfood;//指向食物节点的指针
    enum GameStatus sta;//游戏的状态
    enum SnakeDirection dir;//贪吃蛇的方向
    int food_weight;//食物的分数
    int score;//总分
    int sleep_time;//贪吃蛇的速度
}Snake;

//设置光标位置
void SetPos(int x, int y);


//初始化欢迎界面
void InitWelcome();


//创建游戏地图
void CreatGameMap();


//初始化蛇
void InitSnake(Snake* ps);


//创建食物
void CreatFood(Snake* ps);


//调整贪吃蛇
void ModifySnake(Snake* ps);


//移动贪吃蛇
void SnakeMove(Snake* ps);

//吃掉食物
void EatFood(SnakeNode* pnext, Snake* ps);


//不是食物
void NotFood(SnakeNode* pnext, Snake* ps);


//初始化游戏
void InitGame(Snake* ps);


//运行游戏
void GameRun(Snake* ps);


//游戏结束
void GameOver(Snake* ps);

2. Snake.c 源文件

#define KEY_PRESS(VK) ((GetAsyncKeyState(VK)&0x1)?1:0)


#include "Snake.h"

//设置光标位置
void SetPos(int x, int y)
{
    //获取句柄
    HANDLE houtput = NULL;
    houtput = GetStdHandle(STD_OUTPUT_HANDLE);

    //设置光标坐标
    COORD pos = { x,y };
    SetConsoleCursorPosition(houtput, pos);
}


//初始化欢迎界面
void InitWelcome()
{
    system("title 贪吃蛇");
    SetPos(65, 17);
    wprintf(L"欢迎来到贪吃蛇小游戏\n");
    SetPos(68, 24);
    system("pause");
    system("cls");


    SetPos(48, 24);
    wprintf(L"使用 W、A、S、D 或 ↑、↓、←、→ 控制蛇的移动,Shift加速,Ctrl减速");
    SetPos(68, 27);
    system("pause");
    system("cls");

    SetPos(65, 19);
    wprintf(L"加速能够获取更高的分数!");
    SetPos(68, 24);
    system("pause");
    system("cls");
}


//创建游戏地图
void CreatGameMap()
{
    int i = 0;
    SetPos(0, 0);
    for (i = 0; i < 45; i++)
    {
        wprintf(L"%lc", WALL);
    }
    SetPos(0, 34);
    for (i = 0; i < 45; i++)
    {
        wprintf(L"%lc", WALL);
    }
    for (i = 1; i <= 33; i++)
    {
        SetPos(0, i);
        wprintf(L"%lc", WALL);
    }
    for (i = 1; i <= 33; i++)
    {
        SetPos(88, i);
        wprintf(L"%lc", WALL);
    }
    //getchar();
}


//初始化蛇
void InitSnake(Snake* ps)
{
    int i = 0;
    SnakeNode* cur = NULL;
    for (i = 0; i < 5; i++)
    {
        cur = (SnakeNode*)malloc(sizeof(SnakeNode));
        if (cur == NULL)
        {
            perror("InitSnake()::malloc()");
            return;
        }
        cur->next = NULL;
        cur->x = INIT_COLS + i * 2;
        cur->y = INIT_LINES;

        //头插法插入节点
        if (ps->snake == NULL)
        {
            ps->snake = cur;
        }
        else
        {
            cur->next = ps->snake;
            ps->snake = cur;
        }
    }
    cur = ps->snake;
    while (cur)
    {
        SetPos(cur->x, cur->y);
        wprintf(L"%lc", SNAKE_BODY);
        cur = cur->next;
    }
    ps->dir = RIGHT;
    ps->food_weight = 10;
    ps->score = 0;
    ps->sta = OK;
    ps->sleep_time = 200;
}


//创建食物
void CreatFood(Snake* ps)
{
    int x = 0;
    int y = 0;

again:
    do
    {
        x = rand() % 85 + 2;
        y = rand() % 33 + 1;

    } while (x % 2 != 0);

    SnakeNode* cur = ps->snake;
    while (cur)
    {
        if (x == cur->x && y == cur->y)
        {
            goto again;
        }
        cur = cur->next;
    }

    SnakeNode* pFood = (SnakeNode*)malloc(sizeof(SnakeNode));
    pFood->x = x;
    pFood->y = y;
    pFood->next = NULL;

    SetPos(x, y);
    wprintf(L"%lc", FOOD);

    ps->pfood = pFood;

}

//初始化游戏
void InitGame(Snake* ps)
{
    //获取窗口句柄
    HANDLE houtput = NULL;
    houtput = GetStdHandle(STD_OUTPUT_HANDLE);

    //设置光标不可见
    CONSOLE_CURSOR_INFO Cursorinfo;
    GetConsoleCursorInfo(houtput, &Cursorinfo);

    Cursorinfo.bVisible = false;

    SetConsoleCursorInfo(houtput, &Cursorinfo);


    //初始化欢迎界面
    InitWelcome();

    //初始化游戏地图
    CreatGameMap();


    //初始化蛇
    InitSnake(ps);


    //创建食物
    CreatFood(ps);
}


//打印帮助信息
void PrintHelpInfo(Snake* ps)
{
    SetPos(100, 19);
    wprintf(L"%ls", L"使用 W、A、S、D 或 ↑、↓、←、→ 控制蛇的移动");

    SetPos(100, 20);
    wprintf(L"%ls", L"Shift加速(最高N档),Ctrl减速(最高N档)");

    SetPos(100, 21);
    wprintf(L"%ls", L"按ESC退出游戏,按空格开始游戏(暂停游戏)");

    SetPos(114, 25);
    wprintf(L"%ls", L"@开敲制作");
}

//暂停游戏
void Pause()
{
    while (1)
    {
        Sleep(200);
        if (KEY_PRESS(VK_SPACE))
        {
            break;
        }
    }
}


//下一个节点是否是食物
int NextNodeWhetherFood(SnakeNode* pnext, Snake* ps)
{
    return ((pnext->x == ps->pfood->x) && (pnext->y == ps->pfood->y));
}


//吃掉食物
void EatFood(SnakeNode* pnext, Snake* ps)
{
    ps->pfood->next = ps->snake;
    ps->snake = ps->pfood;
    free(pnext);
    pnext = NULL;
    SnakeNode* cur = ps->snake;
    while (cur)
    {
        SetPos(cur->x, cur->y);
        wprintf(L"%lc", SNAKE_BODY);
        cur = cur->next;
    }
    ps->score += ps->food_weight;
    CreatFood(ps);
}


//不是食物
void NotFood(SnakeNode* pnext, Snake* ps)
{
    pnext->next = ps->snake;
    ps->snake = pnext;
    SnakeNode* cur = ps->snake;
    while (cur->next->next)
    {
        SetPos(cur->x, cur->y);
        wprintf(L"%lc", SNAKE_BODY);
        cur = cur->next;
    }
    SetPos(cur->next->x, cur->next->y);
    printf("  ");
    free(cur->next);
    cur->next = NULL;
}

//撞墙
void KillByWall(Snake* ps)
{
    if (ps->snake->x == 0 || ps->snake->x == 88 ||
        ps->snake->y == 0 || ps->snake->y == 34)
        ps->sta = KILL_BY_WALL;
}


//撞到自己
void KillBySelf(Snake* ps)
{
    SnakeNode* cur = ps->snake->next;
    while(cur)
    {
        if (cur->x == ps->snake->x && cur->y == ps->snake->y)
        {
            ps->sta = KILL_BY_SELF;
            break;
        }
        cur = cur->next;
    }
}


//移动贪吃蛇
void SnakeMove(Snake* ps)
{
    SnakeNode* pnext = (SnakeNode*)malloc(sizeof(SnakeNode));
    if (pnext == NULL)
    {
        perror("SnakeMove()::malloc()");
        return;
    }
    pnext->next = NULL;
    switch (ps->dir)
    {
    case UP:
        pnext->x = ps->snake->x;
        pnext->y = ps->snake->y - 1;
        break;
    case DOWN:
        pnext->x = ps->snake->x;
        pnext->y = ps->snake->y + 1;
        break;
    case LEFT:
        pnext->x = ps->snake->x - 2;
        pnext->y = ps->snake->y;
        break;
    case RIGHT:
        pnext->x = ps->snake->x + 2;
        pnext->y = ps->snake->y;
        break;
    }

    if (NextNodeWhetherFood(pnext, ps))
    {
        EatFood(pnext,ps);
    }
    else
    {
        NotFood(pnext,ps);
    }

    //撞墙
    KillByWall(ps);

    //撞到自己
    KillBySelf(ps);
}

//调整贪吃蛇
void ModifySnake(Snake* ps)
{
    do
    {
        SetPos(100, 15);
        wprintf(L"总分数:%2d     当前食物分数:%2d", ps->score, ps->food_weight);
        if ((KEY_PRESS(VK_UP)|| KEY_PRESS(0x57)) && ps->dir != DOWN)
        {
            ps->dir = UP;
        }
        else if ((KEY_PRESS(VK_DOWN)|| KEY_PRESS(0x53)) && ps->dir != UP)
        {
            ps->dir = DOWN;
        }
        else if ((KEY_PRESS(VK_LEFT)|| KEY_PRESS(0x41)) && ps->dir != RIGHT)
        {
            ps->dir = LEFT;
        }
        else if ((KEY_PRESS(VK_RIGHT)|| KEY_PRESS(0x44)) && ps->dir != LEFT)
        {
            ps->dir = RIGHT;
        }
        else if (KEY_PRESS(VK_SPACE))
        {
            //暂停游戏
            Pause();
        }
        else if (KEY_PRESS(VK_ESCAPE))
        {
            //退出游戏
            ps->sta = END_NORMAL;
            return;
        }
        else if (KEY_PRESS(VK_SHIFT))
        {
            //加速
            if (ps->food_weight < 30)
            {
                ps->sleep_time -= 40;
                ps->food_weight += 5;
            }
        }
        else if (KEY_PRESS(VK_CONTROL))
        {
            //减速
            if (ps->food_weight > 5)
            {
                ps->sleep_time += 40;
                ps->food_weight -= 5;
            }
        }
        SnakeMove(ps);//移动贪吃蛇
        Sleep(ps->sleep_time);
    } while (ps->sta == OK);
}


//运行游戏
void GameRun(Snake* ps)
{
    //打印帮助信息
    PrintHelpInfo(ps);
    //调整贪吃蛇
    ModifySnake(ps);
}


//游戏结束
void GameOver(Snake* ps)
{
    int flag = 0;
    SetPos(45, 17);
    switch (ps->sta)
    {
    case END_NORMAL:
        wprintf(L"结束游戏");
        break;
    case KILL_BY_WALL:
        wprintf(L"很遗憾,你撞到墙了");
        break;
    case KILL_BY_SELF:
        wprintf(L"很遗憾,你吃到自己了!");
        break;
    }
}

3. Test.c 头文件

#include "Snake.h"


void SnakeTest()
{
    system("mode con cols=150 lines=40");
    char ch = 0;
    do
    {
        Snake snake = { 0 };
        system("cls");
        //初始化游戏
        InitGame(&snake);


        //运行游戏
        GameRun(&snake);


        //游戏结束
        GameOver(&snake);
        SetPos(45, 19);
        wprintf(L"再来一局?(Y/N):");

        ch = getchar();
        while (getchar() != '\n');
    } while (ch == 'Y' || ch == 'y');
    SetPos(0, 37);
}


int main()
{
    setlocale(LC_ALL, "");
    srand((unsigned int)time(NULL));
    SnakeTest();
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/559529.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

只需几步,即可享有笔记小程序

本示例是一个简单的外卖查看店铺点菜的外卖微信小程序&#xff0c;小程序后端服务使用了MemFire Cloud&#xff0c;其中使用到的MemFire Cloud功能包括&#xff1a; 其中使用到的MemFire Cloud功能包括&#xff1a; 云数据库&#xff1a;存储外卖微信小程序所有数据表的信息。…

二进制OpenStack

二进制搭建OpenStack 1.环境准备 1.1机器的准备 主机名服务器配置操作系统IP地址controller-node4C8Gcentos7.9172.17.1.117computer-node4C8Gcentos7.9172.17.1.118 1.2网络架构 [rootcotroller-node ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noque…

dy号转uid和sec_uid

如何将抖dy号转换为uid和sec_uid&#xff1f; 摘要&#xff1a;本文将介绍如何实dy号与uid、sec_uid之间的转换过程&#xff0c;并提供相关的代码示例。 正文&#xff1a; dy作为一款热门的短视频社交平台&#xff0c;每个用户都有着唯一的用户ID&#xff08;uid&#xff09…

VisualGLM-6B的部署步骤

对于如下命令&#xff0c;你将完全删除环境和环境中的所有软件包 conda remove -n env_name --all 一、VisualGLM-6B环境安装 1、硬件配置 操作系统&#xff1a;Ubuntu_64&#xff08;ubuntu22.04.3&#xff09; GPU&#xff1a;4050 显存&#xff1a;16G 2、配置环境 建…

如何在Windows 11上退出安全模式?这里提供详细步骤

序言 安全模式是对电脑进行故障排除的强大工具。通过仅使用关键和必要的软件和服务启动电脑,它可以帮助你确定后台进程是否干扰了你的正常日常使用,或者是否有任何第三方软件导致电脑出现问题并使其难以使用。 如果你想退出安全模式,最简单的方法是重新启动你的电脑。只要…

Spring Boot入门(17):秒懂Spring Boot整合Knife4j,让你的Swagger界面秒变高颜值

前言 在使用Swagger进行API文档编写时&#xff0c;我们不可避免的会遇到Swagger的一些瓶颈。例如&#xff0c;Swagger的UI界面不太友好&#xff0c;样式单调且难看&#xff0c;交互体验也不是很好。为了解决这些问题&#xff0c;我们可以使用Knife4j对Spring Boot进行整合&…

C++笔记:类和对象(一)

类和对象 认识类和对象 先来回忆一下C语言中的类型和变量&#xff0c;类型就像是定义了数据的规则&#xff0c;而变量则是根据这些规则来实际存储数据的容器。类是我们自己定义的一种数据类型&#xff0c;而对象则是这种数据类型的一个具体实例。类就可以理解为类型&#xff0c…

ViM-UNet:用于生物医学细分的 Vision Mamba

ViM-UNet&#xff1a;用于生物医学细分的 Vision Mamba 摘要IntroductionMethod and Experiments结果与讨论 ViM-UNet: Vision Mamba for Biomedical Segmentation 摘要 卷积神经网络&#xff08;CNNs&#xff09;&#xff0c;尤其是UNet&#xff0c;是生物医学分割的默认架构…

易点易动固定资产管理系统驱动企业高效运营

对于企业来说,固定资产管理一直是一项关键的业务环节。无论是制造企业的生产设备,还是服务企业的办公设备,这些固定资产都是企业运营的基础和支撑。良好的固定资产管理不仅能确保企业的生产经营持续稳定,还能为企业创造更大的价值。 然而,在实际操作中,企业在固定资产管理方面却…

C/C++易错知识点(4):static修饰变量和函数

static是C/C中一个非常容易混淆的语法&#xff0c;在不同的地方针对不同的对象有不同的效果。 它在大型项目中有至关重要的作用&#xff0c;需要我们详细研究。 1.变量 所有static修饰的变量的生命周期都是自调用它起到程序结束&#xff0c;期间这些变量都只会初始化一次 ①…

MT41K128M16JT-125 k功能和参数及ECC功能启用和配置

MT41K128M16JT-125 k功能和参数介绍-公司新闻-配芯易-深圳市亚泰盈科电子有限公司 MT41K128M16JT-125 K 是一款 128Mb&#xff08;16M x 8 位&#xff09;的 DDR3 SDRAM&#xff08;Double Data Rate Third Generation Synchronous Dynamic Random Access Memory&#xff09;芯…

MDC搭配ttl

1.MDC 1.简介 MDC 介绍​ MDC&#xff08;Mapped Diagnostic Context&#xff0c;映射调试上下文&#xff09;是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能。MDC 可以看成是一个与当前线程绑定的Map&#xff0c;可以往其中添加键值对。MDC 中包含的内容可…

kaggle电子邮件分类xgboost建模可视化模型评估混淆矩阵范例

目录 概述 依赖环境 代码解读 库的导入 数据读取 扇形图可视化统计 词云图可视化 分布条形图可视化 数据预处理 划分数据集 模型训练 模型预测和评估 ROC曲线评估 混淆矩阵评估 多维度交叉评估 配套源码和数据集 xgboost邮件分类配套数据集和源码下载地址 概述…

适用于Windows的最佳数据恢复软件合集(免费和付费)

任何数据恢复尝试的结果都取决于您使用的文件恢复软件。作为 Windows 用户&#xff0c;您可以从许多不同的免费和付费应用程序中进行选择&#xff0c;以至于很容易遇到决策瘫痪并浪费宝贵的时间&#xff0c;而这些时间本来可以更好地用于恢复数据。 为了帮助您做出正确的选择&…

手机app抓包流程(fiddler)

废话不多说直接开始&#xff1a; 1.先下载fiddler&#xff0c;一款抓包软件&#xff08;下载地址后续补充&#xff0c;或自行查找&#xff09;&#xff1a; 2.同意并安装 3.安装好后启动&#xff0c;找到options进行配置&#xff1a; 4.https部分勾选至下图效果&#xff1a; 5…

百度AI大会发布的APP Builder和Agent Builder有什么区别

百度在AI大会发布了三款AI工具&#xff0c;包括智能体开发工具AgentBuilder、AI原生应用开发工具AppBuilder、各种尺寸的模型定制工具ModelBuilder 有很多人就问&#xff0c;APP Builder和Agent Builder有什么不一样&#xff0c;怎么那么多builder? 你们就这么理解&#xff…

Keepalived+LVS+nginx搭建nginx高可用集群

一、简介 nginx是一款非常优秀的反向代理工具&#xff0c;支持请求分发&#xff0c;负载均衡&#xff0c;以及缓存等等非常实用的功能。在请求处理上&#xff0c;nginx采用的是epoll模型&#xff0c;这是一种基于事件监听的模型&#xff0c;因而其具备非常高效的请求处理效率…

【漏洞复现】锐捷 EG易网关 phpinfo.view.php 信息泄露漏洞

0x01 产品简介 锐捷EG易网关是一款综合网关产品&#xff0c;集成了先进的软硬件体系构架&#xff0c;并配备了DPI深入分析引擎、行为分析/管理引擎。这款产品能在保证网络出口高效转发的基础上&#xff0c;提供专业的流控功能、出色的URL过滤以及本地化的日志存储/审计服务。 …

【传输层】

文章目录 传输层传输服务和协议传输层 vs. 网络层Internet传输层协议多路复用/解复用在发送方主机多路复用在接收方主机多路解复用 多路解复用工作原理无连接&#xff08;UDP&#xff09;多路解复用无连接传输&#xff1a;UDPUDP&#xff1a;用户数据报协议UDP校验和 传输层 目…

Springboot+Vue项目-基于Java+MySQL的图书馆管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…