贪吃蛇项目实现(C语言)——附源码
前言
贪吃蛇是一款十分经典的游戏,其通过控制贪吃蛇的上下左右移动来吃食物,延长自己的身体,也会因为撞到墙体和自身而死亡。下面我们通过C语言来实现贪吃蛇。
1.技术要点
C语言枚举,结构体,链表,动态内存管理,预处理指令,函数,Win32 API等。
2. Win 32 API
要使用Win32 API 我们就需要先了解学习一下Win 32 API。
2.1 Win 32 API
Windows 这个多作业系统除了协调应⽤程序的执行、分配内存、管理资源之外, 它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每⼀种服务就是⼀个函数),可以帮应用程序达到开启 视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序(Application), 所以便 称之为 Application Programming Interface,简称 API 函数。WIN32 API 也就是Microsoft Windows 32位平台的应⽤程序编程接口。
2.2 控制台程序(Console)
我们平时运行起来的黑框程序就是控制台程序
我们可以使用cmd命令来控制窗口的长和宽:设置长100列,宽30行
mode con cols=100 lines=30;
也可以设置控制台窗口的名字:
title 贪吃蛇;
这些控制窗口执行的命令可以通过调用system函数来执行。例如:
#include<stdio.h>
int main()
{
//设置窗口大小为30行,100列
system("mode con cols=100 lines=30");
//设置窗口名称为贪吃蛇
system("title 贪吃蛇");
return 0;
}
2.3 控制坐标COORD
COORD是一个结构体,表示一个字符在控制台屏幕缓冲区上的坐标,坐标系(0,0)的原点位于缓冲区的顶部左侧单元
声明类型:
typedef struct _COORD{short x;short y;}COORD,*PCOORD;
赋值:
COORD pos = {10,15};
2.4 隐藏光标
光标的显示会让贪吃蛇游戏的进行不是很友好,所以我们需要将其隐藏。
2.4.1 GetStdHandle
GetStdHandle 是⼀个Windows API函数。它⽤于从⼀个特定的标准设备(标准输入、标准输出或标 准错误)中取得⼀个句柄(用来标识不同设备的数值),使用这个句柄可以操作设备。
函数的参数:
HANDLE GetStdHandle(DWORD nStdHandle);
实例:
HANDLE houtput = NULL;
houtput = GetStdHandle(STD_OUTPUT_HANDLE);
2.4.2 GetConsoleCursorInfo
检索有关指定控制台屏幕缓冲区的光标大小和可见性的信息;
BOOL WINAPI GetConsoleCursorInfo(HANDLE hConsoleOutput,PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
);
//PCONSOLE_CURSOR_INFO 是指向 CONSOLE_CURSOR_INFO 结构的指针,该结构接收有关主机游标
(光标)的信息
实例:
HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
2.4.3 CONSOLE_CURSOR_INFO
这个结构体,包含有关控制台光标的信息;
typedef sturct _CONSOLE_CURSOR_INFO
{
DWORD dwSize;
BOOL bVisible;
}_CONSOLE_CURSOR_INFO,*P_CONSOLE_CURSOR_INFO;
dwSize,由光标填充的字符单元格的百分比。 此值介于1到100之间。 光标外观会变化,范围从完 全填充单元格到单元底部的水平线条。
• bVisible,游标的可见性。 如果光标可见,则此成员为 TRUE。
CursorInfo.bVisible = false; //光标隐藏
2.4.4 SetConsoleCursorInfo
设置指定控制台屏幕缓冲区的光标的大小和可见性。
BOOL WINAPI SetConsoleCursorInfo(HANDLE hConsoleOutput,const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);
实例:
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态
2.5 封装设置光标位置函数
设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD类型的pos中,调用SetConsoleCursorPosition函数将光标位置设置到指定的位置。
BOOL WINAPI SetConsoleCursorPosition(HANDLE hConsoleOutput,COORD pos
);
实例:
COORD pos = { 10, 5};HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值)hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//设置标准输出上光标的位置为posSetConsoleCursorPosition(hOutput, pos);
封装成函数:
//设置光标的坐标
void SetPos(short x, short y)
{COORD pos = { x, y };HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值)hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//设置标准输出上光标的位置为posSetConsoleCursorPosition(hOutput, pos);
}
3. GetAsyncKeyState
获取按键情况,GetAsyncKeyState的函数原型:
short GetAsyncKeyState(
int vKey
);
将键盘上的虚拟值传递给函数,函数通过返回值来分辨按键状态。
GetAsyncKeyState 的返回值是short类型,在上⼀次调用 GetAsyncKeyState 函数后,如果返回的16位的short数据中,最高位是1,说明按键的状态是按下,如果最高是0,说明按键的状态是抬 起;如果最低位被置为1则说明,该按键被按过,否则为0。 如果我们要判断⼀个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1.
我们通过函数与宏定义来判断键是否被按过。判断依据GetAsyncKeyState函数的返回值的最高位。
实现:
#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )
通过宏定义将函数的结果与1,得到结果,后面再通过多个if表达式实现键值的判断。
4.功能实现
贪吃蛇需要实现一些基本的功能:
1. 地图绘制
2. 蛇吃食物的功能(上、下、左、右方向键控制蛇的动作)
3. 蛇撞墙死亡
4. 蛇撞自身死亡
5. 计算得分
6. 蛇身加速、减速
7.暂停游戏
下面来依次实现这些功能:
4.1 地图绘制
这是贪吃蛇游戏的大纲,我们该如何设置这样的界面呢?
上面讲了,横向为X轴,纵向为y轴,从上到下依次增长。
我们在地图上打印墙体,蛇身,食物的时候需要分别使用使用宽字符□,●,○。
普通字符占一个字节,这类宽字符占两个字节。
4.1.1 <locale.h>本地化
提供的函数⽤于控制C标准库中对于不同的地区会产⽣不⼀样行为的部分。
在标准中,依赖地区的部分有以下几项:
• 数字量的格式
• 货币量的格式
• 字符集
• 日期和时间的表示形式
4.1.1.1类项
通过修改地区,程序可以改变它的行为来适应世界的不同区域。但地区的改变可能会影响库的许多部 分,其中⼀部分可能是我们不希望修改的。所以C语言支持针对不同的类项进行修改,下面的⼀个宏, 指定⼀个类项:
4.1.1.2 setlocale函数
char* setlocale (int category, const char* locale);
第一个函数可以是一个类项,也可以是全部类项,第二个参数有两种取值:“C”(正常模式)和“”(本地模式)。
任意程序执行开始,都会隐藏式执行调用:
setlocale(LC_ALL,"C");
当切换到本地模式后,我们才可以输出宽字符。
setlocale(LC_ALL,"");
setlocale的返回值是字符串指针,表示已经设置好的格式,如果调用失败,则返回空指针NULL。
将第二个参数设置NULL就可以用来查询当前地区了。
#include <locale.h>
int main()
{char* loc;loc = setlocale(LC_ALL, NULL);printf("默认的本地信息:%s\n", loc);loc = setlocale(LC_ALL, "");printf("设置后的本地信息: %s\n", loc);return 0;
}
4.1.2 宽字符的打印
宽字符的字⾯量必须加上前缀 L ,否则 C 语言会把字面量当作窄字符类型处理。前缀 L 在单引号前面,表示宽字符,宽字符的打印使用 wprintf ,对应 wprintf() 的占位符为 %lc ;在双引号前面,表示宽字符串,对应 wprintf() 的占位符为 %ls。
例如:
#include <stdio.h>
#include<locale.h>
int main() {setlocale(LC_ALL, "");wchar_t ch1 = L'●';wchar_t ch2 = L'重';wchar_t ch3 = L'邮';wchar_t ch4 = L'★';printf("%c%c\n", 'a', 'b');wprintf(L"%lc\n", ch1);wprintf(L"%lc\n", ch2);wprintf(L"%lc\n", ch3);wprintf(L"%lc\n", ch4);return 0;
}
结果:
从打印结果可以看出,一个宽字符占两个字符的位置。
还需要注意的是,一个字符的长度是宽度的两倍,所以我们在使用宽字符的时候需要处理好地图上坐标的计算。
4.1.3 地图坐标
我们这里实现打印一个27行,58列的棋盘,通过棋盘画出地图。(可通过自己的实际情况修改)
27行(0-26),58列(0-57);其中列必须是2的倍数,因为宽字符的宽度为2,实现地图全是宽字符。
4.1.4 地图绘制
绘制地图可以通过四个for循环实现。
代码实现如下:
这里通过宏定义减少代码量:
#define wall L'□'
void create_wall()
{//x是横,y是竖//上for (int i = 0; i <29;i++ ){wprintf(L"%lc", wall);}//下setpos(0, 26);for (int i = 0; i < 29;i++){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);}setpos(0, 27);
}
注意:
其中的上下通过只需要从0到28,因为宽字符占两个字节。打印完上下两部分之后,打印左右两部分的时候,只需要各打印25行,因为打印上下两部分的时候已经打印了两行。每打印完一部分就需要再重新定位光标位置。
4.2 蛇身和食物
蛇身的实现需要运用到链表结果,通过初始化五个宽字符将蛇身链接起来。
需要注意的是:
蛇身的X坐标必须要是2的倍数。不然宽字符打印出来可能在墙体,坐标不好对齐。
食物坐标的生成是随机的,并且坐标不在蛇身和墙体上。
4.2.1 蛇身实现
蛇身的每个结点需要包含:横纵坐标以及一个结点指针指向下一个结点。
typedef struct snakenode
{int x;int y;struct snakenode* next;
}snakenode;
为了更好的管理蛇,我们再创建一个结构体:
typedef struct snake
{snakenode* psnake;//头结点snakenode* pfood;//食物结点enum direction dir;//蛇的方向enum game_states status;int food_weight;//食物分数int score;///总分数int sleep_time;//休息时间。
}snake;
里面包含了所需要的所有东西。
其中蛇的方向以及游戏状态通过枚举一一列举:
蛇的初始化:
snakenode* cur = NULL;
int i = 0;
//生成五个结点
for (i = 0; i < 5; i++)
{cur = (snakenode*)malloc(sizeof(snakenode));if (cur == NULL){printf("malloc fail");exit(1);}cur->next = NULL;cur->x = snake_x+ 2*i;cur->y = snake_y;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->food_weight = 10;//初始食物十分
ps->score = 0;//总分
ps->sleep_time = 200;//两百毫秒
ps->status = ok;
4.2.2 食物的随机生成
使用真正的随机需要包含头文件<time.h>。
srand((unsigned int)time(NULL));
然后通过随机函数实现食物坐标的随机生成。
思路:
生成一个满足X坐标为2到54,Y坐标1到25,并且X为2的倍数,然后再遍历蛇身,如果与任意一个蛇身结点横纵坐标重合,则再重新进行生成横纵坐标。实现这一过程我们可以使用goto指针。
实现后创建一个食物指针,将横纵坐标都填进去,并将其next指针指向NULL,然后定位到食物结点的坐标,进行打印食物节点,最后将该结点存到snake结构体里面。
代码实现:
int x = 0;
int y = 0;
//随机创建
//x在2到54,y在1到25,不和墙重叠do
again:
do
{x = rand() % 53 + 2;y = rand() % 25 + 1;
} while (x % 2 != 0);
//遍历蛇身判断是否和蛇身重叠
//重叠时使用goto函数进行重置
snakenode* cur = psnake->psnake;
while (cur)
{if (cur->x == x && cur->y)goto again;cur = cur->next;
}
snakenode* pfood = (snakenode*)malloc(sizeof(snakenode));
if (pfood == NULL)
{printf("malloc");exit(2);
}
pfood->next = NULL;
pfood->x = x;
pfood->y = y;
setpos(x, y);
wprintf(L"%lc", food);
psnake->pfood = pfood;
4.3 蛇移动
蛇的移动有多种情况:首先需要通过按键方向确定下一步的位置,再判断是吃到食物还是撞到墙还是吃到自己还是不是食物。
我们实现移动的方式是,创建一个新结点,将该新节点作为新的头结点,打印新蛇身。
头结点坐标实现:
switch (psnake->dir){case left:next->x = psnake->psnake->x - 2;next->y = psnake->psnake->y ;break;case right:next->x = psnake->psnake->x + 2;next->y = psnake->psnake->y;break;case up:next->x = psnake->psnake->x;next->y = psnake->psnake->y-1;break;case down:next->x = psnake->psnake->x;next->y = psnake->psnake->y + 1;break;}
分析:向左移动则横坐标-2。向左移动则横坐标+2。向上移动则纵坐标-1。向下移动则纵坐标+1。
4.3.1 获取按键情况
通过宏定义来实现按键的获取:
//宏定义按键
#define key_press(vk) ((GetAsyncKeyState(vk)&1)?1:0)
if (key_press(VK_UP) && psnake->dir != down)
{psnake->dir = up;
}
else if (key_press(VK_DOWN) && psnake->dir != up)
{psnake->dir = down;
}
else if (key_press(VK_LEFT) && psnake->dir != right)
{psnake->dir = left;
}
else if (key_press(VK_RIGHT) && psnake->dir != left)
{psnake->dir = right;
}
else if (key_press(VK_SPACE))
{pause();
}
else if (key_press(VK_ESCAPE))//正常退出
{psnake->status = end_normal;
}
else if (key_press(VK_F3))
{if (psnake->food_weight <20){psnake->sleep_time -= 20;psnake->food_weight += 2; }}
else if (key_press(VK_F4))
{if (psnake->food_weight > 2){psnake->sleep_time += 20;psnake->food_weight -= 2;}}
当获取到一个方向时,如果之前的方向与这个方向相反,那么该次按键不实现。当按空格时,实现暂停函数,当按到退出键时,退出函数,当按到F3时,加速,当按到F4时,减速。
4.3.1.1 暂停函数
我们可以通过一个不退出循环的while循环实现永久暂停,直到满足再按一次暂停键。
代码实现:
void pause()
{while (1){Sleep(200);if (key_press(VK_SPACE)){break;}}
}
当按到退出键时,则只需要将游戏状态设置为end_normal即可。
当按到F3(加速)时,我们食物一开始的分数是10,最高分是20,最低分是2。当小于20的时候,我们可以加速,即将休眠时间降低。
当按到F4(减速)时,当大于2的时候,我们就可以减速,即将休眠时间延长。
4.3.2 不是食物
不是食物则将之前蛇身的最后一个结点以“ ”输出。
void notfood(snakenode* pnext, snake* psnake)
{pnext->next = psnake->psnake;psnake->psnake = pnext;snakenode* cur = psnake->psnake;while (cur->next->next){setpos(cur->x, cur->y);wprintf(L"%lc", body);cur = cur->next;}//打印倒数第二个结点的身体setpos(cur->x, cur->y);wprintf(L"%lc", body);//最后一个节点打印空格setpos(cur->next->x, cur->next->y);printf(" ");free(cur->next);cur->next = NULL;
}
注意:这里的while循环完之后,cur指针的位置在之前蛇身的倒数第二个结点。然后将最后一个结点free掉并置为零。
4.3.3 是食物
是食物则直接将新结点变为头结点,遍历蛇身,打印蛇身释放掉食物结点。然后再重新生成一个食物结点。
void eatfood(snakenode * pnext,snake* psnake)
{//头插法,将next结点插入pnext->next = psnake->psnake;psnake->psnake = pnext;snakenode* cur = psnake->psnake;while (cur){setpos(cur->x, cur->y);wprintf(L"%lc", body);cur = cur->next;}psnake->score += psnake->food_weight;free(psnake->pfood);psnake->pfood = NULL;//创建新食物foodcreate(psnake);
}
4.3.4 撞墙结束
撞到墙后就将游戏状态设置为撞墙结束。
void killbywall(snakenode* next,snake * psnake)
{if (next->x == 0 || next->x == 56 || next->y == 0 || next->y == 26)psnake->status = kill_by_wall;}
4.3.5 撞到自己结束
遍历蛇身,如果撞到自己就将游戏状态设置为撞自己结束。
void killbyself(snakenode* next, snake* ps)
{snakenode* cur = ps->psnake->next;while (cur){if (cur->x == next->x && cur->y == next->y){ps->status = kill_by_self;break;}cur = cur->next;}
}
4.4 退出游戏
先通过游戏状态来决定输出怎样的汉字告诉玩家:
switch (snake->status){case kill_by_wall:printf("您撞到墙啦,游戏结束");break;case kill_by_self:printf("您撞到自己啦,游戏结束");break;case end_normal:printf("您退出游戏,游戏结束");break;}
再销毁蛇身链表。
//链表销毁
snakenode* cur = snake->psnake;
while (cur)
{snakenode* del = cur;cur = cur->next;free(del);del = NULL;}
5. 总的包装
为了流畅的实现贪吃蛇游戏,我们需要在test函数中运用循环来实现多次玩游戏。
void test()
{int ch = 0;do{system("cls");snake psnake = { 0 };//3. 欢迎界面,开始游戏// //打印墙体// 初始化蛇体//创建食物gamestart(&psnake);//4. 运行游戏gamerun(&psnake);//5. 退出游戏gameend(&psnake);setpos(30, 16);system("pause");setpos(30, 16);printf("还要再玩一次吗?(Y/N):");ch = getchar();while (getchar() != '\n');} while ((ch == 'y' || ch == 'Y'));setpos(0, 27);}
通过getchar函数得到玩家的答案,判断是否再进行游戏。
需要注意的是,玩完之后要清屏,并且在玩家输入前需要进行pause,避免up和right键调出之前的输入记录。
6. 源码
贪吃蛇实现 · 976d8af · 重邮阿江/c_study_experience - Gitee.com
相关文章:

贪吃蛇项目实现(C语言)——附源码
前言 贪吃蛇是一款十分经典的游戏,其通过控制贪吃蛇的上下左右移动来吃食物,延长自己的身体,也会因为撞到墙体和自身而死亡。下面我们通过C语言来实现贪吃蛇。 1.技术要点 C语言枚举,结构体,链表,动态内…...

【C++】42道面试经典问题总结
C this指针是干什么用的? 假如一个类型定义了很多对象,类里面有很多定义的私有成员变量,共享一套成员方法。通过this指针这可以区分方法、变量是操作的哪个对象的。 C的new和delete,new[]和delete[]可以混用吗? 一般来…...

php 实现JWT
在 PHP 中,JSON Web Token (JWT) 是一种开放标准 (RFC 7519) 用于在各方之间作为 JSON 对象安全地传输信息。JWT 通常用于身份验证系统,如 OAuth2 或基于令牌的身份验证。 以下是一个基本的 PHP 实现 JWT 生成和验证的代码示例。 JWT 的组成部分 JWT …...

vue table id一样的列合并
合并场景:如果id一样,则主表列合并,子表列不做合并,可实现单行、多行合并,亲测!!! 展示效果如图示: 组件代码: // table组件 :span-method"objectSpa…...

xshell密钥方式连接阿里云Linux
前提条件 有阿里云ECS linux实例安装好xshell工具 步骤 创建密钥对并绑定ECS实例 浏览器登录阿里云-->控制台-->ECS服务器-->网络与安全-->密钥对-->创建密钥对 根据提示填写密钥名称-->选中默认资源组-->创建 创建完成,会自动下载密钥对的…...

Wni11 下 WSL 安装 CentOS
Wni11 下 WSL 安装 CentOS 方法一、安装包安装下载包安装安装打开 CentOS1. 从 Windows 终端 打开2. 从 PowerShell 打开 方法二、导入 CentOS 的 tar 文件进行安装0. 查看版本(可选)1. 导出 Docker 容器到 tar 文件2. 将 tar 文件导入 WSL2.1. 导入 tar…...

ROADM(可重构光分插复用器)-介绍
1. 引用 https://zhuanlan.zhihu.com/p/163369296 https://zhuanlan.zhihu.com/p/521352954 https://zhuanlan.zhihu.com/p/91103069 https://zhuanlan.zhihu.com/p/50610236 术语: 英文缩写描述灰光模块彩光模块CWDM:Coarse Wave-Length Division …...

HarmonyOS开发之路由跳转
文章目录 一、路由跳转模式与实例1.router.pushUrl2.router.replaceUrl3.router.back 一、路由跳转模式与实例 跳转模式 有点类似于vue的路由跳转 router.pushUrl 保留路由栈,保留当前的页面;router.replaceUrl 销毁当前页面,跳转一个新的页…...

怎么使用ai 免费生成ppt?这4个工具可以帮忙
随之AI工具的流行,网络上也涌现了一批 AIPPT 工具,可以在办公上帮助我们节省很多制作PPT的时间。通常它们的操作也比较简单,所以适合很多人使用。为了可以帮助大家提高办公效率,我在这里跟大家分享4款可以免费使用的AIPPT制作工具…...

Android主副屏显示-Android13
Android主副屏显示-Android13 1、DisplayDeviceInfo屏幕信息2、每个屏幕对应LogicalDisplay2.1 LogicalDisplay添加对应DisplayContent2.2 configureDisplayLocked刷新 DisplayManagerService启动及主屏添加-Android13 1、DisplayDeviceInfo屏幕信息 DisplayManagerService启动…...

什么是 SMB 服务器以及它如何工作?
在本文中,您将了解 SMB 服务器以及它们如何促进网络文件共享。 我们将介绍它们的基本功能、主要特性以及如何安全地设置它们。无论您是新手还是需要复习,本指南都将帮助您更好地了解 SMB 服务器。 什么是 SMB 服务器? SMB(服务器…...

【python计算机视觉编程——10.OpenCV】
python计算机视觉编程——10.OpenCV 10.OpenCV10.2 OpenCV基础知识10.2.1 读取和写入图像10.2.2 颜色空间10.2.3 显示图像及结果 10.3 处理视频10.3.1 视频输入10.3.2 将视频读取到NumPy数组中 10.4 跟踪10.4.1 光流10.4.2 Lucas-Kanade算法使用跟踪器使用发生器 10.5 更多示例…...

医学数据分析实训 项目二 数据预处理预备知识(数据标准化处理,数据离差标准化处理,数据二值化处理,独热编码处理,数据PCA降维处理)
文章目录 数据预处理预备知识任务一 数据标准化处理1. 数据准备2. 数据标准化 任务二 数据离差标准化处理任务三 数据二值化处理任务五 独热编码处理对数据进行“离散化处理”(装箱)将已经装箱的数据进行OneHotEncoder独热编码 任务六 数据PCA降维处理1.…...

MySQL查询执行(四):查一行也很慢
假设存在表t,这个表有两个字段id和c,并且我在里面插入了10万行记录。 -- 创建表t CREATE TABLE t (id int(11) NOT NULL,c int(11) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB;-- 通过存储过程向t写入10w行数据 delimiter ;; create procedure idat…...

【Obsidian】当笔记接入AI,Copilot插件推荐
当笔记接入AI,Copilot插件推荐 自己的知识库笔记如果增加AI功能会怎样?AI的回答完全基于你自己的知识库余料,是不是很有趣。在插件库中有Copilot插件这款插件,可以实现这个梦想。 一、什么是Copilot? 我们知道githu…...

Spring Cloud集成Gateaway
Spring Cloud Gateway 是一个基于 Spring 生态的网关框架,用于构建微服务架构中的API网关。它可以对请求进行路由、过滤、限流等操作,是Spring Cloud微服务体系中常用的组件之一。下面介绍 Spring Cloud Gateway 的核心概念、应用场景以及简单的示例。 …...

如何准备技术面试?
大家好,我是老三,好久没更新了,翻出之前的一篇旧稿,是一篇总纲性质的文章——如何准备一场技术面试。这篇文章原本的开头是写给金三银四的,转眼就“金九银十”了,每一年都是最差的一年,又是未来…...

Kafka原理剖析之「Topic创建」
一、前言 Kafka提供了高性能的读写,而这些读写操作均是操作在Topic上的,Topic的创建就尤为关键,其中涉及分区分配策略、状态流转等,而Topic的新建语句非常简单 bash kafka-topics.sh \ --bootstrap-server localhost:9092 \ // …...

Java 高级学习路线概要~
前言:恭喜你已经掌握了 Java 的基础知识!现在,让我们踏上 Java 高级学习之旅,探索更强大的编程技巧和技术。学习前记得不要忘了巩固和加强基础的学习哦,高级学习也是建立在基础的学习之上。 1. 集合框架进阶 Map 接口…...

浏览器插件快速开启/关闭IDM接管下载
假设你已经为浏览器安装了IDM扩展,那么按下图的点击顺序,可以快速开启或关闭IDM的下载接管,而不必在IDM软件的设置->选项中,临时作调整。...

初识c++:入门基础
打字不易,留个赞再走吧~~ 目录 一.第一个c程序二.命名空间 namespace三.C输⼊&输出四.缺省参数 C兼容C语⾔绝⼤多数的语法,所以C语⾔实现的hello world依旧可以运⾏,C中需要把定义⽂件 代码后缀改为.cpp 一.第一个c程序 做好准备我们来写…...

Java Exception 异常相关总结
1.简介 在Java中,当代码运行有问题时会抛出异常,主要分为两类: 1.可以通过try...catch来捕获解决的,不影响后续执行的RuntimeException。 2.不可以通过代码解决的Exception。 为了提高代码的健壮性,我们会选择去捕…...

HighCharts图表自动化简介
什么是分析数据? 在任何应用程序中捕获并以图形或图表形式显示的分析数据是任何产品或系统的关键部分,因为它提供了对实时数据的洞察。 验证此类分析数据非常重要,因为不准确的数据可能会在报告中产生问题,并可能影响应用程序/系统的其他相关领域。 什么是HighChart? …...

使用LDAP登录GitLab
使用LDAP登录GitLab gitlab.rb 配置如下 gitlab_rails[ldap_enabled] true #gitlab_rails[prevent_ldap_sign_in] false###! **remember to close this block with EOS below** gitlab_rails[ldap_servers] YAML.load <<-EOSmain:label: LDAPhost: 172.16.10.180port:…...

【2024】前端学习笔记5-表单标签使用
表单是网页提供的一种交互式操作手段,主要用于采集用户输入的信息。 学习笔记 1.表单框架:form标签1.1.action属性:目标指向1.2.method属性:提交方式1.3.id属性:唯一标识1.4.placeholder属性:提示文字2.input标签2.1.text类型:基本文本输入2.2.password类型:密码输入2.…...

数据结构--二叉树(C语言实现,超详细!!!)
文章目录 二叉树的概念代码实现二叉树的定义创建一棵树并初始化组装二叉树前序遍历中序遍历后序遍历计算树的结点个数求二叉树第K层的结点个数求二叉树高度查找X所在的结点查找指定节点在不在完整代码 二叉树的概念 二叉树(Binary Tree)是数据结构中一种…...

【将字符串变为空的编辑距离】
题目描述 求由s串变成t串的编辑距离 在s串的开头/末尾添加一个字符,花费p 在s串的开头/末尾添加一个s串的子串,花费q 每次作都是基于当前的s串 s串初始为空 分析 等价于将一个字符串变为空串的过程 第一层按照长度遍历(如果按照下标i,j遍…...

卡特兰数的推理
卡特兰数(Catalan number),又称卡塔兰数、明安图数,是组合数学中一种常出现于各种计数问题中的数列。它以比利时数学家欧仁查理卡特兰的名字命名,但值得注意的是,这一数列的首次发现可以追溯到1730年&#…...

高精度治具加工的重要性和优势
在现代工业制造中,高精度治具加工扮演着举足轻重的角色。它不仅关乎产品制造的精度与质量,还直接影响到生产效率和成本控制。因此,时利和将深入探讨高精度治具加工的重要性和优势,对于提升工业制造水平具有重要意义。 高精度治具加…...

新版IDEA提示@Autowired不建议字段注入
随着项目的复杂度的增加,我们通常会在一个业务类中注入其他过多的业务类。从而使当前的业务层扩充成一个大而全的功能模块。那么就容易出现一下问题 字段注入会让依赖关系变得不那么明显,因为你无法通过构造函数看到所有的依赖项。使用构造函数时&#…...