当前位置: 首页 > news >正文

【C++游戏开发-03】贪吃蛇

文章目录

  • 前言
  • 一、工具准备
    • 1.1游戏开发框架
    • 1.2visual studio2022下载
    • 1.3easyX下载
    • 1.4图片素材
  • 二、逻辑分析
    • 2.1数据结构
    • 2.2蛇的移动
    • 2.3吃食物
    • 2.4游戏失败
  • 三、DEMO代码实现
  • 四、完整源代码
  • 总结


🐱‍🚀个人博客https://blog.csdn.net/qq_51000584?type=blog
🐱‍👤收录专栏:C++游戏开发探索
🐱‍👓专栏目标:通过所学知识和自己对游戏的理解去开发一系列游戏提高自己的编码和逻辑能力
🐱‍💻作者:敲代码的猫(Codemon)


前言

上次我们通过qt工具实现了推箱子的图形化编程http://t.csdnimg.cn/08AY9,本节我们将使用Visual Studio2022和easyX图形库来实现贪吃蛇的demo。成品如下:
在这里插入图片描述

一、工具准备

1.1游戏开发框架

代码链接:http://t.csdnimg.cn/iAvkm
经过对推箱子的开发,相信大家对游戏开发的流程已经有了一定的理解,那么为了方便我将游戏demo开发做成了框架,我们直接在这基础上实现即可。

1.2visual studio2022下载

转载博客:VS2022的下载和使用(作者:羽舟_)

1.3easyX下载

easyX官网
在这里插入图片描述
下载后直接运行exe文件,单击下一步,然后选择vs2022安装即可
在这里插入图片描述

1.4图片素材

链接:https://pan.baidu.com/s/1pOJxEfaePlcN-lVAJ0mFRA
提取码:1025
下载并解压到本地即可

二、逻辑分析

在逻辑分析前,同样我们先来了解一下贪吃蛇的游戏规则,
游戏规则:
贪吃蛇游戏的基本规则如下:
玩家通过控制蛇的移动来寻找并吃掉地图上的食物,每次吃掉食物后,蛇的身体会相应加长。
蛇的移动方向由玩家通过键盘上的上下左右键来控制。
在游戏过程中,蛇不能碰到墙壁或者自己的身体
如果蛇在移动过程中撞到墙壁或者咬到自己的身体,游戏会立即结束。

2.1数据结构

根据游戏规则我们会发现,蛇的身体分为一节一节的,并且连续,这会让我们联想到相关的数据结构——链表。如果我们能维护一个链表,那么它的头节点就是蛇的头,每当头节点移动,全身的节点都移动到上一个节点的位置,这样就实现了蛇的移动。
在这里插入图片描述
为了方便蛇身之间可以找到相邻的节点,蛇身长度增加,我们实现一个双向链表的创建、尾添加、删除功能。

