C++EasyX之五子棋PVP和PVE
以下是该C++ EasyX五子棋代码的详细解析:
1 代码
1.1 全代码
#include <graphics.h>
#include <conio.h>
#include <Windows.h>
#include <cmath>
#include <vector>
#include <tuple>
#include <algorithm>using namespace std;// 游戏状态枚举
enum GameState { MAIN_MENU, DIFFICULTY_MENU, PLAYING, SHOP };
enum GameMode { PVP, PVE };
enum AIDifficulty { EASY, ORDINARY, DIFFICULT, VERY_DIFFICULT };// 全局变量
GameState gameState = MAIN_MENU;
GameMode gameMode = PVP;
AIDifficulty aiDifficulty = EASY;
bool vsAI = false;
int times = 0;
int coins = 0;
int board[15][15] = { 0 };
bool isBlack = true;
bool gameOver = false;// 棋盘参数
const int cellSize = 44;
const int boardSize = 14;
const int startX = (640 - cellSize * 14) / 2;
const int startY = 760 - cellSize * 14 - 10;// 函数声明
void DrawMainMenu();
void DrawDifficultyMenu();
void HandleMainMenuInput();
void HandleDifficultyInput();
void ResetGame();
void PlacePiece(int x, int y);
void EasyAI();
void OrdinaryAI();
void DifficultAI();
void VeryDifficultAI();void init() {initgraph(640, 760);setbkcolor(RGB(255, 240, 200));cleardevice();setbkmode(TRANSPARENT);settextcolor(BLACK);setlinecolor(BLACK);setfillcolor(BLACK);settextstyle(20, 0, L"Arial");
}void DrawCenteredText(int x, int y, int width, int height, const wchar_t* str) {int textWidth = textwidth(str);int textHeight = textheight(str);int tx = x + (width - textWidth) / 2;int ty = y + (height - textHeight) / 2;outtextxy(tx, ty, str);
}void DrawBoard() {setlinecolor(BLACK);for (int i = 0; i < 15; ++i) {line(startX + i * cellSize, startY, startX + i * cellSize, startY + cellSize * 14);line(startX, startY + i * cellSize, startX + cellSize * 14, startY + i * cellSize);}const int starPos[5][2] = { {3,3}, {3,11}, {11,3}, {11,11}, {7,7} };for (int i = 0; i < 5; ++i) {int x = startX + starPos[i][0] * cellSize;int y = startY + starPos[i][1] * cellSize;setfillcolor(BLACK);solidcircle(x, y, 5);}for (int i = 0; i < 15; i++) {for (int j = 0; j < 15; j++) {if (board[i][j] != 0) {int x = startX + i * cellSize;int y = startY + j * cellSize;setfillcolor(board[i][j] == 1 ? BLACK : WHITE);setlinecolor(DARKGRAY);fillcircle(x, y, 18);}}}
}void DrawValue() {setfillcolor(RGB(255, 245, 214));solidroundrect(10, 10, 200, 124, 5, 5);settextstyle(35, 0, _T("Arial"));DrawCenteredText(10, 10, 200, 60, L"TIMES");wchar_t timeStr[20];swprintf_s(timeStr, L"%d", times / 80);DrawCenteredText(10, 50, 200, 50, timeStr);solidroundrect(210, 10, 410, 124, 5, 5);settextstyle(35, 0, _T("Arial"));DrawCenteredText(210, 20, 200, 30,(vsAI && !isBlack) ? L"AI's turn" :(isBlack ? L"Black's turn" : L"White's turn"));
}// 新增菜单绘制函数
void DrawMainMenu() {setfillcolor(RGB(255, 245, 214));solidrectangle(0, 0, 640, 760);settextstyle(40, 0, _T("Arial"));settextcolor(BLACK);// 绘制标题DrawCenteredText(0, 100, 640, 100, L"GOBANG 1.0");// 绘制三个菜单按钮int baseY = 260;const wchar_t* menus[] = { L"PVP", L"PVE", L"STORE" };for (int i = 0; i < 3; i++) {setfillcolor(RGB(255, 222, 173));fillroundrect(220, baseY + i * 120, 420, baseY + i * 120 + 70, 10, 10);DrawCenteredText(220, baseY + i * 120, 200, 70, menus[i]);}
}void DrawDifficultyMenu() {setfillcolor(RGB(255, 245, 214));solidrectangle(0, 0, 640, 760);settextstyle(40, 0, _T("Arial"));DrawCenteredText(0, 100, 640, 100, L"CHOOSE AI DIFFICULTY");// 绘制四个难度按钮int baseY = 200;const wchar_t* diffs[] = { L"EASY AI", L"ORDINARY AI", L"DIFFICULT AI", L"COMING SOON" };for (int i = 0; i < 4; i++) {setfillcolor(RGB(255, 222, 173));fillroundrect(170, baseY + i * 100, 470, baseY + i * 100 + 70, 10, 10);DrawCenteredText(170, baseY + i * 100, 300, 70, diffs[i]);}
}// 输入处理函数
void HandleMainMenuInput() {ExMessage msg;if (peekmessage(&msg, EM_MOUSE)) {if (msg.message == WM_LBUTTONDOWN) {// 检查PVP按钮点击if (msg.x >= 220 && msg.x <= 420) {if (msg.y >= 260 && msg.y <= 330) { // PVPgameMode = PVP;vsAI = false;gameState = PLAYING;ResetGame();}else if (msg.y >= 380 && msg.y <= 450) { // PVEgameState = DIFFICULTY_MENU;}}}}
}void HandleDifficultyInput() {ExMessage msg;if (peekmessage(&msg, EM_MOUSE)) {if (msg.message == WM_LBUTTONDOWN) {if (msg.x >= 170 && msg.x <= 470) {int section = (msg.y - 200) / 100;if (section >= 0 && section < 4) {aiDifficulty = static_cast<AIDifficulty>(section);gameMode = PVE;vsAI = true;gameState = PLAYING;ResetGame();}}}}
}// 检查在(x, y)位置落子后,玩家是否获胜
bool CheckWin(int x, int y, int player) {// 定义四个检查方向:水平、垂直、右下对角线、左下对角线int dx[4] = { 1, 0, 1, 1 }; // x方向增量(右/下/右下/左下)int dy[4] = { 0, 1, 1, -1 }; // y方向增量(下/右/右下/左上)// 遍历四个主要方向(每个方向的正反都会被检查)for (int i = 0; i < 4; i++) {int count = 1; // 当前连续棋子数,初始包含刚下的棋子// 正向检查:沿当前方向延伸int nx = x + dx[i], ny = y + dy[i];while (nx >= 0 && nx < 15 && ny >= 0 && ny < 15 && board[nx][ny] == player) {count++; // 统计连续棋子nx += dx[i]; // 继续沿当前方向移动ny += dy[i];}// 反向检查:沿相反方向延伸nx = x - dx[i], ny = y - dy[i];while (nx >= 0 && nx < 15 && ny >= 0 && ny < 15 && board[nx][ny] == player) {count++;nx -= dx[i]; // 沿反方向移动ny -= dy[i];}// 任意方向连续五子即获胜if (count >= 5) return true;}return false; // 所有方向均未达到五子连线
}void PlacePiece(int x, int y) {if (board[x][y] == 0) {board[x][y] = isBlack ? 1 : 2;if (CheckWin(x, y, board[x][y])) {gameOver = true;wchar_t msgText[50];settextcolor(BLACK);swprintf_s(msgText, L"%s WIN!",(board[x][y] == 1 ? L"BLACK" : L"WHITE"));settextstyle(40, 0, _T("Arial"));DrawCenteredText(0, 0, 640, 720, msgText);FlushBatchDraw();Sleep(1000);}isBlack = !isBlack;}
}int lx = 0, ly = 0;void HandleGameInput() {ExMessage msg;if (peekmessage(&msg, EM_MOUSE)) {if (msg.message == WM_LBUTTONDOWN && !gameOver) {int x = (msg.x - startX + cellSize / 2) / cellSize;int y = (msg.y - startY + cellSize / 2) / cellSize;lx = x, ly = y;if (x >= 0 && x < 15 && y >= 0 && y < 15) {PlacePiece(x, y);}}}
}void ResetGame() {memset(board, 0, sizeof(board));isBlack = true;gameOver = false;times = 0;
}void EasyAI() {vector<pair<int, int>> available;for (int i = 0; i < 15; ++i) {for (int j = 0; j < 15; ++j) {if (board[i][j] == 0) {available.emplace_back(i, j);}}}if (!available.empty()) {int index = rand() % available.size();int x = available[index].first;int y = available[index].second;PlacePiece(x, y);}
}bool CanWin(int x, int y, int player) {if (board[x][y] != 0) return false;board[x][y] = player;bool win = CheckWin(x, y, player);board[x][y] = 0;return win;
}
// 新增威胁评估函数(需要放在OrdinaryAI之前)
int EvaluateThreat(int x, int y, int player) {if (board[x][y] != 0) return 0;const int dirs[4][2] = { {1,0}, {0,1}, {1,1}, {1,-1} };int maxThreat = 0;for (auto& dir : dirs) {int dx = dir[0], dy = dir[1];int length = 1;int openEnds = 0;bool blocked[2] = { false, false };// 正向延伸int px = x + dx, py = y + dy;while (px >= 0 && px < 15 && py >= 0 && py < 15) {if (board[px][py] == player) {length++;px += dx;py += dy;}else {if (board[px][py] == 0) openEnds++;else blocked[0] = true;break;}}if (!blocked[0] && px >= 0 && px < 15 && py >= 0 && py < 15) openEnds++;// 反向延伸px = x - dx, py = y - dy;while (px >= 0 && px < 15 && py >= 0 && py < 15) {if (board[px][py] == player) {length++;px -= dx;py -= dy;}else {if (board[px][py] == 0) openEnds++;else blocked[1] = true;break;}}if (!blocked[1] && px >= 0 && px < 15 && py >= 0 && py < 15) openEnds++;// 威胁评估规则if (length >= 4 && openEnds > 0) { // 活四/冲四return 10000; // 最高优先级}else if (length == 3) {if (openEnds >= 2) { // 活三maxThreat = max(maxThreat, 5000);}else if (openEnds == 1) { // 眠三maxThreat = max(maxThreat, 2000);}}else if (length == 2) {if (openEnds >= 2) { // 活二maxThreat = max(maxThreat, 1000);}}}return maxThreat;
}// 改进后的OrdinaryAI
void OrdinaryAI() {vector<pair<int, int>> threats;// 1. 检查自己是否能直接获胜for (int i = 0; i < 15; ++i) {for (int j = 0; j < 15; ++j) {if (board[i][j] == 0 && CanWin(i, j, 2)) {PlacePiece(i, j);return;}}}// 2. 检测玩家威胁并收集int maxThreatLevel = 0;for (int i = 0; i < 15; ++i) {for (int j = 0; j < 15; ++j) {if (board[i][j] == 0) {int threat = EvaluateThreat(i, j, 1); // 检查玩家威胁if (threat > maxThreatLevel) {maxThreatLevel = threat;threats.clear();threats.emplace_back(i, j);}else if (threat == maxThreatLevel && threat > 0) {threats.emplace_back(i, j);}}}}// 3. 处理威胁if (!threats.empty()) {// 选择威胁最大的位置int index = rand() % threats.size();int x = threats[index].first;int y = threats[index].second;PlacePiece(x, y);return;}// 4. 随机落子作为保底EasyAI();
}int EvaluatePosition(int x, int y, int player) {if (board[x][y] != 0) return 0;int score = 0;const int dirs[4][2] = { {1,0}, {0,1}, {1,1}, {1,-1} };for (auto& dir : dirs) {int dx = dir[0], dy = dir[1];int count = 1;int openEnds = 0;// Positive directionint px = x + dx, py = y + dy;bool blocked = false;while (px >= 0 && px < 15 && py >= 0 && py < 15) {if (board[px][py] == player) {count++;px += dx;py += dy;}else {if (board[px][py] == 0) openEnds++;else blocked = true;break;}}if (!blocked) openEnds++;// Negative directionpx = x - dx, py = y - dy;blocked = false;while (px >= 0 && px < 15 && py >= 0 && py < 15) {if (board[px][py] == player) {count++;px -= dx;py -= dy;}else {if (board[px][py] == 0) openEnds++;else blocked = true;break;}}if (!blocked) openEnds++;// Scoringif (count >= 5) {score += 1000000;}else if (count == 4) {if (openEnds >= 2) score += 10000;else if (openEnds == 1) score += 1000;}else if (count == 3) {if (openEnds >= 2) score += 500;else if (openEnds == 1) score += 200;}else if (count == 2) {if (openEnds >= 2) score += 100;else if (openEnds == 1) score += 50;}}return score;
}void DifficultAI() {int maxScore = -1;vector<pair<int, int>> bestMoves;for (int i = 0; i < 15; ++i) {for (int j = 0; j < 15; ++j) {if (board[i][j] == 0) {int score = EvaluatePosition(i, j, 2) + EvaluatePosition(i, j, 1) * 0.8;if (score > maxScore) {maxScore = score;bestMoves.clear();bestMoves.emplace_back(i, j);}else if (score == maxScore) {bestMoves.emplace_back(i, j);}}}}if (!bestMoves.empty()) {int index = rand() % bestMoves.size();int x = bestMoves[index].first;int y = bestMoves[index].second;PlacePiece(x, y);}else {EasyAI();}
}int main() {init();BeginBatchDraw();srand(GetTickCount());while (true) {cleardevice();switch (gameState) {case MAIN_MENU:DrawMainMenu();HandleMainMenuInput();break;case DIFFICULTY_MENU:DrawDifficultyMenu();HandleDifficultyInput();break;case PLAYING: {HandleGameInput();if (!isBlack && vsAI && !gameOver) {switch (aiDifficulty) {case EASY: EasyAI(); break;case ORDINARY: OrdinaryAI(); break;case DIFFICULT: DifficultAI(); break;//case VERY_DIFFICULT: VeryDifficultAI(); break;}}DrawBoard();DrawValue();if (gameOver) {FlushBatchDraw();if (MessageBox(GetHWnd(), L"再来一局?", L"游戏结束", MB_YESNO) == IDYES) {ResetGame();}else {gameState = MAIN_MENU;}}break;}case SHOP:// 商店实现(示例)settextstyle(40, 0, _T("Arial"));settextcolor(BLACK);DrawCenteredText(0, 300, 640, 100, L"商店功能开发中...");break;}FlushBatchDraw();Sleep(10);times++;}EndBatchDraw();closegraph();return 0;
}
1.2 分析
一、代码结构分析
- 全局变量与枚举
enum GameState { MAIN_MENU, DIFFICULTY_MENU, PLAYING, SHOP };
enum GameMode { PVP, PVE };
enum AIDifficulty { EASY, ORDINARY, DIFFICULT, VERY_DIFFICULT };int board[15][15] = { 0 }; // 15x15棋盘
bool isBlack = true; // 当前落子方
- 定义了游戏状态、模式和AI难度枚举
- 使用15x15数组存储棋盘状态(0=空,1=黑棋,2=白棋)
- 图形初始化
void init() {initgraph(640, 760); // 创建640x760窗口setbkcolor(RGB(255, 240, 200)); // 浅黄色背景setbkmode(TRANSPARENT); // 文字透明背景
}
- 使用EasyX创建图形窗口
- 设置棋盘背景色和文字样式
- 棋盘绘制
void DrawBoard() {// 绘制棋盘线for (int i=0; i<15; i++) {line(startX + i*cellSize, startY, ...);}// 绘制星位标记const int starPos[5][2] = {{3,3}, {3,11}, ...};// 绘制棋子if(board[i][j] != 0) fillcircle(x, y, 18);
}
- 动态计算棋盘起始位置(startX, startY)
- 使用cellSize=44控制格子大小
- 绘制传统五子棋的5个星位
- 游戏逻辑
bool CheckWin(int x, int y, int player) {// 检查四个方向的连续棋子int dx[4] = {1,0,1,1}; // 检查方向for(每个方向){while(正向计数)...while(反向计数)...if(count >=5) return true;}
}
- 使用经典的四方向检测算法
- 双向延伸检查连续棋子
二、AI实现分析
- 简单AI(EasyAI)
void EasyAI() {vector<pair<int, int>> available;// 收集所有空位int index = rand() % available.size(); // 随机选择
}
- 完全随机落子
- 无策略性
- 普通AI(OrdinaryAI)
void OrdinaryAI() {// 1. 检查自己是否能直接胜利for(所有空位){if(CanWin(i,j,2)) 落子;}// 2. 评估玩家威胁int threat = EvaluateThreat(i,j,1);// 3. 处理最高威胁位置
}
- 使用威胁评估函数
EvaluateThreat
- 优先阻止玩家形成活四、冲四等危险棋型
- 困难AI(DifficultAI)
int EvaluatePosition(int x, int y, int player) {// 评估该位置对player的价值// 考虑四个方向的连子情况// 计算开放度、连子数等
}
- 综合评估位置价值
- 平衡进攻与防守
- 计算己方得分 + 0.8倍敌方得分
三、用户交互设计
- 菜单系统
void DrawMainMenu() {// 绘制三个按钮:PVP、PVE、商店fillroundrect(220,260,420,330,10,10);
}
void HandleMainMenuInput() {// 检测鼠标点击区域if(msg.y在260-330区间) 进入PVP;
}
- 使用圆角矩形按钮
- 通过鼠标坐标判断选项
- 游戏界面
void DrawValue() {// 显示回合数、当前玩家solidroundrect(10,10,200,124,5,5); // 信息面板
}
- 顶部显示游戏状态信息
- 使用柔和色系提升视觉体验
四、代码特点总结
- 优点
- 模块化设计:各功能函数划分清晰
- 可扩展的AI架构:通过枚举实现多难度
- 完整的游戏流程:包含菜单→游戏→结束循环
- 友好的UI设计:使用抗锯齿图形和柔和配色
- 待改进点
- 商店功能未实现(SHOP状态空置)
- 最高难度AI未完成(VERY_DIFFICULT)
- 缺乏音效和动画效果
- 棋盘坐标转换存在潜在越界风险
五、运行效果示意
主菜单界面
---------------------GOBANG 1.0
[ PVP ] [ PVE ] [商店]
---------------------
游戏界面
---------------------
棋盘居中显示
顶部状态栏显示当前玩家
支持鼠标点击落子
AI自动响应(PVE模式)
---------------------
该代码实现了五子棋的核心玩法,适合作为教学示例或进一步开发的基础框架。通过扩展AI算法和添加新功能(如网络对战),可以提升项目的完整性和实用性。
限时免费至5月初,点赞破20火速更新STORE和VERY DIFFICULT难度!!!
相关文章:
C++EasyX之五子棋PVP和PVE
以下是该C EasyX五子棋代码的详细解析: 1 代码 1.1 全代码 #include <graphics.h> #include <conio.h> #include <Windows.h> #include <cmath> #include <vector> #include <tuple> #include <algorithm>using na…...
【Tauri2】015——前端的事件、方法和invoke函数
目录 前言 正文 准备 关键url 获取所有命令 切换主题set_theme 设置大小 获得版本version 名字name 监听窗口移动 前言 【Tauri2】005——tauri::command属性与invoke函数-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146581991?spm1001.2014.3001.…...
【C++奇遇记】C++中的进阶知识(继承(二))
🎬 博客主页:博主链接 🎥 本文由 M malloc 原创,首发于 CSDN🙉 🎄 学习专栏推荐:LeetCode刷题集 数据库专栏 初阶数据结构 🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如…...
qt designer 软件主题程序设计
对于使用Qt Designer设计的界面,主题切换的实现需要结合Qt的信号槽机制、样式表动态加载以及资源管理。以下是针对Qt Designer UI的详细解决方案: 一、UI文件与主题系统的整合架构 二、核心实现步骤 1. 动态样式表加载系统 // ThemeManager.h class …...
2025 年 4 月补丁星期二预测:微软将推出更多 AI 安全功能
微软正在继续构建其 AI 网络安全战略,并于本月宣布在 Microsoft Security Copilot 中引入新代理。 他们引入了用于网络钓鱼分类的代理、用于数据丢失预防和内部风险管理的警报分类、条件访问优化、漏洞修复和威胁情报简报。 这些代理的目标是不断从这些不同学科中…...
docker swarm常用命令
1、初始化Swarm集群 用于初始化一个Swarm集群,并将当前节点设置为Manager节点。 用法:docker swarm init --advertise-addr <Manager节点IP> # docker swarm init --advertise-addr 192.168.1.100 这会将当前节点初始化为Swarm集群的管理节点&…...
抖音直播位置与IP属地不同?解析原因与应对策略
在当今短视频直播盛行的时代,抖音作为头部平台吸引了大量主播和观众。然而,许多用户发现一个令人困惑的现象:直播间显示的位置信息与账号IP属地不一致。这种情况不仅让观众产生疑问,也可能给主播带来不必要的麻烦。本文将深入分析…...
「限时开源」全网首发!DeepSeek-R1+AI绘画+音乐生成全栈源码
—企业级AIGC私有化终极方案,3大模态整合,成本直降90% 行业痛点:为什么企业急需这套方案? 1. 多模态AIGC的三大困局 成本失控 API吸血: 使用MidjourneyStable DiffusionGPT-4Suno API生成内容,企业月均支…...
设计模式简述(二)单例模式
单例模式 描述基本使用防破坏单例饿汉式懒汉式有上限多例 描述 一个类全局只有一个实例,自行实例化并提供给使用。 构造函数私有化是前提 基本使用 防破坏单例 防反射:在构造函数中判断类中实例是否已初始化 private InnerClassSingleton (){if(Inn…...
区块链钱包:与主流钱包APP的区别
前言 在前端开发者速入:DApp中的前端要干些什么?文中我简单讲解了在DApp中前端开发者要干的是什么,本来在接下来的内容中我应该继续讲解在DApp中前端开发者的一系列工作和其他所要用到的技术栈,但是为了方便后续的讲解,我们这里不得不提及一下在区块链中让无数人又爱又恨…...
23种设计模式-行为型模式-中介者
文章目录 简介问题解决代码架构优势 总结 简介 中介者是一种行为设计模式, 能让你减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,强制让它们通过一个中介者对象进行合作。 问题 假如你有一个创建和修改用户资料的对话框࿰…...
mysql数据库中getshell的方式总结
mysql数据库中getshell的方式总结 MySQL版本大于5.0,MySQL 5.0版本以上会创建日志文件,我们通过修改日志文件的全局变量,就可以GetSHELL,下面这篇文章主要给大家介绍了关于mysql数据库中getshell的方式,需要的朋友可以参考下 outfile和dumpfile写shell 利用条件 …...
神经网络基础
神经网络的基本组成元素 一个神经元: 单层神经网络: 多层神经网络:(前向计算) 为什么要使用激活函数 如果不使用激活函数,每层只对上层的输入进行线性变换,实际这些线性变换可以归为一层即可。…...
Redis的公共操作命令
目录 1.Key操作命令1.1 keys *1.2 exists <key]>1.3 type <key>1.4 del <key>1.5 unlink <key>1.6 ttl <key>1.7 expire <key> <秒数>1.8 move <key> <index> 2.库操作命令2.1 select <index>2.2 dbsize2.3 flush…...
Redash:一个开源的数据查询与可视化工具
Redash 是一款免费开源的数据可视化与协作工具,可以帮助用户快速连接数据源、编写查询、生成图表并构建交互式仪表盘。它简化了数据探索和共享的过程,尤其适合需要团队协作的数据分析场景。 数据源 Redash 支持各种 SQL、NoSQL、大数据和 API 数据源&am…...
Transformer+BO-SVM多变量时间序列预测(Matlab)
TransformerBO-SVM多变量时间序列预测(Matlab) 目录 TransformerBO-SVM多变量时间序列预测(Matlab)效果一览基本介绍程序设计参考资料 效果一览 基本介绍 本期推出一期高创新模型,基于Transformer提取时序特征后输入S…...
【Redis】服务端高并发分布式结构
一、认识Redis Redis是开源的,用于存储数据的,在内存中存储数据。Redis被用作数据库,缓存,消息队列等一些作用。 在数据库的学习中,我们学习了MySQL,但是MySQL有一些大问题:其访问速度比较慢。在…...
C和C++(list)的链表初步
链表是构建其他复杂数据结构的基础,如栈、队列、图和哈希表等。通过对链表进行适当的扩展和修改,可以实现这些数据结构的功能。想学算法,数据结构,不会链表是万万不行的。这篇笔记是一名小白在学习时整理的。 C语言 链表部分 …...
第九课:LoRA模型的原理及应用
文章目录 Part.01 3种LoRA的使用方式Part.02 5种LoRA的应用方向Part.01 3种LoRA的使用方式 LoRA能够在家用级设备上训练,实现对Checkpoint在某些方面的微调使用Lora的三种方式:放置Lora模型到目录中,然后作为提示词的一部分输入。点击生成按钮下面的“画”,然后打开Additio…...
make_01_Program_07_$@ $^ 是什么含义
在 Makefile 中,$ 和 $^ 是自动变量,用于表示目标和依赖关系的特殊含义。它们常用于规则中的命令部分,以便简化 Makefile 的书写。 自动变量解析 $: $ 表示当前规则的目标文件名。换句话说,在一个特定的规则中&#x…...
CKPT文件是什么?
检查点(Checkpoint,简称ckpt)是一种用于记录系统状态或数据变化的技术,广泛应用于数据库管理、机器学习模型训练、并行计算以及网络安全等领域。以下将详细介绍不同领域中ckpt检查点的定义、功能和应用场景。 数据库中的ckpt检查点…...
YOLOv11训练教程:PyTorch与PyCharm在Windows 11下的完整指南
YOLOv11训练教程:PyTorch与PyCharm在Windows 11下的完整指南 介绍与引言 YOLO(You Only Look Once)是当前最流行的实时目标检测算法系列之一,YOLOv11作为该系列的最新演进版本,继承了YOLO家族高效、快速的特点,同时在精度和速度…...
使用MATIO库写入MATLAB结构体(struct)数据的示例程序
使用MATIO库写入MATLAB结构体(struct)数据的示例程序 MATIO是一个用于读写MATLAB数据文件(.mat)的开源C库。下面是一个完整的示例程序,展示如何使用MATIO库创建一个包含结构体数据的MAT文件。 示例程序 #include <stdio.h> #include <stdlib.h> #inc…...
【大模型深度学习】提示学习:Prefix tuning 、P-tuning v2、P-tuning 到底有什么区别?
Prefix tuning 、P-tuning v2、P-tuning还在傻傻分不清。 到底有什么区别,本文希望说明白这些区别,如有错误欢迎指出。 一、为什么需要提示学习? 从全参微调到参数高效微调(PEFT),这些微调方法的思想都是重新训练模…...
多周期多场景的供应链优化问题 python 代码
这段代码是一个使用 Gurobi 优化器的混合整数规划(MIP)模型,用于解决一个多周期多场景的供应链优化问题。代码定义了一个名为 `MCCG` 的类,该类包含了多个方法,用于构建和解决主问题(Master Problem)、子问题(Subproblem)和子子问题(Sub-subproblem)。下面是对代码中…...
CCF GESP Python编程 一级认证真题 2025年3月
Python 一级 2025 年 03 月 题号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 答案 D D B D D C B D C A B D C A A 一、单选题(每题 2 分,共 30 分) 第 1 题 2025年春节有两件轰动全球的事件,一个是DeepSeek横空出世,另一…...
python爬虫爬取淘宝热销(热门)男装商品信息(课程设计;提供源码、使用说明文档及相关文档;售后可联系博主)
TOC 本文仅为记录学习轨迹,如有侵权,联系删除 一、环境说明 使用前必须检查以下环境 (1)python编译环境 (2)python脚本执行所需要的库,具体看代码(main.py)import导入的部分库 &a…...
AntDesign下,Select内嵌Menu标签,做一个多选下拉框,既可以搜索,还可以选择下拉项
话不多说,直接上效果和代码 效果图一: 效果图二: renderAddStyleOption (item: any) > {const { value } this.props;const { currentSelectedOptionIds, currentStyleId } this.state;const styleSettings value?.styleSettings;c…...
15.1linux设备树下的platform驱动编写(知识)_csdn
上一章我们详细的讲解了 Linux 下的驱动分离与分层,以及总线、设备和驱动这样的驱动框架。基于总线、设备和驱动这样的驱动框架, Linux 内核提出来 platform 这个虚拟总线,相应的也有 platform 设备和 platform 驱动。 上一章我们讲解了传统的…...
【C++进阶五】list深度剖析
【C进阶五】list深度剖析 1.什么是list2.list的使用2.1构造函数2.2list迭代器2.3容量操作2.4增删查改 3.list迭代器失效4.迭代器类型5.list不能使用的算法库函数 1.什么是list STL标准库中的list是一个带头双向循环链表 和vector不同,list没有支持[ ]访问以及resize和reserve容…...
小刚说C语言刷题——第15讲 多分支结构
1.多分支结构 所谓多分支结构是指在选择的时候有多种选择。根据条件满足哪个分支,就走对应分支的语句。 2.语法格式 if(条件1) 语句1; else if(条件2) 语句2; else if(条件3) 语句3; ....... else 语句n; 3.示例代码 从键盘输入三条边的长度,…...
L2-024 部落 #GPLT,并查集 C++
文章目录 题目解读输入格式输出格式 思路Ac Code参考 题目解读 我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同一个部落。 输入格式 第一…...
【BFS最小步数】魔板题解
魔板题解 题目传送门 题目传送门 一、题目描述 Rubik先生发明了魔板的二维版本,这是一个有8个格子的板子,初始状态为: 1 2 3 4 8 7 6 5我们可以用三种操作来改变魔板状态: A:交换上下两行B:将最右边一…...
Qt之QHostInfo
简介 QHostInfo表示主机信息,即主机名称 常用接口 static QHostInfo fromName(const QString &name); QString hostName() const; QList<QHostAddress> addresses() const;结构 #mermaid-svg-HTJ95sEk8JwO4uCy {font-family:"trebuchet ms",…...
C++11观察者模式示例
该示例代码采用C11标准,解决以下问题: 消除了类继承的强耦合方式;通知接口使用可变参数模板,支持任意参数; 示例代码 .h文件如下: #include <functional> #include <string> #include <…...
解释观察者模式,如何实现观察者模式?
一、模式本质 观察者模式(Observer Pattern)建立对象间的一对多依赖关系,当核心对象(Subject)状态变化时,自动通知所有订阅者(Observers)。 这是一种推模型的典型…...
机器学习算法能够自动学习并使用不同条件下的变化趋势,确保预测结果的准确性的智慧地产开源了
智慧地产视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。 AI是新形势下数…...
【首款ARMv9开源芯片“星睿“O6测评】在“周易”NPU上部署Yolov8l模型并实现实时目标检测
博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 博客内容主要围绕: 5G/6G协议讲解 高级C语言讲解 Rust语言讲解 文章目录 在"星睿"O6的“周易”NPU上部署Yolov8l模型并实现…...
[ctfshow web入门] web4
前置知识 robots.txt是机器人协议,在使用爬虫爬取网站内容时应该遵循的协议。协议并不能阻止爬虫爬取,更像是一种道德规范。 假设robots.txt中写道 Disallow: /admind.php,那我就暴露了自己的后台,这属于信息泄漏,攻击…...
Golang的Goroutine(协程)与runtime
目录 Runtime 包概述 Runtime 包常用函数 1. GOMAXPROCS 2. Caller 和 Callers 3. BlockProfile 和 Stack 理解Golang的Goroutine Goroutine的基本概念 特点: Goroutine的创建与启动 示例代码 解释 Goroutine的调度 Gosched的作用 示例代码 输出 解…...
与Linux操作系统相关的引导和服务
目录 一.Linux操作系统引导过程 1.1引导过程总览 1.2系统初始化进程 1.2.1init进程 1.2.2sysmted 1.3systemd单元类型 二.排除启动类故障 2.1MBR扇区故障 2.1.1故障原因 2.1.2故障现象 2.1.3解决办法 2.1.4模拟修复MBR扇区故障 1)添加新的硬盘 2)进行…...
JS API 事件监听
焦点事件案例:搜索框激活下拉菜单 事件对象 事件对象存储事件触发时的相关信息 可以判断用户按键,点击元素等内容 如何获取 事件绑定的回调函数中的第一个形参就是事件对象 一般命名为e,event 事件对象常用属性 type类型 click mouseenter client…...
【8】搭建k8s集群系列(二进制部署)之安装node节点组件(kubelet)
一、下载k8s二进制文件 下载地址: https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG -1.20.md 注:打开链接你会发现里面有很多包,下载一个 server 包就够了,包含了 Master 和 Worker Node 二进制文件。…...
Harmony OS“一多” 详解:基于窗口变化的断点自适应实现
一、一多开发核心概念(18N模式) 目标:一次开发多端部署 解决的问题: 1、界面级一多:适配不同屏幕尺寸 2、功能级一多:设备功能兼容性处理(CanIUser) 3、工…...
Rust切片、结构体、枚举
文章目录 切片类型字符串切片其他结构的切片 结构体结构体实例元组结构体结构体所有权输出结构体结构体的方法结构体关联函数单元结构体 枚举match语法Option枚举类if let 语句 切片类型 切片(Slice)是对数据值的部分“引用” 我们可以从一个数据集合中…...
量子纠错码实战:从Shor码到表面码
引言:量子纠错的必要性 量子比特的脆弱性导致其易受退相干和噪声影响,单量子门错误率通常在10⁻~10⁻量级。量子纠错码(QEC)通过冗余编码测量校正的机制,将逻辑量子比特的错误率降低到可容忍水平。本文从首个量子纠错…...
Pod的生命周期
概念 Pod对象自从其创建开始至其终止退出的时间范围称为其生命周期。在这段时间中,Pod会处于多种不同的状态,并执行一些操作;其中,创建主容器(main container)为必需的操作,其他可选的操作还包…...
使用QAction编辑器添加QAction到ui里
在 Qt Designer 或 Qt Creator 的 UI 设计器 中,可以直接通过 Action Editor 可视化添加和管理 QAction,无需手动编写代码。以下是详细步骤: 步骤 1:打开 Action Editor 在 Qt Creator 中打开 .ui 文件(双击项目中的…...
Unity:标签(tags)
为什么需要Tags? 在游戏开发中,游戏对象(GameObject)数量可能非常多,比如玩家、敌人、子弹等。开发者需要一种简单的方法来区分这些对象,并根据它们的类型执行不同的逻辑。 核心需求: 分类和管…...
深入解析 Python 正则表达式:全面指南与实战示例
深入解析 Python 正则表达式:全面指南与实战示例 📌 引言 正则表达式(Regular Expressions, regex)是用于文本匹配、查找和替换的强大工具。在 Python 中,我们可以使用 re 模块来处理正则表达式。无论是数据清洗、日…...