C++ 实现对战AI五子棋

 个人主页:日刷百题

系列专栏〖C/C++小游戏〗〖Linux〗〖数据结构〗 C语言

🌎欢迎各位点赞👍+收藏⭐️+留言📝 

前言:

     为了能够快速上手一门语言,我们往往在学习了基本语法后,采用写一个小项目的方式来加深理解语言的语法及运用,本文采用c++去实现对战AI五子棋,采用面向对象开发的一款游戏,里面应用了类和对象以及vector容器等知识。

 一、项目效果展示


 


二、游戏思路

 


 

三、游戏框架

我们这里创建四个类(可以简单的理解为加强版的结构体),玩家类、AI类、棋盘类、棋盘控制类,将玩家类、AI类、棋盘类作为参数传给棋盘控制类,棋盘控制类获取这三个类的信息,从而可以控制游戏的运行,而玩家和AI要进行下棋操作时,需要棋盘信息,所以在玩家和AI类设置棋盘类。

根据上面分析,我们搭建好框架,先实现棋盘类功能,再实现AI和玩家类,最后实现棋盘控制类

四、棋盘类实现

4.1  用棋盘类构造函数初始化

4.1.1  checkerboard.h

#include<graphics.h>//eaysx头文件
#include<vector>
using namespace std;
enum  GameResult { BLACK_WIN,WHITE_WIN,DRAW ,CONTINUE};
class checkerboard
{
public://构造函数初始化成员变量checkerboard(int BoardSize, int margin_x, int margin_y, float ChessSize){this->BoardSize = BoardSize;//几线棋盘this->margin_x=margin_x;this->margin_y = margin_y;this->ChessSize = ChessSize;//棋子大小//加载黑子和白子图片到黑子和白子变量loadimage(&BLACK_IMG, "res/black.png", ChessSize, ChessSize, true);loadimage(&WHITE_IMG, "res/white.png", ChessSize, ChessSize, true);//棋盘初始化for (int i = 0; i < ChessSize; i++){vector<int> row;for (int j = 0; j < ChessSize; j++){row.push_back(0);}BoardMap.push_back(row);}gameresult= CONTINUE;}int BoardSize;//棋盘大小float ChessSize;//棋子大小vector<vector<int>> BoardMap;//表示棋盘落子情况
private:IMAGE BLACK_IMG;//黑棋图片变量IMAGE WHITE_IMG;//白棋图片变量int margin_x;//左侧边界45int margin_y;//右侧边界45};

