C语言贪吃蛇(可在头文件中添加食物,选择撞墙是否会死)

1. 项目目标

项目为控制台程序,在控制台上实现。

1. 实现游戏开始界面,让用户选择模式(撞墙/循环)等;

2. 实现地图的绘制;

3. 实现贪吃蛇,并使其根据用户的命令移动;

4. 实现食物的随机刷新,并为每一种食物设置分值;

5. 在游戏过程中打印适当的提示信息以及实时信息的刷新;

6. 实现贪吃蛇的变长;

7. 实时检测游戏状态(正常/撞墙/撞到自己);

2. 所需知识

C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等。

这些知识,想必大家在学习C语言的过程中已经熟练到出神入化了,但是对于Win32 API可能会感到有点陌生。

接下来我们重点介绍一下Win32 API。

2.1 WIn32 API

Windows 这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外, 它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每⼀种服务就是⼀个函数),可以帮应用程序达到开启视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序(Application), 所以便称之为 Application Programming Interface,简称 API 函数。

Win32 API也就是Microsoft Windows 32位平台的应用程序编程接口。

利用Win32 API提供的函数,我们就可以比较方便地在控制台上进行信息的打印,地图的绘制等。

以下为这个项目需要用到的一些API函数。


2.1.1 GetStdHandle 函数 - Windows Console | Microsoft Learn

HANDLE GetStdHandle(DWORD nStdHandle);

GetStdHandle是⼀个Windows API函数。它用于从⼀个特定的标准设备(标准输入、标准输出或标准错误)中取得⼀个句柄(用来标识不同设备的数值,类型为HANDLE),使用这个句柄可以操作设备。

句柄其实就类似于FILE*指针:当你需要对某个文件进行操作时,你需要将对应的文件指针传入对应的函数;当你需要对某个设备进行操作时,你需要将对应的句柄传入对应的函数。

他的参数有以下三个:

含义
STD_INPUT_HANDLE标准输入设备
STD_OUTPUT_HANDLE标准输出设备
STD_ERROR_HANDLE标准错误设备

 

控制台的屏幕属于标准输出设备,所以在该项目中我们在使用这个函数时传入的都是STD_OUTPUT_HANDLE,然后定义一个HANDLE类型的变量来接收其返回的句柄即可。

例如:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

 2.1.2 GetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

BOOL WINAPI GetConsoleCursorInfo(HANDLE hConsoleOutput,PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
);

GetConsoleCursorInfo函数用于检索有关指定控制台屏幕缓冲区的光标大小和可见性的信息 。

它的第一个参数为标准输出设备的句柄,第二个参数为一个指向 CONSOLE_CURSOR_INFO(CONSOLE_CURSOR_INFO 结构 - Windows Console | Microsoft Learn) 结构的指针,该结构接收有关控制台游标的信息。

CONSOLE_CURSOR_INFO结构的定义如下

typedef struct _CONSOLE_CURSOR_INFO {DWORD dwSize;BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

• dwSize:表示光标填充的字符单元格的百分比, 此值介于1到100之间。

                  光标外观会变化,范围从完全填充单元格到单元底部的水平线条。

• bVisible:表示光标的可见性。 如果光标可见,则此成员为 TRUE。

在使用时,我们需要先定义一个CONSOLE_CURSOR_INFO类型的变量,然后将其传入函数中。

此时,这个变量中就存储了当前光标的大小和可见性信息,我们可以通过访问这个结构体变量的成员来修改光标的参数。

例如:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息

但是,该变量只是获得了一个备份并将其储存,并没有直接与光标建立联系。

要使修改后的参数得到应用,我们还需要调用GetConsoleCursorInfo函数。


2.1.3 SetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

BOOL WINAPI SetConsoleCursorInfo(HANDLE hConsoleOutput,const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);

SetConsoleCursorInfo函数用于设置光标的参数,本质上就是让刚才获得的CONSOLE_CURSOR_INFO类型的变量存储的信息得到应用。

它的参数与GetConsoleCursorInfo函数一模一样,只需要在设置完光标参数之后,将变量再统统扔给它即可。

例如:

HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态

 2.1.4 SetConsoleCursorPosition 函数 - Windows Console | Microsoft Learn

BOOL WINAPI SetConsoleCursorPosition(HANDLE hConsoleOutput,COORD pos
);

SetConsoleCursorPosition函数用于设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD(COORD 结构 - Windows Console | Microsoft Learn)类型的pos中,调用SetConsoleCursorPosition函数将光标位置设置到指定的位置。

COORD结构体的定义如下:

typedef struct _COORD {SHORT X;SHORT Y;
} COORD, *PCOORD;

COORD 是Windows API中定义的一个结构体,表示一个字符在控制台屏幕幕缓冲区上的坐标,坐标系 (0,0) 的原点位于缓冲区的顶部左侧单元格。

水平向右为x轴正方向,竖直向下为y轴正方向。

y轴的单位长度(一个中文字符的高度/宽度)是x轴单位长度的两倍。

例如: 

COORD pos = { 10, 5};HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值)hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//设置标准输出上光标的位置为posSetConsoleCursorPosition(hOutput, pos);