//双向链表节点
struct Node {struct Node* pNext;struct Node* pPre;Point pos;Node() {//节点初始化pNext = nullptr;//下一个节点pPre = nullptr;//上一个节点}
};//双向链表
struct List {struct Node* pHead;struct Node* pTail;int length;List() {pHead = nullptr;//头节点pTail = nullptr;//尾节点length = 0;//链表长度}
};//创建双向链表
void CreateList(List** L) {*L) = new List;
}//双向链表尾添加节点
void AddNode(List* L, Point p) {if (L->pHead == nullptr) {//空链表L->pHead = new Node;L->pHead->pos = p;L->pHead->pNext = L->pHead;L->pTail = L->pHead;L->length++;}else {//尾添加Node* temp = new Node;temp->pos = p;L->pTail->pNext = temp;temp->pPre = L->pTail;L->pTail = temp;L->length++;}
}//链表资源释放
void DeleteList(List* L) {Node* pNode = L->pHead;while (pNode != nullptr) {Node* temp = pNode;pNode = pNode->pNext;delete temp;temp = nullptr;}delete L;L = nullptr;
}

2.2蛇的移动

蛇的移动和推箱子比起来就容易了很多,我们不需要再去判断复杂的地形,只需要保证蛇头没有碰到边界、没有咬到身体、对吃到食物进行处理即可。
蛇的移动是由程序自动控制的,玩家通过键盘的输入控制的只是改变了蛇的方向,因此我们定义一个全局变量和相应的宏

#define UP 0
#define LEFT 1
#define DOWN 2
#define RIGHT 3
int direct;

当我们按下键盘后只改变direct的值,然后每次刷新根据direct决定蛇向哪个方向移动。

2.3吃食物

我们假设蛇吃的是苹果,那么苹果每次出现在地图上的位置则是随机选定的,我们需要加入随机数种子的初始化。当蛇移动后的位置和苹果重合时,我们要更新苹果的位置,并且为蛇进行尾部添加节点的操作。

2.4游戏失败

当蛇移动后的位置超过了我们的地图边界即碰到了墙壁,此时失败。或者蛇移动后的位置是自己的身体时代表蛇咬到了自己,此时也会失败。我们可以在全局加入一个布尔值:

bool m_isQuit;

由m_isQuit的值来决定游戏的运行,当游戏 初始化时m_isQuit为true,当游戏失败条件触发时,将m_isQuit更改为false,这样就实现了游戏的失败退出功能。
综上来看贪吃蛇的逻辑要比推箱子容易很多。

三、DEMO代码实现

在游戏框架的代码基础上,首先我们要在GreedySnake类中添加我们需要使用的游戏相关全局变量:

bool m_isQuit;//游戏退出标识
List* snake;//存储蛇的双向链表
int direct;//记录当前方向
//屏幕大小
int screenWidth;
int screenHeight;
//苹果坐标
int appleX;
int appleY;
//格子大小
int base;
//蛇头坐标
Point m_point;

定义IMAGE对象来存储我们需要绘制的图,该类是easyX图形库中的成员,可以帮我们很方便的绘制图片。因此要加入头文件

#include <easyx.h>
IMAGE map;
IMAGE head_up;
IMAGE head_down;
IMAGE head_left;
IMAGE head_right;
IMAGE apple;
IMAGE body;

右键我们的vs项目,选择在文件资源管理器中打开文件夹
在这里插入图片描述
将我们的图片素材文件夹拖入到此处
在这里插入图片描述
进入该文件夹,点击map.bmp图片的属性
在这里插入图片描述
点击详细信息
在这里插入图片描述
可以看到该图片的大小为600*600像素,也就是说一格的大小为30*30,而蛇可移动的范围只有18*18格。我们设置窗口大小就为600*600
在构造函数中为成员变量初始化:

public:GreedySnake() {m_isQuit = true;//游戏运行//窗口大小screenWidth = 600;screenHeight = 600;srand((unsigned)time(NULL));//初始化随机数种子OnInit();//游戏初始化}

由于调用了time函数作为随机数种子,所以我们要加入头文件

#include <ctime>

对游戏进行初始化

void OnInit() {direct = UP;//初始化蛇的方向为向上base = 30;//格子大小30*30//随机初始化苹果的位置appleX = rand() % 18 + 1;appleY = rand() % 18 + 1;//初始化蛇m_point.setPoint(9, 9);//蛇头坐标初始化CreateList(&snake);//蛇双向链表初始化//-------------------------------------------Point temp;//定义坐标变量temp.setPoint(9, 9);AddNode(snake, temp);temp.setPoint(9, 10);AddNode(snake, temp);temp.setPoint(9, 11);AddNode(snake, temp);//-------------------------初始化三个节点长的蛇//加载图片(注意图片的路径)loadimage(&map, L".\\image\\map.bmp");loadimage(&head_right, L".\\image\\head0.bmp");//Rloadimage(&head_up, L".\\image\\head1.bmp");//Uloadimage(&head_left, L".\\image\\head2.bmp");//Lloadimage(&head_down, L".\\image\\head3.bmp");//Dloadimage(&apple, L".\\image\\apple.bmp");loadimage(&body, L".\\image\\body.bmp");initgraph(screenWidth, screenHeight);//初始化窗口大小}

下面是游戏运行函数

void OnRun() {while (m_isQuit) {//m_isQuit控制游戏的运行if (_kbhit())//处理键盘输入-----------需要头文件conio.h{int k = _getch();//获取键盘输入//需要头文件conio.hswitch (k){case 'A':case 'a':case 75://左direct = LEFT;break;case 'S':case 's':case 80://下direct = DOWN;break;case 'D':case 'd':case 77://右direct = RIGHT;break;case 'W':case 'w':case 72://上direct = UP;break;}}//------------------------------------SnakeMove();//蛇的移动if (!m_isQuit) {break;}OnDraw();//绘制图片Sleep(200);//控制刷新率,不易太快或太慢,以毫秒为单位}
}

蛇的移动

void SnakeMove() {switch (direct)//根据当前方向决定蛇头的移动{case UP:m_point.y--;break;case DOWN:m_point.y++;break;case LEFT:m_point.x--;break;case RIGHT:m_point.x++;break;}if (m_point.x < 1 || m_point.x>18 || m_point.y < 1 || m_point.y>18) {//移动后出界(碰墙)m_isQuit = false;return;}if (appleX == m_point.x && appleY == m_point.y) {//和苹果坐标重叠(吃到苹果)AddNode(snake, snake->pTail->pos);//给蛇添加节点//更新苹果坐标appleX = rand() % 18 + 1;appleY = rand() % 18 + 1;}//从蛇尾向蛇头遍历,每一个节点移动到前一个节点的位置(思靠一下为什么从蛇尾向蛇头遍历)Node* pNode = snake->pTail;while (pNode->pPre != NULL) {pNode->pos.x = pNode->pPre->pos.x;pNode->pos.y = pNode->pPre->pos.y;pNode = pNode->pPre;}snake->pHead->pos = m_point;//从蛇头向蛇尾遍历检测是否咬到了蛇身pNode = snake->pHead->pNext;while (pNode != NULL) {if (pNode->pos.x == m_point.x && pNode->pos.y == m_point.y) {m_isQuit = false;return;}pNode = pNode->pNext;}
}

图片绘制
BeginBatchDraw()函数和EndBatchDraw()函数用于打开和关闭缓冲区,也是easyX中的函数,要配对使用,我们将绘制图片的函数放在他们中间即可。

void OnDraw() {::BeginBatchDraw();//打开缓冲区开始绘制putimage(0, 0, &map);//绘制背景从(0,0)开始putimage(appleX * base, appleY * base, &apple);//绘制苹果Node* pNode = snake->pHead->pNext;//绘制蛇头switch (direct){case UP:putimage(m_point.x * base, m_point.y * base, &head_up);break;case DOWN:putimage(m_point.x * base, m_point.y * base, &head_down);break;case LEFT:putimage(m_point.x * base, m_point.y * base, &head_left);break;case RIGHT:putimage(m_point.x * base, m_point.y * base, &head_right);break;}//绘制蛇身while (pNode != NULL) {putimage(pNode->pos.x * base, pNode->pos.y * base, &body);pNode = pNode->pNext;}::EndBatchDraw();//关闭缓冲区结束绘制
}

游戏关闭:
由于我们使用到了链表,并且申请了堆的空间,因此在程序结束时需要对这一部分的资源进行释放。
先前在链表实现的地方已经写好了相应的函数,这里直接调用即可。

void OnClose() {DeleteList(snake);
}

运行后就是下面的样子啦
在这里插入图片描述

四、完整源代码

#include <iostream>
#include <easyx.h>
#include <conio.h>
#include <ctime>
using namespace std;//坐标结构体
struct Point {int x;int y;void setPoint(int px, int py) {this->x = px;this->y = py;}
};//游戏框架类
class CGameFrame {
public:CGameFrame() {}virtual ~CGameFrame() {}virtual void OnInit() = 0;//初始化virtual void OnRun() = 0;//游戏运行virtual void OnDraw() = 0;//绘制virtual void OnClose() = 0;//游戏关闭};//双向链表节点
struct Node {struct Node* pNext;struct Node* pPre;Point pos;Node() {pNext = nullptr;pPre = nullptr;}
};//双向链表
struct List {struct Node* pHead;struct Node* pTail;int length;List() {pHead = nullptr;pTail = nullptr;length = 0;}
};//创建双向链表
void CreateList(List** L) {*L = new List;(*L)->length = 0;
}//双向链表尾添加节点
void AddNode(List* L, Point p) {if (L->pHead == nullptr) {L->pHead = new Node;L->pHead->pos = p;L->pHead->pNext = L->pHead;L->pTail = L->pHead;L->length++;}else {Node* temp = new Node;temp->pos = p;L->pTail->pNext = temp;temp->pPre = L->pTail;L->pTail = temp;L->length++;}
}//链表资源释放
void DeleteList(List* L) {Node* pNode = L->pHead;while (pNode != nullptr) {Node* temp = pNode;pNode = pNode->pNext;delete temp;temp = nullptr;}delete L;L = nullptr;
}#define UP 0
#define LEFT 1
#define DOWN 2
#define RIGHT 3//贪吃蛇类
class GreedySnake :public CGameFrame
{
private:bool m_isQuit;//游戏退出标识List* snake;//存储蛇int direct;//记录当前方向IMAGE map;IMAGE head_up;IMAGE head_down;IMAGE head_left;IMAGE head_right;IMAGE apple;IMAGE body;//屏幕大小int screenWidth;int screenHeight;//苹果坐标int appleX;int appleY;//格子大小int base;//蛇头坐标Point m_point;public:GreedySnake() {m_isQuit = true;screenWidth = 600;screenHeight = 600;srand((unsigned)time(NULL));OnInit();}~GreedySnake() {}void OnInit() {direct = UP;base = 30;//初始化苹果appleX = rand() % 18 + 1;appleY = rand() % 18 + 1;//初始化蛇m_point.setPoint(9, 9);CreateList(&snake);//蛇初始化Point temp;temp.setPoint(9, 9);AddNode(snake, temp);temp.setPoint(9, 10);AddNode(snake, temp);temp.setPoint(9, 11);AddNode(snake, temp);//加载图片loadimage(&map, L".\\image\\map.bmp");loadimage(&head_right, L".\\image\\head0.bmp");//Rloadimage(&head_up, L".\\image\\head1.bmp");//Uloadimage(&head_left, L".\\image\\head2.bmp");//Lloadimage(&head_down, L".\\image\\head3.bmp");//Dloadimage(&apple, L".\\image\\apple.bmp");loadimage(&body, L".\\image\\body.bmp");initgraph(screenWidth, screenHeight);}void OnRun() {while (m_isQuit) {if (_kbhit())//处理键盘输入-----------{int k = _getch();switch (k){case 'A':case 'a':case 75://左direct = LEFT;break;case 'S':case 's':case 80://下direct = DOWN;break;case 'D':case 'd':case 77://右direct = RIGHT;break;case 'W':case 'w':case 72://上direct = UP;break;}}//------------------------------------SnakeMove();if (!m_isQuit) {break;}OnDraw();Sleep(200);}}void OnDraw() {::BeginBatchDraw();putimage(0, 0, &map);putimage(appleX * base, appleY * base, &apple);Node* pNode = snake->pHead->pNext;//绘制蛇头switch (direct){case UP:putimage(m_point.x * base, m_point.y * base, &head_up);break;case DOWN:putimage(m_point.x * base, m_point.y * base, &head_down);break;case LEFT:putimage(m_point.x * base, m_point.y * base, &head_left);break;case RIGHT:putimage(m_point.x * base, m_point.y * base, &head_right);break;}//绘制蛇身while (pNode != NULL) {putimage(pNode->pos.x * base, pNode->pos.y * base, &body);pNode = pNode->pNext;}::EndBatchDraw();}void OnClose() {DeleteList(snake);}void SnakeMove() {switch (direct){case UP:m_point.y--;break;case DOWN:m_point.y++;break;case LEFT:m_point.x--;break;case RIGHT:m_point.x++;break;}if (m_point.x < 1 || m_point.x>18 || m_point.y < 1 || m_point.y>18) {m_isQuit = false;return;}if (appleX == m_point.x && appleY == m_point.y) {AddNode(snake, snake->pTail->pos);appleX = rand() % 18 + 1;appleY = rand() % 18 + 1;}Node* pNode = snake->pTail;while (pNode->pPre != NULL) {pNode->pos.x = pNode->pPre->pos.x;pNode->pos.y = pNode->pPre->pos.y;pNode = pNode->pPre;}snake->pHead->pos = m_point;pNode = snake->pHead->pNext;while (pNode != NULL) {if (pNode->pos.x == m_point.x && pNode->pos.y == m_point.y) {m_isQuit = false;return;}pNode = pNode->pNext;}}};int main() {GreedySnake* pGame = new GreedySnake;pGame->OnRun();pGame->OnClose();delete pGame;pGame = nullptr;return 0;
}

总结

在前两节推箱子中已经实现过很多细节的部分,因此本篇贪吃蛇更多的是干货。下期我将继续使用qt工具实现贪吃蛇的完整版开发,敬请期待…

Codemon2024.02.21

相关文章:

【C++游戏开发-03】贪吃蛇

文章目录 前言一、工具准备1.1游戏开发框架1.2visual studio2022下载1.3easyX下载1.4图片素材 二、逻辑分析2.1数据结构2.2蛇的移动2.3吃食物2.4游戏失败 三、DEMO代码实现四、完整源代码总结 &#x1f431;‍&#x1f680;个人博客https://blog.csdn.net/qq_51000584?typeblo…...

如何理解CSS的边框宽度?

CSS 边框宽度学习手记 CSS 边框宽度小概念 在CSS的世界里&#xff0c;border-width这个属性真的很实用&#xff0c;它能帮我指定HTML元素四周边框的宽度。这个宽度嘛&#xff0c;可以用像素px、点pt、厘米cm、相对单位em这些来表示&#xff0c;很方便吧&#xff01;还有呢&am…...

java 写入写出 zip

package com.su.test.aaaTest.ioTest; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** 将文件压缩到 zip 中 */ public c…...

问题解决:‘telnet‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件

当在windows终端中运行telnet指令的时候&#xff0c;发现指令不可用&#xff0c;原因在于系统没安装telnet功能。 解决方法&#xff1a; 打开控制面板–》程序–》启用或关闭windows功能–》勾选Telnet客户端&#xff0c;点击确定即可。...

从基础到高级:Linux用户与用户组权限设置详解

目录 博客前言&#xff1a; 一.简介 1.用户的定义 用户账户分类 2.用户组的定义 二.用户的相关linux语法 1.创建用户&#xff08;useradd&#xff09; 2.删除用户&#xff08;userdel&#xff09; 3.修改用户&#xff08;usermod&#xff09; 4.修改用户密码 5.su切…...

【感知机】感知机(perceptron)学习算法知识点汇总

机器学习——感知机 感知机(perceptron)是一种二分类的线性模型&#xff0c;属于判别模型&#xff0c;也称为线性二分类器。输入为实例的特征向量&#xff0c;输出为实例的类别(取1和-1)。可以视为一种使用阶梯函数激活的人工神经元,例如通过梅尔频率倒谱系数&#xff08;MFCC…...

蓝桥杯:C++二分算法

在基本算法中&#xff0c;二分法的应用非常广泛&#xff0c;它是一种思路简单、编程容易、效率极高的算法。蓝桥杯软件类大赛中需要应用二分法的题目很常见。 二分法有整数二分和实数二分两种应用场景 二分法的概念 二分法的概念很简单&#xff0c;每次把搜索范围缩小为上一…...

Leetcode刷题笔记题解(C++):83. 删除排序链表中的重复元素

思路&#xff1a;链表相关的问题建议就是画图去解决&#xff0c;虽然理解起来很容易&#xff0c;但就是写代码写不出来有时候&#xff0c;依次去遍历第二节点如果与前一个节点相等则跳过&#xff0c;不相等则遍历第三个节点 /*** Definition for singly-linked list.* struct …...

@ 代码随想录算法训练营第8周(C语言)|Day56(动态规划)

代码随想录算法训练营第8周&#xff08;C语言&#xff09;|Day56&#xff08;动态规划&#xff09; Day56、动态规划&#xff08;包含题目 ● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组 &#xff09; 300.最长递增子序列 题目描述 给你一个整数…...

C# OpenCvSharp DNN Image Retouching

目录 介绍 模型 项目 效果 代码 下载 C# OpenCvSharp DNN Image Retouching 介绍 github地址&#xff1a;https://github.com/hejingwenhejingwen/CSRNet (ECCV 2020) Conditional Sequential Modulation for Efficient Global Image Retouching 模型 Model Properti…...

通过Docker Compose的方式在Docker中安装Maven环境

目前可以说 Docker 已经是在开发部署中成为主流&#xff0c;所以我们很多环境和工具都会安装在 Docker 容器中&#xff0c;Maven 环境是 SpringBoot 项目中最常用的依赖管理工具。当我们使用自动运维工具如 Ansible、Chef 、Puppet、Walle、Spug等&#xff09;管理和部署 Maven…...

Python实现线性逻辑回归和非线性逻辑回归

线性逻辑回归 # -*- coding: utf-8 -*- """ Created on 2024.2.20author: rubyw """import matplotlib.pyplot as plt import numpy as np from sklearn.metrics import classification_report from sklearn import preprocessing from sklearn…...

【软考】软件维护

目录 一、说明二、正确性维护三、适应性维护四、完善性维护五、预防性维护 一、说明 1.软件维护主要是根据需求变化或硬件环境的变化对应用程序进行部分或全部修改 2.修改时应充分利用源程序&#xff0c;修改后要填写程序修改登记表&#xff0c;并在程度变更通知书上写明新旧程…...

突破性创新:OpenAI推出Sora视频模型,预示视频制作技术的未来已到来!

一、前言 此页面上的所有视频均由 Sora 直接生成&#xff0c;未经修改。 OpenAI - Sora is an AI model that can create realistic and imaginative scenes from text instructions. 2024 年 2 月 16 日&#xff0c;OpenAI 发布 AI 视频模型 Sora&#xff0c;60 秒的一镜到底…...

【Web前端笔记10】CSS3新特性

10 CSS3新特性 &#xff11;、圆角 &#xff12;、阴影 &#xff08;&#xff11;&#xff09;盒阴影 &#xff13;、背景渐变 &#xff08;&#xff11;&#xff09;线性渐变&#xff08;主要掌握这种就可&#xff09; &#xff08;&#xff12;&#xff09;径向渐变 &…...

LabVIEW荧光显微镜下微管运动仿真系统开发

LabVIEW荧光显微镜下微管运动仿真系统开发 在生物医学研究中&#xff0c;对微管运动的观察和分析至关重要。介绍了一个基于LabVIEW的仿真系统&#xff0c;模拟荧光显微镜下微管的运动过程。该系统提供了一个高效、可靠的工具&#xff0c;用于研究微管与运动蛋白&#xff08;如…...

【Java面试】MQ(Message Queue)消息队列

目录 一、MQ介绍二、MQ的使用1应用解耦2异步处理3流量削峰4日志处理5消息通讯三、使用 MQ 的缺陷1.系统可用性降低:2.系统复杂性变高3.一致性问题四、常用的 MQActiveMQ:RabbitMQ:RocketMQ:Kafka:五、如何保证MQ的高可用?ActiveMQ:RabbitMQ:RocketMQ:Kafka:六、如何保…...

【安卓基础1】初识Android

&#x1f3c6;作者简介&#xff1a;|康有为| &#xff0c;大四在读&#xff0c;目前在小米安卓实习&#xff0c;毕业入职。 &#x1f3c6;安卓学习资料推荐&#xff1a; 视频&#xff1a;b站搜动脑学院 视频链接 &#xff08;他们的视频后面一部分没再更新&#xff0c;看看前面…...

08-静态pod(了解即可,不重要)

我们都知道&#xff0c;pod是kubelet创建的&#xff0c;那么创建的流程是什么呐&#xff1f; 此时我们需要了解我们k8s中config.yaml配置文件了&#xff1b; 他的存放路径&#xff1a;【/var/lib/kubelet/config.yaml】 一、查看静态pod的路径 [rootk8s231 ~]# vim /var/lib…...

PROBIS铂思金融破产后续:ASIC牌照已注销

2024年1月31日&#xff0c;PROBIS铂思金融的澳大利亚ASIC牌照 (AFSL 338241) 被注销《差价合约经纪商PROBIS宣布破产&#xff0c;澳大利亚金融服务牌照遭暂停》&#xff0c;这也就意味着&#xff0c;PROBIS铂思金融目前已经没有任何金融牌照。 值得注意的是&#xff0c;时至今日…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...