 4.2  棋盘类初始化函数

注:

这个初始化函数和棋盘类构造函数的初始化一样,为什么再初始化一次呢?因为我们后面进行游戏运行时,一局结束,再来一局还需要再调用一次棋盘初始化,而定义棋盘类只能调用一次构造函数,所以再创一个棋盘类初始化函数

4.2.1  checkerboard.h

pubilc:
void Init();//棋盘初始化

4.2.2   checkerboard.cpp

void checkerboard::Init()
{initgraph(L, W, 1);//窗口大小//加载到窗口棋盘图片loadimage(0, "res/棋盘2.jpg", L,W,true);//播放声音/*  mciSendString("play res/start.WAV", 0, 0, 0);*///加载黑子和白子图片到黑子和白子变量//loadimage(&BLACK_IMG, "res/black.png", ChessSize, ChessSize, true);//loadimage(&WHITE_IMG, "res/white.png", ChessSize, ChessSize, true);//后面没有调用构造函数,调用初始化,所有在这里还需要对容器归0for (int i = 0; i < ChessSize; i++){for (int j = 0; j < ChessSize; j++){BoardMap[i][j] = 0;}}gameresult = CONTINUE;}

4.3  检查鼠标点击是否有效

注:

虽然代码很长,但是思路很简单,先计算点击位置(x,y) 附近的4个落棋位置的实际坐标位置,然后再计算点击位置到这四个落棋位置之间的距离,如果落棋位置与点击位置距离小于棋子大小的0.4倍,就认为这个落棋位置是玩家想要落棋的位置,存储在pos中。若此时该位置没有其他棋子,则为有效点击,返回真。

4.3.1 checkerboard.h

棋盘类外:

//落子位置
struct ChessPos
{int row;int col;
};
enum  chess_type{CHESS_WHITE=-1,CHESS_BLACK=1};

棋盘类内:

public:
bool ClickBord(int x, int y, ChessPos& pos);//检查有效点击

4.3.2 checkerboard.cpp

bool checkerboard::ClickBord(int x, int y, ChessPos& pos)
{//保证在棋盘内if (x >= margin_x && x <= (L - margin_x) && y >= margin_y && y <= (W - margin_y)){int col = (x - margin_x) / ChessSize;int row = (y - margin_y) / ChessSize;//该位置左上角的交点的坐标int LTPos_x = margin_x + ChessSize * col;int LTPos_y = margin_y + ChessSize * row;int critical = ChessSize * 0.4;//临界值//鼠标点击位置与右上角交点之间的距离int distance1 = sqrt((x - LTPos_x) * (x - LTPos_x) + (y - LTPos_y) * (y - LTPos_y));//勾股定理//该位置右上角的交点的坐标int RTPos_x = LTPos_x + ChessSize;int RTPos_y = LTPos_y;//鼠标点击位置与右上角交点之间的距离int distance2 = sqrt((x - RTPos_x) * (x - RTPos_x) + (y - RTPos_y) * (y - RTPos_y));//勾股定理//该位置左下角的交点的坐标int LDPos_x = LTPos_x;int LDPos_y = LTPos_y + ChessSize;//鼠标点击位置与左下角交点之间的距离int distance3 = sqrt((x - LDPos_x) * (x - LDPos_x) + (y - LDPos_y) * (y - LDPos_y));//勾股定理//该位置右下角的交点的坐标int RDPos_x = LTPos_x + ChessSize;int RDPos_y = LTPos_y + ChessSize;//鼠标点击位置与右下角交点之间的距离int distance4 = sqrt((x - RDPos_x) * (x - RDPos_x) + (y - RDPos_y) * (y - RDPos_y));//勾股定理if (distance1 <= critical){pos.col = col;pos.row = row;if (BoardMap[pos.row][pos.col] == 0)//该坐标没有棋子{return true;}return false;}else if (distance2 <= critical){pos.col = col + 1;pos.row = row;if (BoardMap[pos.row][pos.col] == 0)//该坐标没有棋子{return true;}return false;}else if (distance3 <= critical){pos.col = col;pos.row = row + 1;if (BoardMap[pos.row][pos.col ] == 0)//该坐标没有棋子{return true;}return false;}else if (distance4 <= critical){pos.col = col + 1;pos.row = row + 1;if (BoardMap[pos.row ][pos.col] == 0)//该坐标没有棋子{return true;}return false;}else{return false;}}else{return false;}
}

4.4   下棋

功能:实现记录最后一次落子的位置以及最后一次下棋是玩家方还是AI方,在棋盘二维数组记录落子数据。

 4.4.1 checkerboard.h

 棋盘类外:

//落子位置
struct ChessPos
{int row;int col;
};
enum  chess_type{CHESS_WHITE=-1,CHESS_BLACK=1};

棋盘类内:

public:void PlayChess(ChessPos& pos,chess_type type);//下棋

  4.4.2 checkerboard.cpp

void checkerboard::PlayChess(ChessPos& pos, chess_type type)
{int x = margin_x + ChessSize * pos.col-ChessSize*0.5;int y = margin_y + ChessSize * pos.row- ChessSize *0.5;BoardMap[pos.row][pos.col] = type;lastpos.row = pos.row;lastpos.col = pos.col;lasttype = type;if (type == CHESS_BLACK){putimagePNG(x, y, &BLACK_IMG);}else{putimagePNG(x, y, &WHITE_IMG);}
}

4.5  判断棋盘是否下满

4.5.1 checkerboard.h

bool BoardFull();

4.5.2 checkerboard.cpp

bool checkerboard::BoardFull()
{for (int row = 0; row < BoardSize; row++){for (int col = 0; col < BoardSize; col++){if (BoardMap[row][col] == 0)//棋盘没满{return false;}}}return true;
}

 4.6  判断游戏状态

4.6.1 checkerboard.h

 棋盘类外:

enum  GameResult { BLACK_WIN,WHITE_WIN,DRAW ,CONTINUE};

 棋盘类内: 

private:
GameResult gameresult;
GameResult IsWin();

4.6.2 checkerboard.cpp 

GameResult checkerboard::IsWin()
{bool boardfull = BoardFull();//每个方向记连续棋子个数int Black_Num = 0;int  White_Num = 0;if (lasttype == CHESS_BLACK)//黑子方{//计算四个方向是否有5个for (int i = 0; i <= 1; i++)//分横,竖,上斜,下斜4个方向{for (int j = -1; j <= 1; j++){//每个方向记连续棋子个数Black_Num = 0;White_Num = 0;if ((i == 0 && j == 0) || (i == 0 && j == 1)){continue;}for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中的单向{int Cur_row = lastpos.row + i * k;int Cur_col = lastpos.col + j * k;if (Cur_row >= 0 && Cur_row < BoardSize &&Cur_col >= 0 && Cur_col < BoardSize &&BoardMap[Cur_row][Cur_col] == CHESS_BLACK){Black_Num++;}else//超出棋盘或者是白子或者空白{break;}}for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中单向的另一个方向{int Cur_row = lastpos.row - i * k;int Cur_col = lastpos.col - j * k;if (Cur_row >= 0 && Cur_row < BoardSize &&Cur_col >= 0 && Cur_col < BoardSize &&BoardMap[Cur_row][Cur_col] == CHESS_BLACK){Black_Num++;}else//超出棋盘或者是白子或者空白{break;}}//判断游戏状态if (Black_Num == 4)//5个黑子,游戏结束{return BLACK_WIN;}else{if (boardfull){return  DRAW;}}}}}else//白子方{//计算四个方向是否有5个for (int i = 0; i <= 1; i++)//分横,竖,上斜,下斜4个方向{for (int j = -1; j <= 1; j++){//每个方向记连续棋子个数Black_Num = 0;White_Num = 0;if ((i == 0 && j == 0) || (i == 0 && j == 1)){continue;}for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中的单向{int Cur_row = lastpos.row + i * k;int Cur_col = lastpos.col + j * k;if (Cur_row >= 0 && Cur_row < BoardSize &&Cur_col >= 0 && Cur_col < BoardSize &&BoardMap[Cur_row][Cur_col] == CHESS_WHITE){White_Num++;}else//超出棋盘或者是黑子或者空白{break;}}for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中单向的另一个方向{int Cur_row = lastpos.row - i * k;int Cur_col = lastpos.col - j * k;if (Cur_row >= 0 && Cur_row < BoardSize &&Cur_col >= 0 && Cur_col < BoardSize &&BoardMap[Cur_row][Cur_col] == CHESS_WHITE){White_Num++;}else//超出棋盘或者是黑子或者空白{break;}}//判断游戏状态if (White_Num == 4)//5个白子,游戏结束{return WHITE_WIN;}else{if (boardfull){return  DRAW;}}}}}return CONTINUE;
}

4.7   判断游戏是否结束

4.7.1 checkerboard.h

bool CheckOver();//检查游戏是否结束 

4.7.2  checkerboard.cpp

bool checkerboard::CheckOver()
{gameresult = IsWin();if (gameresult == BLACK_WIN){Sleep(2000);loadimage(0, "res/胜利.jpg",W,L,true);//播放声音mciSendString("play res/胜利.mp3", 0, 0, 0);_getch();return true;}else if (gameresult == WHITE_WIN){Sleep(2000);loadimage(0, "res/失败.jpg",W , L, true);//播放声音mciSendString("play res/失败.mp3", 0, 0, 0);_getch();//暂停,按任意键继续return true;}else if (gameresult == DRAW){Sleep(2000);loadimage(0, "res/平局.png",W , L , true);_getch();return true;}else//继续游戏{return false;}}

五、玩家类实现 

5.1  用玩家类构造函数初始化

5.1.1  chess_player.h

#include"checkerboard.h"
#include"AI.h"
class chess_player
{
public:chess_player(checkerboard& checkerboard){this->checkerboard = &checkerboard;}void go();
private:checkerboard* checkerboard;
};

5.2  玩家下棋

5.2.1 chess_player.h

void go();

5.2.2  chess_player.cpp 

void chess_player::go()
{ChessPos pos;while (1){MOUSEMSG mousemsg = GetMouseMsg();//鼠标信息结构体变量bool click_board = checkerboard->ClickBord(mousemsg.x, mousemsg.y, pos);if (mousemsg.uMsg == WM_LBUTTONDOWN &&click_board )//用到checkboard对象的成员{printf("%d,%d\n", pos.row, pos.col);break;}}checkerboard->PlayChess(pos, CHESS_BLACK);//黑子下棋的位置(渲染和记录)
}

六、AI类实现

6.1 用AI类构造函数初始化

6.1.1  AI.h

#include"checkerboard.h"
#include<vector>
class AI
{
public:AI(checkerboard& checkerboard)//AI构造函数{this->checkerboard = &checkerboard;for (int i = 0; i <checkerboard.ChessSize; i++){vector<int> row;for (int j = 0; j <checkerboard.ChessSize; j++){row.push_back(0);}ScoreMap.push_back(row);}}void go();private:checkerboard* checkerboard;vector<vector<int>>  ScoreMap;void  CalculateScore();ChessPos   MaxScore();};

6.2  AI计算权值最高的棋盘空白位置

计算棋盘空白位置的权值,首先对该位置的横、竖、上斜、下斜四个方位做判断,以该位置为起点,每个方位只需要在单方向上判断4个棋子位,反方向判断四个棋子位,统计连续的白子或者黑子个数,根据下面的表格给出相应权重值,选择出累计权值最高的位置为AI落子点。

 6.2.1  AI.h 

private:vector<vector<int>>  ScoreMap;void  CalculateScore();

  6.2.2  AI.cpp

void AI::CalculateScore()
{int Black_Num = 0;int White_Num = 0;int Empty_Num = 0;for(int row=0;row<checkerboard->BoardSize;row++)for (int col = 0; col< checkerboard->BoardSize; col++){if (checkerboard->BoardMap[row][col] != 0)//有棋子,则跳过判断{continue;}//先假设下黑子,计分情况for (int i = 0; i <= 1; i++)//分横,竖,上斜,下斜4个方向{for (int j = -1; j <= 1; j++){//每个方向记连续棋子个数Black_Num = 0;White_Num = 0;Empty_Num = 0;if ((i == 0 && j == 0) || (i ==0 && j == 1)){continue;}for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中的单向{int Cur_row = row + i * k;int Cur_col = col + j * k;if (Cur_row>=0&&Cur_row<checkerboard->BoardSize&&Cur_col>=0&&Cur_col<checkerboard->BoardSize&&checkerboard->BoardMap[Cur_row][Cur_col] == CHESS_BLACK){Black_Num++;}else if(Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&checkerboard->BoardMap[Cur_row][Cur_col] ==0){Empty_Num++;break;}else//超出棋盘或者是白子{break;}}for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中单向的另一个方向{int Cur_row = row - i * k;int Cur_col = col - j * k;if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&checkerboard->BoardMap[Cur_row][Cur_col] == CHESS_BLACK){Black_Num++;}else if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&checkerboard->BoardMap[Cur_row][Cur_col] == 0){Empty_Num++;break;}else//超出棋盘或者是白子{break;}}//该位置的得分情况if (Black_Num == 1)//2个黑子{ScoreMap[row][col] += 10;}else if (Black_Num == 2)//连续三个黑子{if (Empty_Num == 1){ScoreMap[row][col] += 30;}else if(Empty_Num==2){ScoreMap[row][col] += 40;}}else if (Black_Num == 3)//连续4个黑子{if (Empty_Num == 1){ScoreMap[row][col] += 60;}else if (Empty_Num == 2){ScoreMap[row][col] += 200;}}else if (Black_Num == 4)//连续5个黑子{ScoreMap[row][col] += 20000;}}}//假设该位置下白子,计分情况for (int i = 0; i <= 1; i++)//分横,竖,上斜,下斜4个方向{for (int j = -1; j <= 1; j++){//每个方向记连续棋子个数Black_Num = 0;White_Num = 0;Empty_Num = 0;if ((i == 0 && j == 0) || (i == 0 && j == 1)){continue;}for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中的单向{int Cur_row = row + i * k;int Cur_col = col + j * k;if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&checkerboard->BoardMap[Cur_row][Cur_col] == CHESS_WHITE){White_Num++;}else if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&checkerboard->BoardMap[Cur_row][Cur_col] == 0){Empty_Num++;break;}else//超出棋盘或者是黑子{break;}}for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中单向的另一个方向{int Cur_row = row - i * k;int Cur_col = col - j * k;if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&checkerboard->BoardMap[Cur_row][Cur_col] == CHESS_WHITE){White_Num++;}else if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&checkerboard->BoardMap[Cur_row][Cur_col] == 0){Empty_Num++;break;}else//超出棋盘或者是黑子{break;}}//该位置的得分情况if (White_Num == 0)//1个白子{ScoreMap[row][col] += 5;}else if (White_Num == 1)//连续2个白子{ScoreMap[row][col] += 10;}else if (White_Num == 2)//连续3个白子{if (Empty_Num == 1){ScoreMap[row][col] += 25;}else if (Empty_Num == 2){ScoreMap[row][col] += 50;}}else if (White_Num == 3)//连续4个白子{if (Empty_Num == 1){ScoreMap[row][col] += 55;}else if (Empty_Num == 2){ScoreMap[row][col] += 300;}}else if (White_Num == 4)//连续5个白子{ScoreMap[row][col] += 30000;}}}}
}

6.3  选择权值最高的棋盘位置

 6.3.1  AI.h 

private:
ChessPos   MaxScore();

 6.3.2  AI.cpp

ChessPos AI::MaxScore()
{int max = 0;vector<ChessPos> maxscore_pos;ChessPos pos;CalculateScore();for (int row = 0; row < checkerboard->BoardSize; row++){for (int col = 0; col < checkerboard->BoardSize; col++){if (ScoreMap[row][col] > max){max = ScoreMap[row][col];maxscore_pos.clear();pos.row = row;pos.col = col;maxscore_pos.push_back(pos);}else if (ScoreMap[row][col] == max){pos.row = row;pos.col = col;maxscore_pos.push_back(pos);}}}//计分棋盘归0for (int i = 0; i < checkerboard->ChessSize; i++){for (int j = 0; j < checkerboard->ChessSize; j++){ScoreMap[i][j] = 0;}}int index = rand() % maxscore_pos.size();return maxscore_pos[index];
}

 6.4 AI下棋

 6.4.1  AI.h 

void go();

 6.4.2  AI.cpp

void AI::go()
{ChessPos pos = MaxScore();checkerboard->PlayChess(pos, CHESS_WHITE);//白子下棋的位置(渲染和记录)
}

 七、棋盘控制类实现

7.1 用棋盘控制类构造函数初始化

7.1.1 ChessGame.h

#include"chess_player.h"
#include"AI.h"
#include"checkerboard.h"
class ChessGame
{
public:ChessGame(chess_player& chess_player, AI& ai, checkerboard& checkerboard)//构造函数初始化{this->chess_player = &chess_player;this->ai = &ai;this->checkerboard = &checkerboard;}void play();//开始游戏//创建数据成员变量
private:chess_player* chess_player;AI* ai;checkerboard* checkerboard;};

7.2 控制游戏进行

7.2.1 ChessGame.h 

void play();//开始游戏

7.2.2 ChessGame.cpp

//开始游戏void ChessGame::play()
{
again:checkerboard->Init();while (1){//棋手先走chess_player->go();if (checkerboard->CheckOver()){goto  again;}//AI走ai->go();if (checkerboard->CheckOver()){goto  again;}}
}

八、主函数

#include<iostream>
#include"ChessGame.h"
int main()
{srand((unsigned int)time(NULL));checkerboard checkerboard( 13, 45*0.7, 45*0.7,67.25*0.7);//自动调用构造函数chess_player chess_player(checkerboard);//自动调用构造函数AI ai(checkerboard);//自动调用构造函数;ChessGame chessgame(chess_player,ai, checkerboard);//引用传值chessgame.play();return 0;}

完整代码及素材:c和c++代码: 争取每日一更。。。。。。 - Gitee.comicon-default.png?t=N7T8https://gitee.com/daily-brush-100-questions/c-language-training-camp/tree/master/c++AI%E4%BA%94%E5%AD%90%E6%A3%8B/c++AI%E4%BA%94%E5%AD%90%E6%A3%8B

希望大家阅读完可以有所收获,同时也感谢各位铁汁们的支持。文章有任何问题可以在评论区留言,百题一定会认真阅读!

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

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

相关文章

vue保姆级教程----深入了解 Vue3路由守卫

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; CSS专栏&#xff1a;想学CSS的&#xff0c;冲这里 &#x1f4…

非英专生雅思首考 8 分经验贴

非英专生雅思首考 8 分经验贴 备考材料1.网站2.微信公众号3.APP4.PDF资料5.纸质教辅书 四个单项听力阅读写作口语注意事项 又来了&#xff0c;好文当分享&#xff01;如侵删。 背景&#xff1a;某工科学校经管类专业学生&#xff0c;7月份刚毕业。四级643&#xff0c;六级604。…

Netty实战(待完善)

Netty组件 1. Bootstrap, ServerBootstrap Netty 中 Bootstrap 类是客户端程序的启动引导类&#xff0c;ServerBootstrap 是服务端启动引导类。 2. NioEventLoop, NioEventLoopGroup NioEventLoop 中维护了一个线程和任务队列&#xff0c;支持异步提交执行任务&#xff0c;…

Spring——Spring IOC(1)

Spring IOC 创建工程&#xff1a; 1.程序的耦合 耦合&#xff1a;耦合指的就是对象之间的依赖关系。对象之间的耦合越高&#xff0c;维护成本越高。 案例&#xff1a;没有引入IOC容器时系统的Web层、业务层、持久层存在耦合 /*** 持久层实现类*/ public class UserDaoImpl …

SpringBoot的测试

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

12.递归汉诺塔

使用递归实现汉诺塔 public class Main {public static void move(char pos1,char pos2) {System.out.print(pos1" > "pos2" ");}public static void han(int n,char pos1,char pos2,char pos3) {if(n 1) {move(pos1,pos3);return ;}han(n-1,pos1,pos…

阿里、字节等大厂系统测试方法的知识点总结,终于被我搞到手了

系统测试一般采取黑盒测试&#xff0c;系统测试的方法也比较多&#xff0c;其中常用的方法有&#xff1a;多任务测试、临界测试、中断测试、等价划分测试 多任务测试 多任务测试是指在非idle状态下&#xff0c;测试对象处于工作状态时&#xff0c;有新的事件发生&#xff0c;…

multipath 内核接口及框架介绍

文章目录 1 云主机使用网络存储 io 流程2 multipath 介绍 1 云主机使用网络存储 io 流程 对于一个云服务环境&#xff0c;大致会有网络节点&#xff0c;存储节点&#xff0c;计算节点&#xff0c;控制节点&#xff0c;其中虚拟云主机在计算节点工作&#xff0c;而虚拟云主机&a…

LCR 176. 判断是否为平衡二叉树

解题思路&#xff1a; class Solution {public boolean isBalanced(TreeNode root) {return recur(root) ! -1;}private int recur(TreeNode root) {if (root null) return 0;int left recur(root.left);if(left -1) return -1;int right recur(root.right);if(right -1) …

ebay头像如何设置?eBay店铺的头像怎么改?-站斧浏览器

ebay头像如何设置&#xff1f; eBay店铺的头像可以通过以下方式进行设置&#xff1a; 登录eBay账户&#xff1a;店主需要使用自己的eBay账号登录到eBay网站。 进入店铺管理后台&#xff1a;在登录后&#xff0c;店主可以点击页面右上角的用户名或店铺名称&#xff0c;从下拉…

被低估的流量宝地,如何通过Reddit为Shopify店铺引流?

独立站店铺相对于电商平台来说&#xff0c;有一个运营难点那就是需要自主引流。做好引流&#xff0c;你的Shopify店铺也就成功了一半。Reddit作为国外知名的论坛平台&#xff0c;非常适合作为引流的阵地&#xff0c;许多人对这个网站尚不了解&#xff0c;接下来就为大家介绍如何…

HackTheBox - Medium - Linux - Socket

Socket Socket 是一台中等难度的 Linux 机器&#xff0c;其特点是反转 Linux/Windows 桌面应用程序以获取其源代码&#xff0c;从那里发现其 Web 套接字服务中的“SQL”注入。转储数据库会显示一个哈希值&#xff0c;一旦破解&#xff0c;就会产生对该框的“SSH”访问。最后&a…

1295. X的因子链(数论/求1~N的所以质因子)

题目&#xff1a; 1295. X的因子链 - AcWing题库 输入样例&#xff1a; 2 3 4 10 100输出样例&#xff1a; 1 1 1 1 2 1 2 2 4 6 思路&#xff1a; 代码&#xff1a; #include <cstdio> #include <cstring> #include <iostream> #include <algorithm…

Gin 路由注册与请求参数获取

Gin 路由注册与请求参数获取 文章目录 Gin 路由注册与请求参数获取一、Web应用开发的两种模式1.前后端不分离模式2.前后端分离模式 二、RESTful介绍三、API接口3.1 RESTful API设计指南3.2 API与用户的通信协议3.3 RestFul API接口设计规范3.3.1 api接口3.3.2 接口文档&#xf…

viewer插件——预览图片时一直闪烁——问题修复,亲测有效

viewer插件——预览图片时一直闪烁——问题修复&#xff0c;亲测有效 viewer插件的介绍遇到的问题——图片会一直重复加载&#xff0c;造成图片在闪烁的效果解决方法 viewer插件的介绍 之前写过一篇文章&#xff0c;是关于v-viewer图片预览插件——vue2插件集合(elementUi中的…

JAVA 终极面试题

目录标题 一: JAVA 基础1.JDK和JRE有什么区别&#xff1f;2. 面向对象的特征&#xff08;了解&#xff09;3. 和equals的区别是什么&#xff1f;4.两个对象的hashCode()相同,则equals()一定为true&#xff0c;对吗&#xff1f;5.final关键字在java中的作用6.java中的Math.round…

bat批处理文件_命令汇总(1)

文章目录 1、复制文件&#xff1a;2、 移动文件&#xff1a;3、删除文件&#xff1a;4、创建目录&#xff1a;5、删除目录&#xff1a;6、切换目录&#xff1a;7、显示当前目录&#xff1a;8、运行程序&#xff1a;9、显示系统环境变量&#xff1a;10、设置环境变量&#xff1a…

HCIA-Datacom题库(自己整理分类的)——OSPF协议判断

1.路由表中某条路由信息的Proto为OSPF则此路由的优先级一定为10。√ 2.如果网络管理员没有配置骨干区域,则路由器会自动创建骨干区域&#xff1f; 路由表中某条路由信息的Proto为OSPF&#xff0c;则此路由的优先级一定为10。 当两台OSPF路由器形成2-WAY邻居关系时&#xff0…

Android 相机库CameraView源码解析 (四) : 带滤镜预览

1. 前言 这段时间&#xff0c;在使用 natario1/CameraView 来实现带滤镜的预览、拍照、录像功能。 由于CameraView封装的比较到位&#xff0c;在项目前期&#xff0c;的确为我们节省了不少时间。 但随着项目持续深入&#xff0c;对于CameraView的使用进入深水区&#xff0c;逐…

【OpenBMC】的内部README 模板

OpenBMC 本项目的AST2500分支核心代码的机型是ast2500-default&#xff0c;克隆代码后进入编译环境的命令为&#xff1a; source setup ast2500-default 一、源码下载、配置以及编译 重要&#xff1a;请参阅confluence 详细步骤 二、代码使用方法 目前所有自定义修改的代码…