这段代码就是将光标的位置设置到(10,5)的位置。

由于在项目中,无论是绘制地图,打印蛇,打印食物还是在指定位置打印信息都需要设置光标位置,所以我们将设置光标位置的功能封装为了一个函数SetPos。

//设置光标的坐标
void SetPos(short x, short y)
{COORD pos = { x, y };HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值)hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//设置标准输出上光标的位置为posSetConsoleCursorPosition(hOutput, pos);
}

2.1.5 getAsyncKeyState 函数 (winuser.h) - Win32 apps | Microsoft Learn

SHORT GetAsyncKeyState(int vKey
);

GetAsyncKeyState函数用于获取按键的状态。

将键盘上每个键的虚拟键值传递给函数,函数通过返回值来分辨按键的状态。

虚拟键码 (Winuser.h) - Win32 apps | Microsoft Learn 

GetAsyncKeyState 的返回值是short类型,在上一次调用 GetAsyncKeyState 函数后,如果返回的16位的short数据中:

• 最高位是1,说明按键的状态是按下,如果最高是0,说明按键的状态是抬 起。

• 如果最低位被置为1则说明,该按键被按过,否则为0。

如果我们要判断一个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1.

为了使用方便,我们定义了下面这个宏:

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

2.2 C语言的国际化特性

如果你需要用一些中文的宽字符来表示表示墙体,蛇,食物的话,就需要用到这个知识。

例如:打印墙体使用宽字符:□,打印蛇使用宽字符●,打印食物使用宽字符★

具体的细节,如果感兴趣的话可以自己去了解,在该项目中,你只需要知道setlocale函数即可。

setlocale - C++ Reference

char* setlocale (int category, const char* locale);

要使程序能够打印这些宽字符,只需要下面这个语句即可:

setlocal(LC_ALL, "");

3. 项目实现

3.1 Snake.h

这里我没有使用宽字符来表示墙,蛇,和食物,而是直接使用的汉字,目的是为了方便读者分辨定义的符号是什么意思。

