C语言·贪吃蛇游戏(下)
上节我们将要完成贪吃蛇游戏所需的前置知识都学完了,那么这节我们就开始动手写代码了
1. 程序规划
首先我们应该规划好我们的代码文件,设置3个文件:snack.h 用来声明游戏中实现各种功能的函数,snack.c 用来实现函数,test.c 用来测试和运行这个游戏
然后我们将游戏的大概流程在test.c文件中写出来,因为我们会用到宽字符,所以要记得适配本地中文环境
2. 游戏数据结构设计
2.1 蛇身数据结构(链表)
我们设计用链表来表示蛇身,链表的每个节点中需要存这节蛇身的坐标 x、y 和下一节点的地址,然后我们给蛇身节点结构体类型改个好写一点的名字
链表的基础知识:数据结构·单链表-CSDN博客
2.2 维护整个游戏的结构体
我们还要创建一个结构体,用来存放当前游戏的种种状态
3. 游戏开始前的初始化
游戏的开始前初始化都在GameStart()函数中实现,那么我们着手开始写这个函数。
首先,我们要先创建维护贪吃蛇游戏的结构体,将它的信息传到GameStart()中去,在snack.h中声明这函数,然后再在snack.c中实现它
我们把这个函数种封装的功能先都展示出来,之后就不重复展示了
3.1 控制台信息设置及光标隐藏
控制台为了美观我们设置成100列30行的,名字就叫做贪吃蛇
运行以下发现控制台设置好了,并且光标也很好的隐藏了起来
3.2 打印欢迎信息
WelcomeToGame()函数内部的大部分东西我们上节其实已经写过了,下面就展示一下
3.3 打印地图
地图大小我们上节已经说过了,要设计一个27行58列的棋盘,然后我们用一个宏把每块墙写出来,方便写打印语句
在打印墙的时候上边界和下边界挨着打印就行,左边界和右边界的时候要在每次打印之前把光标都定一下位
展示打印地图的代码:
3.4 初始化蛇
蛇身我们采用链表的结构进行管理。最开始,我们展示5个蛇身,初始的蛇尾巴从(24,5)的位置开始,向右5节之后是蛇头,这里我们采用头插的方式依次创建节点并加入蛇身中。
同时定义蛇尾初始位置的宏和蛇身形状的宏
最后将贪吃蛇的所有状态进行初始化
3.5 创建食物
创建食物时不能随意创建的,要满足一下四点要求:
1. 食物是随机出现的,就是说坐标是随机的
2. 坐标必须在墙内 (x:2~54 y:1~25)
3. 坐标不能在蛇身上
4. 横坐标必须是偶数
创建的食物其实就相当于蛇的一段身体,所以我们之间用蛇身节点的结构体类型保存食物的()(位置)信息就行,然后食物的创建要满足上面的要求,最后要注意的是,我们想要生成真随机数,就不要忘了在程序开始时给rand()函数种种子srand()
4. 游戏的运行过程
下面我们来完成GameRun()函数,首先将这个函数中要实现的功能理出来
4.1 打印帮助信息
这个没啥好说的,定好位打印就行
4.2 按键逻辑
写一个do···while循环,当游戏状态是OK的情况下就一直循环,持续检测按键的状态,同时在这里把帮助信息也写一下。我们检测按键的时候写一个宏 KEY_PRESS 内容跟上节的一样,这里我就不展示了,最后我会把所有代码都贴出来的
pause()函数
4.3 蛇的移动(走一步)
这里我们的策略是在蛇头前面再创建一个节点,用来判断蛇要走的下一个位置是否有食物,这里要注意,当蛇向下走的时候不能直接向上走,向右走的时候不能像左走,以此类推。蛇的下一步的位置信息先全都存在新创建的节点中,等待接入蛇身
4.3.1 蛇头下一步是食物
4.3.2 蛇头下一步不是食物
4.3.3 检测撞墙
撞墙简单,判断一下蛇头横纵坐标有没有跟墙重合就行
4.3.4 检测撞自己
同理,蛇头的横纵坐标没有跟自身重合就行
5. 游戏结束善后的工作
善后工作其实就是打印一下蛇的死亡原因,然后把,malloc的内存都释放掉
6. 复玩功能
复玩功能我们之前已经写过很多次了,像扫雷中就有很详细的介绍,这里我就简单写一下了
扫雷请参考:函数·扫雷游戏-CSDN博客
7. 完整代码
snack.h
#include<locale.h>
#include<stdlib.h>
#include<stdio.h>
#include<Windows.h>
#include<stdbool.h>
#include<time.h>#define WALL L'□'
#define BODY L'●'
#define FOOD L'★'//蛇默认的起始坐标
#define POS_X 24
#define POS_Y 5#define KEY_PRESS(vk) ((GetAsyncKeyState(vk) & 0x1) ? 1 : 0)//游戏当前状态
enum GAME_STATUS
{OK = 1,//游戏正常运行ESC,//玩家按esc要退出KILL_BY_WALL,//蛇撞墙死KILL_BY_SELF //蛇撞自己死
};//当前蛇在向哪个方向移动
enum DIRECTION
{UP = 1,DOWN,LEFT,RIGHT
};//蛇身节点
typedef struct SnakeNode
{int x;int y;struct SnakeNode* next;
}SnakeNode, * pSnakeNode;//贪吃蛇
typedef struct Snake
{pSnakeNode pSnake;//蛇头位置pSnakeNode pFood;//指向食物的指针int Score;//当前累计的分数int FoodWeight;//一个食物的分数//蛇休眠的时间//休眠时间越短,蛇移动的越块int SleepTime;enum GAME_STATUS status;//游戏当前的状态enum DIRECTION dir;//蛇当前走的方向//···
}Snake, * pSnake;//修改光标位置
void SetPos(int x, int y);//游戏开始前的初始化
void GameStart(pSnake ps);//打印欢迎信息
void WelcomeToGame();
//创建地图
void CreateMap();
//初始化蛇
void InitSnake(pSnake ps);
//创建食物
void CreateFood(pSnake ps);//游戏的运行过程
void GameRun(pSnake ps);//打印帮助信息
void PrintHelpInfo();
//蛇的移动
void SnakeMove(pSnake ps);
//蛇头下一步要走的坐标是否是食物
int NextIsFood(pSnake ps,pSnakeNode pNext);
//是食物就吃掉
void EatFood(pSnake ps, pSnakeNode pNext);
//不是食物就走一步
void NotEatFood(pSnake ps, pSnakeNode pNext);
//检测撞墙
void KillByWall(pSnake ps);
//检测撞自己
void KillBySelf(pSnake ps);//游戏结束善后的善后工作
void GameEnd(pSnake ps);
snack.c
#include"snack.h"//修改光标位置
void SetPos(int x, int y)
{//获得设备句柄HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//根据句柄设置光标位置COORD pos = { x,y };SetConsoleCursorPosition(handle, pos);
}
//打印欢迎信息
void WelcomeToGame()
{//欢迎界面SetPos(38, 12);printf("欢迎来到贪吃蛇小游戏\n");SetPos(40, 20);system("pause");system("cls");//清空屏幕//操作介绍界面SetPos(20, 10);printf("用 ↑ . ↓ . ← . → 分别控制蛇的移动, F3为加速,F4为减速\n");SetPos(37, 12);printf("加速能得到更高的分数\n");SetPos(40, 20);system("pause");system("cls");//清空屏幕}//打印地图
void CreateMap()
{int i = 0;//上边界SetPos(0, 0);for (i = 0; i <= 56; i += 2){wprintf(L"%lc", WALL);}//下边界SetPos(0, 26);for (i = 0; i <= 56; i += 2){wprintf(L"%lc", WALL);}//左边界for (int i = 1; i <= 25; i++){SetPos(0, i);wprintf(L"%lc", WALL);}//右边界for (int i = 1; i <= 25; i++){SetPos(56, i);wprintf(L"%lc", WALL);}
}//初始化蛇
void InitSnake(pSnake ps)
{pSnakeNode cur = NULL;int i = 0;for (i = 0; i < 5; i++){cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL)//节点创建失败{perror("InitSnake():malloc()");return;}cur->x = POS_X + 2 * i;cur->y = POS_Y;cur->next = NULL;//头插法if (ps->pSnake == NULL){ps->pSnake = cur;}else{cur->next = ps->pSnake;ps->pSnake = cur;}}//打印蛇身cur = ps->pSnake;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//贪吃蛇的其他信息初始化ps->dir = RIGHT;ps->FoodWeight = 10;ps->pFood = NULL;ps->Score = 0;ps->SleepTime = 200;ps->status = OK;
}//创建食物
void CreateFood(pSnake ps)
{int x = 0, y = 0;again:do{//当x不是偶数就再生成一次x = rand() % 53 + 2;y = rand() % 24 + 1;} while (x % 2 != 0);//坐标和蛇的身体的每个节点坐标比较pSnakeNode cur = ps->pSnake;while (cur){if (x == cur->x && y == cur->y){goto again;}cur = cur->next;}//创建食物pSnakeNode pFood = (pSnakeNode)malloc(sizeof(SnakeNode));if (pFood == NULL){perror("CreateFood():malloc()");return;}//食物其实就相当于一段蛇身,吃了之后把它接上去就行pFood->x = x;pFood->y = y;ps->pFood = pFood;SetPos(x, y);wprintf(L"%lc", FOOD);
}//游戏开始前的初始化
void GameStart(pSnake ps)
{//控制台信息设置system("mode con cols=100 lines=30");system("title 贪吃蛇");//隐藏光标HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息CursorInfo.bVisible = false;SetConsoleCursorInfo(handle, &CursorInfo);//打印欢迎信息WelcomeToGame();//打印地图CreateMap();//初始化蛇InitSnake(ps);//创建食物CreateFood(ps);
}void PrintHelpInfo()
{SetPos(62,15);printf("1. 不能撞墙,不能咬到自己");SetPos(62, 16);printf("2. 用 ↑ ↓ ← → 控制蛇的移动"); SetPos(62, 17);printf("3. F3为加速,F4为减速");}void pause()
{while (1){Sleep(100);if (KEY_PRESS(VK_SPACE)){break;}}
}//蛇头下一步要走的坐标是否是食物
int NextIsFood(pSnake ps, pSnakeNode pNext)
{if (ps->pFood->x == pNext->x && ps->pFood->y == pNext->y){//下一个坐标是食物return 1;}else{//不是食物return 0;}
}//是食物就吃掉
void EatFood(pSnake ps, pSnakeNode pNext)
{//是食物就把新节点头插pNext->next = ps->pSnake;ps->pSnake = pNext;//打印整条蛇pSnakeNode cur = ps->pSnake;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//得分ps->Score += ps->FoodWeight;//释放被吃掉的食物free(ps->pFood);//新建一个食物CreateFood(ps);
}//不是食物就走一步
void NotEatFood(pSnake ps, pSnakeNode pNext)
{//先把新节点头插进去pNext->next = ps->pSnake;ps->pSnake = pNext;//再释放一个蛇尾pSnakeNode pcur = ps->pSnake;while (pcur->next->next){//这里捎带着把新蛇身打印SetPos(pcur->x, pcur->y);wprintf(L"%lc", BODY);pcur = pcur->next;}//先将尾节点的位置打印空白字符SetPos(pcur->next->x, pcur->next->y);printf(" ");//打印两个空格//最后freefree(pcur->next);pcur->next = NULL;
}//检测撞墙
void KillByWall(pSnake ps)
{if (ps->pSnake->x == 0 || \ps->pSnake->x == 56 || \ps->pSnake->y == 0 || \ps->pSnake->y == 26){ps->status = KILL_BY_WALL;}
}//检测撞自己
void KillBySelf(pSnake ps)
{//从蛇头的下一个节点开始判断pSnakeNode cur = ps->pSnake->next;while (cur){if (cur->x == ps->pSnake->x && cur->y == ps->pSnake->y){//撞到自己身上了ps->status = KILL_BY_SELF;return;}cur = cur->next;}
}//蛇的移动
void SnakeMove(pSnake ps)
{//在蛇头前创建一个检测下一个节点是什么的节点pSnakeNode pNext = (pSnakeNode)malloc(sizeof(SnakeNode));if (pNext == NULL){perror("SnakeMove():malloc()");return;}pNext->next = NULL;switch (ps->dir){case UP:pNext->x = ps->pSnake->x;pNext->y = ps->pSnake->y - 1;break;case DOWN:pNext->x = ps->pSnake->x;pNext->y = ps->pSnake->y + 1;break;case LEFT:pNext->x = ps->pSnake->x - 2;pNext->y = ps->pSnake->y;break;case RIGHT:pNext->x = ps->pSnake->x + 2;pNext->y = ps->pSnake->y;break;}//蛇头下一步要走的坐标是否是食物if (NextIsFood(ps, pNext)){//是食物就吃掉EatFood(ps, pNext);}else{//不是食物就走一步NotEatFood(ps, pNext);}//检测撞墙KillByWall(ps);//检测撞自己KillBySelf(ps);
}//游戏的运行过程
void GameRun(pSnake ps)
{//打印帮助信息PrintHelpInfo();do{//当前的分数情况SetPos(62, 10);printf("总分:%d", ps->Score);SetPos(62, 11);printf("食物的分值:%02d", ps->FoodWeight);//检测按键//上、下、左、右、ESC、空格、F3、F4if (KEY_PRESS(VK_UP) && ps->dir != DOWN){ps->dir = UP;}else if (KEY_PRESS(VK_DOWN) && ps->dir != UP){ps->dir = DOWN;}else if (KEY_PRESS(VK_LEFT) && ps->dir != RIGHT){ps->dir = LEFT;}else if (KEY_PRESS(VK_RIGHT) && ps->dir != LEFT){ps->dir = RIGHT;}else if (KEY_PRESS(VK_ESCAPE)){//退出游戏ps->status = ESC;break;}else if (KEY_PRESS(VK_SPACE)){//暂停游戏pause();}else if (KEY_PRESS(VK_F3)){//睡眠时间不能无限减小,控制一下if (ps->SleepTime >= 80){//加速,休眠时间变短ps->SleepTime -= 30;//每个食物得分增加ps->FoodWeight += 2;}}else if (KEY_PRESS(VK_F4)){//睡眠时间不能无限减小,控制一下if (ps->FoodWeight > 2){//减速,休眠时间变长ps->SleepTime += 30;//每个食物得分减少ps->FoodWeight -= 2;}}//睡眠一下Sleep(ps->SleepTime);//蛇的移动SnakeMove(ps);} while (ps->status == OK);
}//游戏结束善后的善后工作
void GameEnd(pSnake ps)
{SetPos(20, 11);switch (ps->status){case ESC:printf("正常退出\n");break;case KILL_BY_WALL:printf("很遗憾,撞墙了!游戏结束\n");break;case KILL_BY_SELF:printf("很遗憾,自杀了!游戏结束\n");break;}//释放贪吃蛇的链表资源pSnakeNode cur = ps->pSnake;pSnakeNode del = ps->pSnake;while (cur){del = cur;cur = cur->next;free(del);}ps->pSnake = NULL;//释放食物节点free(ps->pFood);ps->pFood = NULL;}
test.c
#include"snack.h"void test()
{int ch;//getchar()返回的是整形ASCII码值do{//创建贪吃蛇游戏Snake snake = { 0 };GameStart(&snake);//游戏开始前的初始化GameRun(&snake);//游戏的运行过程GameEnd(&snake);//游戏结束善后的工作SetPos(25, 15);printf("再来一局吗?(Y/N):>");ch = getchar();getchar();//清理缓冲区的\n} while (ch == 'Y');
}int main()
{srand((unsigned int)time(NULL));//修改适配本地中文环境setlocale(LC_ALL, "");//贪吃蛇游戏的测试test();//控制程序退出结语的位置SetPos(0, 27);return 0;
}
8. 结语
那么到此,贪吃蛇游戏就写好了,当然,这个游戏的功能还有美观度还有待各位共同开发,如果说想要给这个游戏图形化一下,大家可以去 easyX 看看EasyX Graphics Library for C++,把这个库下载下来应该就能在VS上用了
同时,我们的C语言讲解就告一段落了,下一阶段我将着手数据结构的相关知识
相关文章:

C语言·贪吃蛇游戏(下)
上节我们将要完成贪吃蛇游戏所需的前置知识都学完了,那么这节我们就开始动手写代码了 1. 程序规划 首先我们应该规划好我们的代码文件,设置3个文件:snack.h 用来声明游戏中实现各种功能的函数,snack.c 用来实现函数,t…...

Flask 入门2:路由
1. 前言 在上一节中,我们使用到了静态路由,即一个路由规则对应一个 URL。而在实际应用中,更多使用的则是动态路由,它的 URL是可变的。 2. 定义一个很常见的路由地址 app.route(/user/<username>) def user(username):ret…...

【C++】 C++入门— 基于范围的 for 循环
C 基于范围的for循环1 使用样例2 使用条件3 完善措施 Thanks♪(・ω・)ノ谢谢阅读!下一篇文章见!!! 基于范围的for循环 1 使用样例 使用for循环遍历数组,我们通常这么写: …...

C++——析构函数
C——析构函数 什么是析构函数 析构函数是C中的一个特殊的成员函数,它在对象生命周期结束时被自动调用,用于执行对象销毁前的清理工作。析构函数特别重要,尤其是在涉及动态分配的资源(如内存、文件句柄、网络连接等)…...

Vue3学习记录(二)--- 组合式API之计算属性和侦听器
一、计算属性 1、简介 计算属性computed(),用于根据依赖的响应式变量的变化,进行自动的计算,并返回计算后的结果。当依赖的响应式变量发生变化时,computed()会自动进行重新计算,并返回最新的计算结果。如果依赖的…...

react-virtualized实现行元素不等高的虚拟列表滚动
前言: 当一个页面中需要接受接口返回的全部数据进行页面渲染时间,如果数据量比较庞大,前端在渲染dom的过程中需要花费时间,造成页面经常出现卡顿现象。 需求:通过虚拟加载,优化页面渲染速度 优点࿱…...

Linux系统各目录作用
/etc文件系统 /etc 目录包含各种系统配置文件,下面说明其中的一些。其他的你应该知道它们属于哪个程序,并阅读该程序的m a n页。许多网络配置文件也在/etc 中。 1. /etc/rc或/etc/rc.d或/etc/rc?.d 启动、或改变运行级时运行的脚本或脚本的目录。 2. /…...

嵌入式系统学习(一)
嵌入式现状(UP经历): 大厂的招聘要求: 技术栈总结: 产品拆解网站: 52audio 方案查询网站iotku,我爱方案网, 主要元器件类型:...

重写Sylar基于协程的服务器(3、协程模块的设计)
重写Sylar基于协程的服务器(3、协程模块的设计) 重写Sylar基于协程的服务器系列: 重写Sylar基于协程的服务器(0、搭建开发环境以及项目框架 || 下载编译简化版Sylar) 重写Sylar基于协程的服务器(1、日志模…...

Linux之系统安全与应用续章
目录 一. PAM认证 1.2 初识PAM 1.2.1 PAM及其作用 1.2.2 PAM认证原理 1.2.3 PAM认证的构成 1.2.4 PAM 认证类型 1.2.5 PAM 控制类型 二. limit 三. GRUB加密 /etc/grub.d目录 四. 暴力破解密码 五. 网络扫描--NMAP 六. 总结 一. PAM认证 1.2 初识PAM PAM是Linux系…...

《HTML 简易速速上手小册》第7章:HTML 多媒体与嵌入内容(2024 最新版)
文章目录 7.1 在HTML中嵌入视频和音频7.1.1 基础知识7.1.2 案例 1:嵌入视频文件7.1.3 案例 2:嵌入音频文件7.1.4 案例 3:创建一个视频和音频混合的播放列表 7.2 使用 <iframe> 嵌入外部内容7.2.1 基础知识7.2.2 案例 1:嵌入…...

【CSS】移动端适配
移动端适配怎么做? 适配的目的是在屏幕大小不同的终端设备拥有统一的界面,让拥有更大屏幕的终端展示更多的内容。 meta viewport (视口) 移动端初始视口的大小默认是980px,因为世界上绝大多数PC网页的版心宽度为980px ,如果网页…...

DFS剪枝算法经典题目-挑选
4954. 挑选 - AcWing题库 给定一个包含 n 个正整数 a1,a2,…,an的集合。 集合中可能存在数值相同的元素。 请你从集合中挑选一些元素,要求同时满足以下所有条件: 被选中元素不少于 2 个。所有被选中元素之和不小于 l 且不大于 r。所有被选中元素之中最大…...

考研经验总结——考试期间
文章目录 一、订房二、看考场三、休息四、考前带宾馆的书五、安全 一、订房 我刚刚看了看,是9.10号订的酒店。你们可以提前向学长学姐打听你的考场在哪个学校(徐州的考生,考省外的学校是在矿大考试,考省内的学校是在江师大&#…...

vue3 源码解析(6)— lifecycle 生命周期的实现
前言 对于 vue3 的生命周期,我们经常性会去疑问,生命周期有哪些呢,它是怎么去实现的, 又是什么时候调用的。 vue3 生命周期有哪些 下面这个表格列出了所有选项式api生命周期钩子和组合式api生命周期钩子,以及他们的…...

three.js CSS2DRenderer、CSS2DObject渲染HTML标签
有空的老铁关注一下我的抖音: 效果: <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red;position: relative;"><…...

SECS/GEM300和半导体e84控制器
SECS(SEMI EQUIPMENT COMMUNICATIONS STANDARD 2)半导体设备通讯标准 GEM(Generic Equipment Model)定义了Fab中各个场景下设备行为及其所使用SECS消息。 GEM300也称为300mm标准,FAB是12寸设备的处理作业规范。主要包…...

k8s二进制及负载均衡集群部署详解
目录 常见部署方式 二进制部署流程 环境准备 操作系统初始化配置 关闭防火墙 配置SELinux 关闭SWAP 根据规划设置主机名 在master添加hosts,便于主机名解析 调整内核参数 配置时间同步 部署docker引擎 在所有node节点部署docker引擎 部署etcd集群 签发…...

【Django开发】0到1开发美多商城项目第3篇:用户注册业务实现(附代码,已分享)
本系列文章md笔记(已分享)主要讨论django商城项目相关知识。项目利用Django框架开发一套前后端不分离的商城项目(4.0版本)含代码和文档。功能包括前后端不分离,方便SEO。采用Django Jinja2模板引擎 Vue.js实现前后端…...

免费的ppt网站分享
前言 相信大学生们深有体会,对于学校而言,好像是任何活动都需要我们做ppt,当你拿着自己辛苦做的ppt去展示现场的时候,你看到别人的ppt比你的还好,此时心情就是毙,当你知道人家不过是仅仅的1个小时不到就完成…...

基于Transformer结构的扩散模型综述
🎀个人主页: https://zhangxiaoshu.blog.csdn.net 📢欢迎大家:关注🔍点赞👍评论📝收藏⭐️,如有错误敬请指正! 💕未来很长,值得我们全力奔赴更美好的生活&…...

POI操作word表格,添加单元格,单元格对齐方法(不必合并单元格)
添加单元格,直接对row进行create新的cell,则会导致新创建的单元格与前面的单元格不对齐的现象。 //表格信息XWPFTable table doc.createTable();table.setWidth("100%");//第一行XWPFTableRow row0table.getRow(0);XWPFTableCell cell00row0.…...

maven代码规范检查(checkstyle、findbugs)
maven代码规范检查 前言一、使用checkstyle插件1. maven-checkstyle-plugin 介绍2. 接入方式3. 如何排除某个类、包下面的文件不进行检查使用suppressionsLocation 4. 如何关闭 二、使用findbugs插件1.findbugs-maven-plugin介绍2. 接入方式3. 如何排除某个类、包下面的文件不进…...

妙用Java反射,让代码更加优雅
最近在改公司项目bug,需要修改别人的代码。在读别人的源码时感觉到反射真的是能够极大的提高代码的优雅性,在某些特定场景能极大的简化代码的编写。因此写了这篇文章用以记录分享。 我们先还原一下场景,在做数据展示的时候,需要处…...

实习日志10
1.用户信息 1.1.在用户管理中编辑用户信息 1.2.绑定公司id 1.3.显示在页面 2.修改识别逻辑 2.1.分析 先识别,再判断,清空键把识别结果清空 2.2.写码 修改了发票识别逻辑,略... 3.接高拍仪 3.1.js引入报错 分析: 遇到的错误…...

配置alias(设置别名@)
Vite配置alias需要两步进行(TS项目) 1、修改vite.config.ts(让程序支持)2、修改tsconfig.json(让编辑器支持)修改vite.config.ts import { defineConfig } from vite import path from path function…...

【动态规划】【数学】1388. 3n 块披萨
作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode1388 3n 块披萨 给你一个披萨,它由 3n 块不同大小的部分组成,现在你和你的朋友们需要按照如下规则来分披萨: 你挑选 任…...

CS144--Chapter0--wsl2+docker环境搭建
我的笔记本配置 荣耀magicbook16,容量是500G,芯片是R7-5800 由于笔记本容量较小,因此考虑这个方案,对于台式机用户,建议可以直接用虚拟机或者双系统。 前言 斯坦福官网给出的方法是用他们的镜像(基于Ubu…...

MGRE实验报告二
实验要求: 实验预览图: 实验分析: 1、对R1-R5配置IP地址,同时R1-R5每个路由器各有一个环回 2.1、对R1、R3、R4路由器开启虚拟接口1,分别配置隧道IP、接口封装协议,接口类型、定义封装源、开启伪广播功能&…...

算法设计与分析实验:最短路径算法
一、网络延迟时间 力扣第743题 本题采用最短路径的思想进行求解 1.1 具体思路 (1)使用邻接表表示有向图:首先,我们可以使用邻接表来表示有向图。邻接表是一种数据结构,用于表示图中顶点的相邻关系。在这个问题中&am…...