要增加食物数量或种类的话,将FOOD_MAX的值修改之后,在FOOD_SHAPES和FOOD_WEIGHTS中分别添加其符号和分值即可。

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <locale.h>
#include <time.h>
#include <stdbool.h>#define WALL L'墙'
#define BODY L'蛇'#define FOOD_MAX 3//食物种数#define FOOD_SHAPES {L'史', L'蕉', L'苹'}//食物外形列表
#define FOOD_WEIGHTS {1145, 10, 20}//食物分值列表#define ORIGIN_LEN 5
#define ORIGIN_X 24
#define ORIGIN_Y 5
#define KEY_PRESS(vk) ((GetAsyncKeyState(vk) & 0x1) ? 1 : 0)//类型定义
enum DIRECTIONS//方向
{UP,//上DOWN,//下LEFT,//左RIGHT//右
};enum STATUS//游戏状态
{NORMAL,//正常END_NORMAL,//正常退出END_WALL,//撞墙结束END_SELF//撞到自己结束
};//蛇身结点
typedef struct SnakeNode
{int x;int y;struct SnakeNode* next;
}SnakeNode, *pSnakeNode;//食物结点
typedef struct Food
{int x;int y;int weight;WCHAR shape;
}Food, *pFood;//贪吃蛇游戏
typedef struct Snake
{pSnakeNode pSnakeHead;//蛇头Food Recipe[FOOD_MAX];//食物清单enum DIRECTIONS Direction;//运动方向enum STATUS Status;//游戏状态int Score;//总分数int SleepTime;//睡眠时间int Attached;//附加分数
}Snake, *pSnake;//函数定义//设置光标位置
void SetPos(int x, int y);//游戏开始
int GameBegin(pSnake ps);
//欢迎界面
int WelComeToGame();
//创建地图26/58
void CreatMap();
//初始化贪吃蛇
void InitSnake(pSnake ps);
//初始化食物
void InitRecipe(pSnake ps);//游戏运行
void GameRun(pSnake ps, int flag);
//打印提示信息
void PrintHelpInfo();
//打印实时信息
void PrintTimelyInfo(pSnake ps);
//暂停
void Pause(pSnake ps);
//蛇行
void SnakeMove(pSnake ps, int flag);
//是否即将触碰食物
int IsTouchingFood(pSnakeNode pn, pSnake ps);
//没吃到食物
void NoFood(pSnake ps);
//改变某食物坐标
void FoodPosModify(pSnake ps, int pos);
//检测是否撞墙
void TouchingWall(pSnakeNode pn, pSnake ps, int flag);
//检测是否撞到自己
void TouchingSelf(pSnakeNode pn, pSnake ps);//游戏结束
void GameEnd(pSnake ps);

3.2 Snake.c

#define _CRT_SECURE_NO_WARNINGS
#include "Snake.h"
//设置光标位置
void SetPos(int x, int y)
{HANDLE HandOutPut = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos = { x, y };SetConsoleCursorPosition(HandOutPut, pos);
}//欢迎界面
int WelComeToGame()
{SetPos(45, 14);wprintf(L"%ls", L"欢迎来到贪吃蛇小游戏");SetPos(45, 16);wprintf(L"%ls", L"1.撞墙模式(撞墙会死)");SetPos(45, 17);wprintf(L"%ls", L"2.循环模式(撞墙不会死)");int choice = 0;SetPos(43, 16);printf(">");do{if (KEY_PRESS(VK_UP))//撞墙模式{SetPos(43, 16);printf(">");SetPos(43, 17);printf(" ");choice = 0;}else if (KEY_PRESS(VK_DOWN))//循环模式{SetPos(43, 17);printf(">");SetPos(43, 16);printf(" ");choice = 1;}else if (KEY_PRESS(VK_RETURN)){break;}} while (1);SetPos(45, 25);system("pause");system("cls");SetPos(37, 14);wprintf(L"用上下左右来控制蛇的移动,按F3加速,按F4减速\n");SetPos(48, 15);wprintf(L"加速能获得更高的分数\n");SetPos(48, 17);system("pause");system("cls");return choice;
}//创建地图26/58
void CreatMap()
{int i = 0;//上for (i = 0; i < 29; i++){wprintf(L"%lc", WALL);}//下SetPos(0, 26);for (i = 0; i < 29; i++){wprintf(L"%lc", WALL);}//左右for (i = 1; i < 26; i++){SetPos(0, i);wprintf(L"%lc", WALL);SetPos(56, i);wprintf(L"%lc", WALL);}
}//初始化贪吃蛇
void InitSnake(pSnake ps)
{//初始化贪吃蛇属性ps->pSnakeHead = NULL;ps->Direction = RIGHT;ps->Score = 0;ps->Status = NORMAL;ps->SleepTime = 200;ps->Attached = 0;//创建蛇pSnakeNode cur = NULL;for (int i = 0; i < ORIGIN_LEN; i++){cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL){perror("InitSnake::malloc");return;}cur->next = NULL;cur->x = ORIGIN_X + 2 * i;cur->y = ORIGIN_Y;//头插cur->next = ps->pSnakeHead;ps->pSnakeHead = cur;}//打印蛇cur = ps->pSnakeHead;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}}//获取合法的食物坐标
void GetPos(pSnake ps, int* x, int* y)
{again:do{*x = rand() % 54 + 2;*y = rand() % 25 + 1;} while (*x % 2 != 0);pSnakeNode cur = ps->pSnakeHead;while (cur){if (cur->x == *x && cur->y == *y)goto again;cur = cur->next;}for (int i = 0; i < FOOD_MAX; i++){if (ps->Recipe[i].x == *x && ps->Recipe[i].y == *y)goto again;}
}//初始化食物
void InitRecipe(pSnake ps)
{int x = 0;int y = 0;WCHAR shapes[FOOD_MAX] = FOOD_SHAPES;int weights[FOOD_MAX] = FOOD_WEIGHTS;for (int i = 0; i < FOOD_MAX; i++){GetPos(ps, &x, &y);ps->Recipe[i].x = x;ps->Recipe[i].y = y;ps->Recipe[i].shape = shapes[i];ps->Recipe[i].weight = weights[i];SetPos(x, y);wprintf(L"%lc", ps->Recipe[i].shape);}
}//游戏开始
int GameBegin(pSnake ps)
{system("mode con cols=100 lines=30");system("title 贪吃蛇");//欢迎界面int flag = WelComeToGame();//创建地图27/58CreatMap();//初始化贪吃蛇InitSnake(ps);//初始化食物InitRecipe(ps);return flag;
}//打印提示信息
void PrintHelpInfo()
{SetPos(64, 16);wprintf(L"%ls", L"不能咬到自己");SetPos(64, 17);wprintf(L"%ls", L"用上下左右来控制蛇移动");SetPos(64, 18);wprintf(L"%ls", L"按F3加速,按F4减速");SetPos(64, 19);wprintf(L"%ls", L"按ESC退出游戏,按空格暂停游戏");
}//打印实时信息
void PrintTimelyInfo(pSnake ps)
{SetPos(64, 9);printf("总分数:%d\n", ps->Score);for (int i = 0; i < FOOD_MAX; i++){SetPos(64, 11 + i);wprintf(L"%lc", ps->Recipe[i].shape);printf("的分数为:%d", ps->Recipe[i].weight);}SetPos(64, 11 + FOOD_MAX);printf("附加分数为:%d", ps->Attached);
}//暂停
void Pause(pSnake ps)
{while (1){Sleep(200);if (KEY_PRESS(VK_SPACE)){break;}if (KEY_PRESS(VK_ESCAPE)){ps->Status = END_NORMAL;break;}}
}//是否即将触碰食物(是,则返回食物下标;否,则返回-1)
int IsTouchingFood(pSnakeNode pn, pSnake ps)
{for (int i = 0; i < FOOD_MAX; i++){if (pn->x == ps->Recipe[i].x && pn->y == ps->Recipe[i].y)return i;}return -1;
}//没吃到食物
void NoFood(pSnake ps)
{pSnakeNode cur = ps->pSnakeHead;while (cur->next->next){cur = cur->next;}SetPos(cur->next->x, cur->next->y);printf("  ");free(cur->next);cur->next = NULL;
}//改变某食物坐标
void FoodPosModify(pSnake ps, int pos)
{int x = 0;int y = 0;GetPos(ps, &x, &y);ps->Recipe[pos].x = x;ps->Recipe[pos].y = y;SetPos(x, y);wprintf(L"%lc", ps->Recipe[pos].shape);
}//检测是否撞墙
void TouchingWall(pSnakeNode pn, pSnake ps, int flag)
{if (flag == 1){if (pn->x == 0){pn->x = 54;}if (pn->x == 56){pn->x = 2;}if (pn->y == 26){pn->y = 1;}if (pn->y == 0){pn->y = 25;}}else{if (pn->x == 0 || pn->x == 56 || pn->y == 26 || pn->y == 0){ps->Status = END_WALL;}}
}//检测是否撞到自己
void TouchingSelf(pSnakeNode pn, pSnake ps)
{pSnakeNode cur = ps->pSnakeHead;while (cur){if (cur->x == pn->x && cur->y == pn->y){ps->Status = END_SELF;return;}cur = cur->next;}
}//蛇行
void SnakeMove(pSnake ps, int flag)
{pSnakeNode newhead = (pSnakeNode)malloc(sizeof(SnakeNode));if (newhead == NULL){perror("SnakeMove::malloc");return;}switch (ps->Direction){case UP:newhead->x = ps->pSnakeHead->x;newhead->y = ps->pSnakeHead->y - 1;break;case DOWN:newhead->x = ps->pSnakeHead->x;newhead->y = ps->pSnakeHead->y + 1;break;case LEFT:newhead->x = ps->pSnakeHead->x - 2;newhead->y = ps->pSnakeHead->y;break;case RIGHT:newhead->x = ps->pSnakeHead->x + 2;newhead->y = ps->pSnakeHead->y;break;}//检测是否撞墙TouchingWall(newhead, ps, flag);//检测是否撞到自己TouchingSelf(newhead, ps);newhead->next = ps->pSnakeHead;ps->pSnakeHead = newhead;SetPos(newhead->x, newhead->y);wprintf(L"%lc", BODY);//判断是否即将碰到食物int judge = IsTouchingFood(newhead, ps);if (judge == -1){//还没吃到食物,删掉最后一个结点NoFood(ps);}else{//修改某食物坐标FoodPosModify(ps, judge);ps->Score += ps->Recipe[judge].weight + ps->Attached;}}//游戏运行
void GameRun(pSnake ps, int flag)
{//打印提示信息PrintHelpInfo(ps);do{//打印实时信息PrintTimelyInfo(ps);//检测按键if (KEY_PRESS(VK_UP) && ps->Direction != DOWN){ps->Direction = UP;}else if (KEY_PRESS(VK_DOWN) && ps->Direction != UP){ps->Direction = DOWN;}else if (KEY_PRESS(VK_LEFT) && ps->Direction != RIGHT){ps->Direction = LEFT;}else if (KEY_PRESS(VK_RIGHT) && ps->Direction != LEFT){ps->Direction = RIGHT;}else if (KEY_PRESS(VK_SPACE)){//暂停Pause(ps);}else if (KEY_PRESS(VK_ESCAPE)){ps->Status = END_NORMAL;}else if (KEY_PRESS(VK_F3)){//加速if (ps->SleepTime > 80){ps->SleepTime -= 30;ps->Attached += 2;}}else if (KEY_PRESS(VK_F4)){//减速if (ps->SleepTime < 320){ps->SleepTime += 30;ps->Attached -= 2;}}SnakeMove(ps, flag);Sleep(ps->SleepTime);} while (ps->Status == NORMAL);
}
//游戏结束
void GameEnd(pSnake ps)
{SetPos(24, 12);switch (ps->Status){case END_NORMAL:printf("退出游戏!\n");break;case END_WALL:printf("撞墙啦牢底!\n");break;case END_SELF:printf("紫砂啦牢底!\n");break;}SetPos(24, 13);//释放蛇身链表pSnakeNode cur = ps->pSnakeHead;while (cur){pSnakeNode del = cur;cur = cur->next;free(del);}
}

3.3 test.c

#define _CRT_SECURE_NO_WARNINGS
#include "Snake.h"void SnakeGame()
{Snake snake = { 0 };//光标隐藏HANDLE HandOutPut = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(HandOutPut, &CursorInfo);CursorInfo.bVisible = false;SetConsoleCursorInfo(HandOutPut, &CursorInfo);int ch = 0;do{fflush(stdin);//游戏开始int flag = GameBegin(&snake);//游戏运行GameRun(&snake, flag);//游戏结束GameEnd(&snake);printf("要再来一次吗(Y/N):");ch = getchar();while (getchar() != '\n');KEY_PRESS(VK_RETURN);} while (ch == 'Y' || ch == 'y');SetPos(0, 28);
}int main()
{setlocale(LC_ALL, "");srand((unsigned int)time(NULL));SnakeGame();return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ELK+Kafka+Zookeeper日志收集系统

环境准备 节点IP节点规划主机名192.168.112.3Elasticsearch Kibana Logstash Zookeeper Kafka Nginxelk-node1192.168.112.3Elasticsearch Logstash Zookeeper Kafkaelk-node2192.168.112.3Elasticsearch Logstash Zookeeper Kafka Nginxelk-node3 基础环境 sys…

存储过程的使用(一)

目录 不带参数的存储过程 创建一个存储过程&#xff0c;向数据表 dept 中插入一条记录 带 IN 参数的存储过程 在存储过程中接受来自外部的数值&#xff0c;在存储过程中判断该数值是否大于零并显示 输入一个编号&#xff0c;查询数据表emp中是否有这个编号&#xff0c;如果…

Ubuntu日常配置

目录 修改网络配置 xshell连不上怎么办 解析域名失败 永久修改DNS方法 临时修改DNS方法 修改网络配置 1、先ifconfig确认本机IP地址&#xff08;刚装的机子没有ifconfig&#xff0c;先apt install net-tools&#xff09; 2、22.04版本的ubuntu网络配置在netplan目录下&…

全面讲解基于大型语言模型的智能Agent:发展历程、架构与基于Langchain的实现demo

在大型语言模型&#xff08;LLM&#xff09;的时代&#xff0c;基于大型语言模型的智能Agen在过去一年中取得了显著进展。 本文主要介绍基于大型语言模型的智能Agent&#xff0c;目录如下&#xff1a; Agent技术的起源。人工智能Agent技术的发展历程。基于LLM的Agent架构。基…

重构国内游戏账号登录系统的思考和实践

本期作者 背景 账号登录系统&#xff0c;作为游戏发行平台最重要的应用之一&#xff0c;在当前的发行平台的应用架构中&#xff0c;主要承载的是用户的账号注册、登录、实名、防沉迷、隐私合规、风控等职责。合规作为企业经营的生命线&#xff0c;同时&#xff0c;账号登录作为…

python爬虫之爬取携程景点评价(5)

一、景点部分评价爬取 【携程攻略】携程旅游攻略,自助游,自驾游,出游,自由行攻略指南 (ctrip.com) import requests from bs4 import BeautifulSoupif __name__ __main__:url https://m.ctrip.com/webapp/you/commentWeb/commentList?seo0&businessId22176&busines…

使用Python免费自制线稿生成工具

图片转线稿代码 这是一个Python脚本&#xff0c;它使用PIL库&#xff08;Python Imaging Library&#xff0c;也被称为Pillow&#xff09;和NumPy库将图片转换为线稿效果。以下是代码的具体内容&#xff1a; # 文件名&#xff1a;ImgProcess.pyfrom PIL import Image import …

nginx根据二级目录转发服务以及带/和不带/的区别

在nginx中配置proxy_pass代理转发时&#xff0c;如果在proxy_pass后面的url加/&#xff0c;表示绝对根路径&#xff1b;如果没有/&#xff0c;表示相对路径&#xff0c;把匹配的路径部分也给代理走。具体实例如下 1.配置文件location带/且proxy_pass带/ server {listen 80;se…

视觉slam14讲-大纲-持续更新

视觉slam入门太难 数学理论编程知识计算机视觉知识 缺一不可&#xff0c;大家一起加油

【RAG 论文】面向知识库检索进行大模型增强的框架 —— KnowledGPT

论文&#xff1a;KnowledGPT: Enhancing Large Language Models with Retrieval and Storage Access on Knowledge Bases ⭐⭐⭐⭐ 复旦肖仰华团队工作 论文速读 KnowledGPT 提出了一个通过检索知识库来增强大模型生成的 RAG 框架。 在知识库中&#xff0c;存储着三类形式的知…

跟TED演讲学英文:How AI could empower any business by Andrew Ng

How AI could empower any business Link: https://www.ted.com/talks/andrew_ng_how_ai_could_empower_any_business Speaker: Andrew Ng Date: April 2022 文章目录 How AI could empower any businessIntroductionVocabularyTranscriptSummary后记 Introduction Expensiv…

ROS 2边学边练(29)-- 使用替换机制

前言 启动文件用于启动节点、服务和执行流程。这组操作可能有影响其行为的参数。替换机制可以在参数中使用&#xff0c;以便在描述可重复使用的启动文件时提供更大的灵活性。替换是仅在执行启动描述期间评估的变量&#xff0c;可用于获取特定信息&#xff0c;如启动配置、环境变…

抖音视频评论自动回复与主动回复的实现

随着抖音平台的迅猛发展&#xff0c;视频内容创作者面临着日益增长的互动需求。用户评论作为互动的重要渠道之一&#xff0c;其管理与回复工作显得尤为重要。为了提高效率和互动质量&#xff0c;引入在线客服系统成为众多创作者和企业的选择。本文将详细介绍基于抖音开放平台接…

解决Ubuntu安装NVIDIA显卡驱动导致的黑屏问题

前言 本文是在经历了3天内5次重装Ubuntu系统后写下的&#xff0c;根本原因就是这篇文章的主题——安装NVIDIA显卡驱动&#xff01;写下本文是为了让自己今后不再出同样类型的错误&#xff0c;同时&#xff0c;给其他出现同样问题的人一些启发&#xff01; 本文实例的电脑配置如…

推荐一款websocket接口测试工具

网址&#xff1a;Websocket在线测试-Websocket接口测试-Websocket模拟请求工具 http://www.jsons.cn/websocket/ 很简单输入以ws开后的网址就可以了 这个网址是你后台设置的 如果连接成功会砸提示框内显示相关字样&#xff0c;反之则不行

Vue项目中Views文件夹

在Vue.js项目中&#xff0c;views 文件夹通常用于存放应用的页面组件。这些组件通常代表应用中的不同“页面”或“视图”&#xff0c;并且是与路由&#xff08;router&#xff09;紧密关联的。每个.vue 文件在 views 文件夹中通常代表一个独立的页面&#xff0c;这些页面通过Vu…

(十八)C++自制植物大战僵尸游戏的游戏暂停实现

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/uzrnw 游戏暂停 当玩家遇到突发事件&#xff0c;可以通过暂停功能暂停游戏&#xff0c;以便及时处理问题。在激烈的游戏中&#xff0c;玩家可能需要暂停游戏来进行策略调整。此外&#xff0c;长时间的游戏对战可能会让玩…

「探索C语言内存:动态内存管理解析」

&#x1f320;先赞后看&#xff0c;不足指正!&#x1f320; &#x1f388;这将对我有很大的帮助&#xff01;&#x1f388; &#x1f4dd;所属专栏&#xff1a;C语言知识 &#x1f4dd;阿哇旭的主页&#xff1a;Awas-Home page 目录 引言 1. 静态内存 2. 动态内存 2.1 动态内…

超越现实的展览体验,VR全景展厅重新定义艺术与产品展示

随着数字化时代的到来&#xff0c;VR全景展厅成为了企业和创作者展示作品与产品的新兴选择。通过结合先进的虚拟现实技术&#xff0c;VR全景展厅不仅能够提供身临其境的观展体验&#xff0c;而且还拓展了传统展示方式的界限。 一、虚拟现实技术的融合之美 1、高度沉浸的观展体验…

本地项目如何设置https——2024-04-19

问题&#xff1a;由于项目引用了html5-qrcode插件&#xff0c;但是该插件在本地移动端调试时只能使用https访问&#xff0c;所有原本的本地地址是http&#xff0c;就需要改成https以方便调试。 解决方法&#xff1a;使用本地https证书 1&#xff09;从项目文件下打开cmd逐步输…