基于MFC实现的人机对战五子棋游戏
基于MFC实现的人机对战五子棋游戏
1、引言
此报告将详细介绍本次课程设计的动机、设计思路及编写技术的详细过程,展现我所学过的C++知识以及我通过本次课程设计所学到例如MFC等知识。在文档最后我也会记录我所编写过程遇到的问题以及解决方案。
1.1 背景
五子棋是起源于中国古代的传统黑白棋种之一,此游戏不仅能增强思维能力,提高智力,而且变化多端,非常富有趣味性和消遣性,伸手人们喜爱。而且人工智能发展迅速,人们不断制造出可以用机器代替人们做一些事的程序,包括五子棋等棋类小游戏。随着经济的快速发展,人们的生活节奏也越来越快,随之而来的便是人们越来越少的空闲时间,而此类小游戏不占空间,占用时间也少,所以成了很多人喜爱的娱乐方式。
传统五子棋的棋具与围棋大致相同,棋子分为黑白两色,棋盘为15×15,棋子放置于棋盘线交叉点上。两人对局,各执一色,轮流下一子,先将横、竖或斜线的5个或5个以上同色棋子连成不间断的一排者为胜(正规比赛中黑棋只能连成5个。6-9个一排算禁手,另外黑棋还有33和44禁手。黑棋禁手判负。白棋没有限制)。 因为传统五子棋在落子后不能移动或拿掉,所以也可以用纸和笔来进行游戏。随着五子棋的发展,逐步发现先行优势非常大,最后得出“先行必胜”即现代五子棋。本游戏为传统无禁手五子棋,适用于初学者。
1.2 动机
五子棋游戏如果开发成功,有以下几个好处:
- 可以增强人们的抽象思维能力、逻辑推理能力、空间想象力、提高人们的记忆力、心算能力等,而且深含哲理,有助于修身养性
- 可以作为人们休闲时的娱乐,容易上手,老少皆宜,而且趣味横生,引人入胜
所以,本系统旨在开发一个传统五子棋小游戏程序。
1.3 要解决的问题
本系统要提供以下几个功能:
- 玩家信息录入功能:在主界面初始化之前,调用对话框的DoModal函数,产生一个对话框即登陆界面,在登录界面录入玩家姓名、年龄和性别,点击登录在对话框结束后,根据结果判断,再进行主界面的初始化,显示玩家信息
- 棋盘绘制:关于棋盘的呈现采用GDI DrawImage 的方法先准备一张15*15的棋盘图片,在OnPaint()函数中从备份DC拷贝到屏的DC里实现图片的显示。再是绘制棋盘中的棋子,本程序根据棋盘坐标定义二维数组,用户在棋盘中放置棋子时,根据鼠标的坐标点获取对应棋子
- 人机对弈:进入主界面后即可进行人机对弈,程序默认为玩家先,可以通过游戏设置,选择人先机后或者机先人后。同时我为计算机设计了一套策略型智能算法,使得在用户每走一步棋后,电脑都要进行一次全盘扫描,然后根据算法选择出得分最高的位置即对对方最有威胁而对自己最有利的位置,选择最佳下棋点下棋,实现人机轮流走棋
- 输赢判断功能:在玩家或计算机每走一步棋后,通过算法判断是否有一方连续的棋子数在“横”、“竖”、“左斜”、“右斜”等于或超过五个棋子,若是则电脑将调用一个函数Messagebox(),弹出对话框提示输赢
- 悔棋功能:在玩家下棋后,如果想返回之前的棋局,则可点“悔棋”使得棋局回到下每步棋之前的棋局
- 错误示功能:如果玩家在下棋时,将棋子落在其它棋子的位置或者在棋盘外的位置时,将会弹出错误提示框,提示请到棋盘内落子
2、系统流程图
五子棋的游戏规则很简单,在玩家登录后开始游戏,在每次玩家或电脑下棋后,系统都要判断是否分出胜负,若否,另一方继续下棋;若是,提示输赢后,可以选择再来一局。下图是此系统的流程图,描述了系统的运行过程,以便大家了解游戏的原理。
3、数据结构设计
棋盘使用二维数组表示,15*15的棋盘就用m_board[15][15]的二维数组表示,第i行,第j列的元素应该是m_board[i][j]。
以下用自定义数据结构类型pos表示棋子位置:
struct pos
{int x,y; //x,y分别行列坐标int flag; //记录xy处下的是白棋还是黑棋;1--白棋
};
玩家信息表如下:
表中内容为数据库表格的三列名称:玩家姓名、年龄和性别,以及各自的数据类型。
4、关键技术
本系统是C++中的MFC基于对话框创建的MFC程序,主要致力于解决如下几个关键问题:
4.1 玩家信息登录
在主界面初始化之前,调用Dialog的DoModal函数,产生另外一个Dialog即登陆界面,玩家在登录界面输入玩家信息(玩家名,年龄,性别),完成后进入主界面,显示玩家信息。
玩家输入的信息
playername=dlg2.m_name; //玩家名
playerage=dlg2.m_age; //年龄
playersex=dlg2.m_sex; //性别
棋盘旁边显示的信息
dlg.m_cname=playername;
dlg.m_csex=playersex;
dlg.m_cage=playerage; //获取对象dlg的信息
dlg.DoModal(); //调用DoModal()函数
4.2 棋盘绘制
关于棋盘的呈现采用GDI DrawImage 的方法先准备一张15*15的棋盘图片,在OnPaint()函数中从源位图拷贝成为目的位图。
void CFivezq::DrawBoard()//画棋盘
{m_pdc->BitBlt(0,0,446,446,m_pboard,0,0,SRCCOPY);
}
4.3 棋子绘制
关于棋子的实现,在于读取鼠标点击的坐标来判断点击位置所在的格子,然后求出该格子的中心位置坐标,以该中心为圆心用GDI画黑色或白色圆,然后用画刷CBrush *brush分别填充黑白色即可。实现代码如下:
//游戏中画棋子
void CFivezq::DrawChess(int px, int py, int type)
//判断下棋次序,如果轮到白棋下
if(m_turn==1)//添加红色中心CPen pen_r(PS_SOLID,2,RGB(255,0,0));
else//如果轮到黑棋下CBrush *brush;
//定义黑色画刷填充黑色
CBrush brush1(RGB(0,0,0));
//窗口无效重画白棋
m_pdc->Ellipse(px*29+7,py*29+7,px*29+34,py*29+34);
CBrush *brush;
//窗口无效重画黑棋子
CBrush brush1(RGB(0,0,0));
4.4 计算机落子
4.4.1 评分算法
为方便后面介绍详细算法先介绍下五子棋相关术语
- 连:2枚以上的同色棋子在一条线上邻接成串
- 五连:五枚同色棋子在一条线上邻接连串
- 成五:五连和长连的统称
- 四:五连去掉1子的棋型
- 活四:有两个威胁的四
- 冲四:只有一个威胁的四
- 死四:不能成五的四连
- 三:可以形成四再形成五的三枚同色棋子组成的棋型
- 活三:再走一着可以形成活四的三
- 连活三:两端都是威胁的连三。简称“连三”
- 眠三:再走一着可以形成冲四的三
- 死三:不能成五的三
- 二:可以形成三、四直至五的两枚同色棋子组成的棋型
- 活二:再走一着可以形成活三的二
- 连活二:连的活二。简称“连二”
- 眠二:再走一着可以形成眠三的二
- 死二:不能成五的二
- 先手:对方必须应答的着法,相对于活三先手而言,冲四称为“绝对先手”
- 三三:一子落下同时形成两个活三。也称“双三”
- 四四:一子落下同时形成两个冲四。也称“双四”
- 四三:一子落下同时形成一个冲四和一个活三
电脑落子之前要对棋局进行判断,那就需要告诉电脑什么时候的局势最好,我们可以通过给不同局势时不同分值的办法来让电脑明白。评分的基本规则及实现代码如下:
//评分函数
void CFivezq::Evaluater(int (&flag)[2][2], int &n, int &score,int turn);
判断是否能成5,如果是电脑方给予100000分,如果是控制者方给予-100000分;
//五连以上,得最高分
else if(n>=5) if(turn==1)score=100000;elsescore=50000;
判断是否能成活4或者是双死4或者是死4活3,如果是电脑方给予10000分,如果是控制方给予-10000分;若成双活3,如果是电脑方给予5000分,如果是控制者方给予-50 00分;若成死3活3,如果是电脑方给予1000分,如果是控制者方给予-1000分;
//活四+****+
if(flag[1][1]&&flag[0][1])if(turn==1)score=10000;elsescore=4000;
判断是否能成死4,如果是电脑方给予500分,如果是控制者方给予-500;
//死四
if(flag[1][0]&&flag[0][0])score=500;
if((flag[1][0]&&flag[0][1])||(flag[1][1]&&flag[0][0]))//冲四o****+ 轮到己方下子冲四>活三if(turn==1)score=4000; elsescore=2500;
判断是否能成单活3,如果是电脑方给予200分,如果是控制者方给予-200分;
//o**---|---**o 眠三
if((flag[1][0]&&flag[0][1])||(flag[1][1]&&flag[0][0]))score=200;
判断是否已成双活2,如果是电脑方给予100分,如果是控制者方给予-100分;若成死3,如果是电脑方给予50分,如果是控制者方给予-50分;
//死三o***o
if(flag[1][0]&&flag[0][0])score=120;
if(flag[1][1]&&flag[0][1])if(turn==1)//活三+***+score=3000; elsescore=2000;
判断是否成眠2,如果是电脑房给予20分,如果是控制者方给予-20分;
//o**---|---**o 眠二
if((flag[1][0]&&flag[0][1])||(flag[1][1]&&flag[0][0]))score=20;
判断是否能成双活2,如果是电脑方给予10分,如果是控制者方给予-10分;判断是否能成活2,如果是电脑方给予5分,如果是控制者方给予-5分;
//活二
if(flag[1][1]&&flag[0][1]) if(turn==1)score=50;elsescore=40;
判断是否能成死2,如果是电脑方给予3分,如果是控制者方给予-3分。
//死二
if(flag[1][0]&&flag[0][0])score=3;
4.4.2 判断最佳落子点核心算法
要使电脑落子必须令计算机知道自己及对方的棋型才行。先来分析己方的棋型,我们从棋盘左上角出发,向右逐行搜索,当碰到一个空白点时,以它为中心向左挨个查找,假如碰到己方的子则记录然后继续,假如碰到对方的子、空白点或边界就停止查找。左边完成后再向右进行同样的操作;最后把左右两边的记录合并起来,得到的数据就是该点横向上的棋型,然后把棋型的编号填入到Computer[x][y][n]中就行了(x、y代表坐标,n=0、1、2、3分别代表横、竖、左斜、右斜四个方向)。而其他三个方向的棋型也可用同样的方法得到,当 搜索完整张棋盘后,己方棋型表也就填写完毕了。然后再用同样的方法填写对方棋型表。
实现代码如下:
//核心算法
void CFivezq::ChessExpert(CPoint &best)
//应全部初始化为零
int computer[15][15][4]={0},player[15][15][4]={0};
//标志数组:标志该空位两端是否到达边界(遇到对方棋子)/遇到空位
int flag[2][2]={0};
int count=0,i,j,k,m;
//(x,y)存储向右搜索时遇到边界/空位/对方棋子时的前一个坐标,向左搜索的起点
int x=0,y=0;
横向向左搜索
//横向--->
for(k=1;k<5;k++)
{//横向右遇到边界if(i+k>14){flag[0][0]=1;break;}//横向右遇到对方棋子+***oif(m_board[i+k][j]==-m_turn){flag[0][0]=1;break;}//横向右遇到空位++*++if(m_board[i+k][j]==0){flag[0][1]=1;break;}
}
横向向右搜索
//横向<---
for(m=0;m>-5;m--)
{//横向左遇到边界if(x+m<0){flag[1][0]=1;break;}if(m_board[x+m][y]==m_turn)count++;//横向左遇到对方棋子o***+if(m_board[x+m][y]==-m_turn){flag[1][0]=1;break;}//横向左遇到空位++*++if(m_board[x+m][y]==0){flag[1][1]=1;break;}
}
纵向向下搜索
//纵向下遇到边界
if(j+k>14)
{flag[0][0]=1;break;
}
//纵向下 遇到对方棋子+***o
if(m_board[i][j+k]==-m_turn)
{flag[0][0]=1;break;
}
//纵向下遇到空位++*++
if(m_board[i][j+k]==0)
{flag[0][1]=1;break;
}
纵向向上搜索
//纵向上遇到界
if(y+m<0)
{flag[1][0]=1;break;
}
if(m_board[x][y+m]==m_turn)count++;
//纵向上遇到对方棋子o***+
if(m_board[x][y+m]==-m_turn)
{flag[1][0]=1;break;
}
//纵向上遇到空位++*++
if(m_board[x][y+m]==0)
{flag[1][1]=1;break;
}
45度向下搜索
//45°向下遇到边界
if(i+k>14||j+k>14)
{flag[0][0]=1;break;
}
//45°向下遇到对方棋子+***o
if(m_board[i+k][j+k]==-m_turn)
{flag[0][0]=1;break;
}
//45°向下遇到空位++*++
if(m_board[i+k][j+k]==0)
{flag[0][1]=1;break;
}
45度向上搜索
//45°向上遇到边界
if(x+m<0||y+m<0)
{flag[1][0]=1;break;
}
//45°向上遇到对方棋子o***+
if(m_board[x+m][y+m]==-m_turn)
{flag[1][0]=1;break;
}
//45°向上遇到空位++*++
if(m_board[x+m][y+m]==0)
{flag[1][1]=1;break;
}
135度向下搜索
//135°向下遇 到边界
if(i-k<0||j+k>14)
{flag[0][0]=1;break;
}
//135°向下遇到对方棋子+***o
if(m_board[i-k][j+k]==-m_turn)
{flag[0][0]=1;break;
}
//135°向下遇到空位++*++
if(m_board[i-k][j+k]==0)
{flag[0][1]=1;break;
}
135度向上搜索
//135°向上遇到边界
if(x-m>14||y+m<0)
{flag[1][0]=1;break;
}
//135°向上遇到对方棋子o***+
if(m_board[x-m][y+m]==-m_turn)
{flag[1][0]=1;break;
}
//135°向上遇到空位++*++
if(m_board[x-m][y+m]==0)
{flag[1][1]=1;break;
}
4.4.3 计算机落子函数
有了上面填写的两张棋型表,现在要作的就是让电脑知道在哪一点下子了。其中最简单的计算方法就是遍历棋型表computer[15][15][4]和player[15][15][4],在通过评分算法找出其中数值最大的一点,在该点下子即可。实现代码如下:
//电脑得分,玩家得分;初始化为0;
int cpscore[15][15],plscore[15][15];
//求每一可能下子的交叉点得分
for(i=0;i<15;i++)
从电脑角度求出最佳下棋点:
//从电脑角度 最好的点(cpx,cpy)
int cpmax=0,cpx=0,cpy=0;
cpmax=cpscore[0][0];
if(cpmax<cpscore[i][j])
{cpmax=cpscore[i][j];cpx=i;cpy=j;
}
从玩家角度选出最佳下棋点:
//从玩家角度 最好的点(cpx,cpy)
int plmax=0,plx=0,ply=0;
plmax=plscore[0][0];
if(plmax<plscore[i][j])
{plmax=plscore[i][j];plx=i;ply=j;
}
4.5 判断输赢
当棋盘中出现连续五个或以上同色棋子相连时,即可判定输赢。实现代码如下:
// 判赢函数
int CFivezq::WhoWin(int nx,int ny)
判断水平行还是否连成五个子,只要够了5个就返回1,否则返回0.
for(i=0;i>-5;i--)
{if(nx+i<0)continue;if(m_board[nx+i][ny]==m_turn){count++;if(count>=5)return m_turn;}elsebreak;
}//向右判断
for(i=1;i<5;i++)
{if(nx+i>14)break;if(m_board[nx+i][ny]==m_turn){count++;if(count>=5)return m_turn;}elsebreak;
}
判断竖行是否连成五个子:
//向下判断
for(i=0;i>-5;i--)
{if(ny+i<0)continue;if(m_board[nx][ny+i]==m_turn){count++;if(count>=5)return m_turn;}elsebreak;
}
//向上判断
for(i=1;i<5;i++)
{if(ny+i>14)break;if(m_board[nx][ny+i]==m_turn){count++;if(count>=5)return m_turn;}elsebreak;
}
判断从左上到右下是否连成五个子:
//向135度判断
for(i=0;i>-5;i--)
{if(nx+i<0||ny+i<0)continue;if(m_board[nx+i][ny+i]==m_turn){count++;if(count>=5)return m_turn;}elsebreak;
}
//向45度判断
for(i=1;i<5;i++)
{if(nx+i>14||ny+i>14)break;if(m_board[nx+i][ny+i]==m_turn){count++;if(count>=5)return m_turn;}elsebreak;
}
判断从右上到右下是否连成五个子:
//向135度判断
for(i=0;i>-5;i--)
{if(ny+i<0)continue;if(nx-i>14)break;if(m_board[nx-i][ny+i]==m_turn){count++;if(count>=5)return m_turn;}elsebreak;
}
//向45度判断
for(i=1;i<5;i++)
{if(nx-i<0)continue;if(ny+i>14)break;if(m_board[nx-i][ny+i]==m_turn){count++;if(count>=5)return m_turn;}elsebreak;
}
4.6 悔棋
在之前的数据中已经保存了各黑白棋子的坐标struct pos ,pos posinfo[225];只要在重画一次即可。实现代码如下:
//悔棋函数
void CFivezq::BackGo(HWND hwnd,int gamemode)
若游戏模式为机先人后时的代码:
m_board[posinfo[posflag-1].x][posinfo[posflag-1].y]=0;
m_board[posinfo[posflag-2].x][posinfo[posflag-2].y]=0;
posflag=posflag-2;
while(posflag==1)posflag--;
游戏模式为人先机后时的代码:
{m_board[posinfo[posflag-1].x][posinfo[posflag-1].y]=0;m_board[posinfo[posflag-2].x][posinfo[posflag-2].y]=0;posflag=posflag-2;
}
消息提示:
elseMessageBox(hwnd,"您已经没有棋可悔!",NULL,MB_OK);
5、系统运行结果
5.1 系统运行环境
- 硬件环境
- 处理器:Intel® Core™ i5 CPU M 460@2.53GHz 2.53GHz
- 内存:2.00GB
- 软件环境
- 操作系统:Windows7
- 编码工具:Microsoft Visual C++ 6.0或 Microsoft Visual Studio 2010
5.2 系统服务模式
本系统是基于C++的MFC中的对话框Dialog进行开发的,所以系统的服务模式是windows窗体程序。
5.3 系统运行结果
5.3.1 系统主界面
本系统是五子棋游戏系统,在系统主界面的棋盘中即可落子下棋,在右侧可以看到玩家信息以及游戏的功能按钮。系统主界面如下图5.1所示:
5.3.2 登录界面
程序运行开始弹出登陆对话框,输入玩家姓名、年龄和性别,然后登录即可进入主界面。玩家登录界面如下图5.2所示:
5.3.3 玩家信息显示界面
玩家在登录界面输入信息登录后,其信息便显示在主界面。玩家信息显示界面如下图5.3所示:
5.3.4 游戏设置界面
玩家在游戏时可以设置游戏的模式:人先机后或者机先人后,也可以选择玩家的棋子颜色:黑棋或者白棋。游戏设置按钮如下图5.4所示:
游戏设置界面如下图5.5所示:
5.3.5 判断输赢界面
玩家下棋后,系统会根据算法判断棋局输赢并弹出对话框提示。胜利界面如下图5.6所示:
失败界面如下图5.7所示:
5.3.6 错误提示界面
当玩家下棋时,如果点击使棋子落在已有棋子的位置上,则会弹出错误提示“此处已经有棋子”;若点击使棋子落在棋盘外时,则会弹出错误提示“请到棋盘内下子”;当玩家悔棋至没有棋子可以悔时,则会弹出错误提示“您已经没有棋可以悔”。
“此处已经有棋子”错误提示界面如下图5.8所示:
“请到棋盘内下子”错误提示界面如下图5.9所示:
“您已经没有棋可以悔”错误提示界面如下图5.10所示:
5.3.7 帮助界面
如果玩家对五子棋不是很了解,可以通过点击“帮助”按钮进入帮助界面查看五子棋简介及游戏规则。帮助界面如下图5.11所示:
6、调试和改进
在游戏设计之初有许多BUG,其中我觉得影响最大的就是编写评分算法时分值的设置。开始我设置的分值差距较小,计算机在判断棋型得分时因为分数的累加得到相同的分数,而电脑在判断双方的分值的时候,就是在落子时对自己的落子点分值和对方的分值进行对比来进行之后落子的判断,分数相同就会使电脑判断错误,导致程序不够“聪明”,即使编写再好的算法也是杯水车薪。所以,后来便将评分算法的分值差距拉大,是电脑能够正确判断,程序能够正确运行。
7、心得和结论
7.1 结论
这是我第一次做课程设计,所以感触颇深。在设计时我遇到了许多问题,但是在解决问题的过程中也收获了很多知识和经验。在诸多困难中,我体会最深的一点就是设计系统架构的重要性。这个五子棋游戏程序不是很大,但是代码的组织是很重要的,因为关系到日后的维护和扩展。在设计之初,我主要针对五子棋的核心算法进行了研究,并得出一段合适的代码,但后来我便认识到这不仅仅是一个算法的问题,因为在完成核心算法之后,还有其他的功能需要编码实现。由于我的系统架构设计在编程之前没有做好,导致很多功能在编码实现的时候非常困难,所以在程序设计之初,必须设计一个好的系统架构才能将如此多个功能、如此多条代码合理的组织在一起,完成一个高性能的完整程序。
本次课程设计也令我获益匪浅。首先,我通过自己的努力完成了一个小型游戏程序设计与实现,也是对自己之前所学专业知识的复习以及能力的肯定,并在此基础上强化自己的实践意识,提高了我的实际动手能力和创新能力。其次,在解决设计过程中遇到的问题时,同学们一起交流经验,不仅获取了知识、开拓了自己的思路,而且还提升了同学之间的凝聚力和解决问题的积极性。再次,因为自己是第一次做课程设计,所以在经验及能力上还是有许多不足之处,需要查阅许多资料才能完成,在找资料的同时我找到了许多好的网站、论坛,比如CSDN IT技术社区,在这个社区中我可以同许多有经验和能力的人交流专业知识,也可以下载许多有用的资料,是自己将来工作或学习中解决问题的良好平台。
虽然这次做的程序有一定的缺陷,但是我相信在进一步的学习以及有了如此宝贵的经验之后,我一定会作出更好的作品。
7.2 进一步改进方向
随着互联网的迅速发展,人们对游戏的要求也越来越高,人机对弈的实现是不够的。本系统的改进方向是能够增加人人对弈功能并连接网络,使得玩家可以通过网络进行对弈。希望有一天可以实现。
主要参考文献
[1] 五子棋百度百科http://baike.baidu.com/view/2697.htm
[2] 刘锐宁、宋坤,visual C++开发典型模块大全,人民邮电出版社,2009年2月。
[3] 郑阿奇、丁有和,C++实用教程,电子工业出版社, 2008年1月。
[4] 明日科技,Visual C++程序开发范例宝典,人民邮电出版社,2007年7月。
[5] C++课程设计五子棋游戏http://wenku.baidu.com/view/979c7ccada38376bae1fae06.html
[6] MFC教程http://wenku.baidu.com/view/9d97c1acdd3383c4bb4cd2f2.html
相关文章:
基于MFC实现的人机对战五子棋游戏
基于MFC实现的人机对战五子棋游戏 1、引言 此报告将详细介绍本次课程设计的动机、设计思路及编写技术的详细过程,展现我所学过的C知识以及我通过本次课程设计所学到例如MFC等知识。在文档最后我也会记录我所编写过程遇到的问题以及解决方案。 1.1 背景 五子棋是…...
mac电脑多个ssh keys共存
一、同一台电脑,不同域名的git仓库为什么要设置不同的ssh keys? 每个git仓库通常要求使用唯一的ssh key,以防止权限冲突和安全问题。 权限控制:每个git仓库的权限是独立的,使用不同的ssh keys可以更好的管理权限&…...
Elasticsearch数据迁移(快照)
1. 数据条件 一台原始es服务器(192.168.xx.xx),数据迁移后的目标服务器(10.2.xx.xx)。 2台服务器所处环境: centos7操作系统, elasticsearch-7.3.0。 2. 为原始es服务器数据创建快照 修改elas…...
【Java-数据结构篇】Java 中栈和队列:构建程序逻辑的关键数据结构基石
我的个人主页 我的专栏:Java-数据结构,希望能帮助到大家!!!点赞❤ 收藏❤ 一、引言 1. 栈与队列在编程中的角色定位 栈和队列作为两种基本的数据结构,在众多编程场景中都有着独特的地位。它们为数据的有序…...
使用ensp搭建内外互通,使用路由跨不同vlan通信。
1.网络拓扑图 2.规则 (1)允许 (自己)ping通内外网,内外网随便一个pc就可以. (2) 允许(电信)ping通内外网,内外网随便一个pc就可以 (时间问题不做…...
URDF 发布者
URDF 发布者 #! /usr/bin/env python3 import rclpy from rclpy.node import Node import rclpy.parameter from sensor_msgs.msg import JointState from rcl_interfaces.msg import SetParametersResultimport threading import timeclass RotateWheelNode(Node):def __init…...
用于目标检测的集中式特征金字塔
摘要 https://arxiv.org/pdf/2210.02093 视觉特征金字塔在多种应用中已展现出其在有效性和效率方面的优越性。然而,现有方法过度关注层间特征交互,却忽略了经验证明有益的层内特征调节。尽管一些方法试图借助注意力机制或视觉变换器来学习紧凑的层内特征表示,但它们忽略了…...
微信小程序购物车全选反选功能以及合计
微信小程序基于Vant Weapp的购物车功能实现 1、单选 使用微信小程序原生表单组件checkbox和checkbox-group 注意:checkbox原生不支持bind:change事件,checkbox-group支持 <checkbox-group bindchange"handleCheck"><checkbox val…...
大数据新视界 -- Hive 数据湖集成与数据治理(下)(26 / 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...
【基础数学二】整除,最大公约数约数,最小公倍数
整除 在数论中,一个整数 a a a 能够被另一个整数 d d d 整除,记做 d ∣ a d|a d∣a。 整除的性质: 如果 d ∣ a d | a d∣a,则对于任意整数 k k k 有 d ∣ k a d | ka d∣ka。如果 d ∣ a d|a d∣a 并且 d ∣ b d|b d∣…...
【lua语言基础(四)】IO模型以及补充知识
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:lua从入门到精通⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你学更多lua语言的知识 🔝🔝 lua语言基础 1. 简单的IO模型2…...
Python知识分享第十九天-网络编程
网络编程 概述用来实现 网络互联 不同计算机上运行的程序间可以进行数据交互也叫Socket编程 套接字编程 三要素IP地址概述设备在网络中的唯一标识分类IPV4城域网13广域网22局域网31IPV6八字节 十六进制相关dos命令查看ipwindows: ipconfigmac和linux: ifconfig测试网络ping 域…...
【JuMP.jl】非线性规划
[JuMP] 03 非线性规划 非线性规划模型 非线性规划问题是线性规划问题的自然推广, 在实际的工程问题中,优化问题中的目标函数与约束不会总是线性函数,因此非线性规划的求解功能是必要的。 min x ∈ R n f 0 ( x ) s.t. l j ≤ f j ( x ) ≤…...
网络(TCP)
目录 TCP socket API 详解 套接字有哪些类型?socket有哪些类型? 图解TCP四次握手断开连接 图解TCP数据报结构以及三次握手(非常详细) socket缓冲区以及阻塞模式详解 再谈UDP和TCP bind(): 我们的程序中对myaddr参数是这样…...
40分钟学 Go 语言高并发:服务性能调优实战
服务性能调优实战 一、性能优化实战概述 优化阶段主要内容关键指标重要程度瓶颈定位收集性能指标,确定瓶颈位置CPU、内存、延迟、吞吐量⭐⭐⭐⭐⭐代码优化优化算法、并发、内存使用代码执行时间、内存分配⭐⭐⭐⭐⭐系统调优调整系统参数、资源配置系统资源利用率…...
5092 星际争霸
逆序对排序; 字符串遍历; pair 特点: 两个值,第一个是字符串,第二个是逆序对数。而且没有重复的字符串。 #include<bits/stdc.h>using namespace std; typedef long long ll; const int N1e35; #define x f…...
AUTOSAR AP 汽车API知识点总结(Automotive API )R24-11
汽车API知识点总结 一、背景与目标 背景:智能互联汽车正逐步依赖远程诊断、软件更新等功能以确保行驶安全,并且用户已习惯于通过智能设备中的应用程序控制连接设备。虽然AUTOSAR标准支持车辆软件的可更新性,但尚未提供将AUTOSAR应用产生的数据和功能安全可靠地暴露给非AUTO…...
vue2:Cascader 级联选择器中加载两种不同的数据结构
前言 因UI调整,需要将el-tree控件更换为级联选择器,而在原树形控件中,加载了两种不同的数据结构,(参见vue2:树形控件el-tree中加载两种不同结构的数据_vue2 树形插件-CSDN博客)所以现在级联选择器中也需要加载这两种不同的数据结构。 问题 原本以为处理方式差不多,在…...
【xLSTM-Transformer序列分类】Pytorch使用xLSTM-Transformer对序列进行分类源代码
Python, Pytorch使用xLSTM-Transformer对序列进行分类源代码。xLSTM是不久前LSTM团队提出来的新模型,将xLSTM融入Transformer的Encoder中,创新型较强。另外,Transformer是完整的,即使用了Encoder、Decoder和Embedding所有模块。 …...
TDengine 签约安徽智质,助力海螺水泥智慧工厂升级
在当前制造业数字化转型的浪潮中,如何实现智能化、自动化与数据驱动的高效生产,成为企业提升竞争力的关键。尤其是在水泥、钢铁等传统行业,随着技术的不断进步,如何打破数据孤岛、提升生产管理效率,已经成为许多工厂亟…...
Hbase整合Mapreduce案例2 hbase数据下载至hdfs中——wordcount
目录 整合结构准备数据下载pom.xmlMain.javaReduce.javaMap.java操作 总结 整合结构 和案例1的结构差不多,Hbase移动到开头,后面跟随MR程序。 因此对于输入的K1 V1会进行一定的修改 准备 在HBASE中创建表,并写入数据 create "wunaii…...
WHLUG丨deepin、华中科技大学开放原子开源俱乐部、 RustSBI 和清华大学开源操作系统训练营共话开源新生代成长之路
2024年11月30日下午,由 deepin(深度)社区联合华中科技大学开放原子开源俱乐部、 RustSBI 开源社区和清华大学开源操作系统训练营共同举办的WHLUG(武汉Linux用户组)线下沙龙在华中科技大学成功举办。 本次活动聚集了50余…...
深入理解AVL树:结构、旋转及C++实现
1. AVL树的概念 什么是AVL树? AVL树是一种自平衡的二叉搜索树,其发明者是Adelson-Velsky和Landis,因此得名“AVL”。AVL树是首个自平衡二叉搜索树,通过对树的平衡因子进行控制,确保任何节点的左右子树高度差最多为1&…...
L15.【LeetCode笔记】相同的树
目录 1.题目 代码模板 2.分析 通过合理的if判断分类讨论两个根节点 1.首先,p和q都为NULL的情况最好排除 2.排除了两个都为NULL的情况,剩下的情况:1.其中一个为NULL;2.两个都不为NULL 写法1 写法2 3.只剩下最后一种情况:p和q都不为NULL 3.代码 提交结果 1.题目 https…...
【算法】【优选算法】位运算(下)
目录 一、:⾯试题 01.01.判定字符是否唯⼀1.1 位图1.2 hash思路1.3 暴力枚举 二、268.丢失的数字2.1 位运算,异或2.2 数学求和 三、371.两整数之和四、137.只出现⼀次的数字 II五、⾯试题 17.19.消失的两个数字 一、:⾯试题 01.01.判定字符是…...
网络——Socket与WebSocket
Socket与WebSocket都是网络通信中的重要概念,但它们在原理、应用场景及特性上存在显著的差异。以下是对两者的详细比较: 一、Socket 定义:Socket(套接字)是计算机网络中的一个抽象层,它允许应用程序通过网…...
Springboot3整合Redis
书接上篇《Redis 安装篇(阿里云服务器)_阿里云安装redis-CSDN博客》,安装好Redis后,就需要在springboot项目中使用Redis了。 一、SpringBoot整合Redis 1.添加坐标 <!--redis--> <dependency><groupId>org.sp…...
Java CountDownLatch 用法和源码解析
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...
微信小程序3-显标记信息和弹框
感谢阅读,初学小白,有错指正。 一、实现功能: 在地图上添加标记点后,标记点是可以携带以下基础信息的,如标题、id、经纬度等。但是对于开发来说,这些信息还不足够,而且还要做到点击标记点时&a…...
Android 消息队列之MQTT的使用:物联网通讯,HTTP太重了,使用MQTT;断网重连、注册、订阅、发送数据和接受数据,实现双向通讯。
目录: 问题MQTT是什么以及为什么使用如何使用:第一阶段、基础功能如何使用:第二阶段、增加断网重连如何使用:第三阶段、封装 一、问题 在开发的时候,我们一般都使用Http和后台进行通讯,比如我们是开发物联…...
详解Java数据库编程之JDBC
目录 首先创建一个Java项目 在Maven中央仓库下载mysql connector的jar包 针对MySQL版本5 针对MySQL版本8 下载之后,在IDEA中创建的项目中建立一个lib目录,然后把刚刚下载好的jar包拷贝进去,然后右键刚刚添加的jar包,点击‘添…...
详解C++类与对象(四)
文章目录 1.类型转换1.1 前言1.2 类型转换的性质 2.static成员2.1 前言2.2 static的基本概念 3.友元4.内部类5.匿名对象 1.类型转换 1.1 前言 在C中,由于程序员可以自己显示定义一个新的类。这样就会出现一个问题:程序员自己显示定义的类类型与编译器中…...
使用 postman 传递 binary 类型的图片到后端接口遇到的坑
使用 psotman 传 binary 类型图片报错: -2024-12-04 [http-nio-9090-exec-1] WARN org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required r…...
第9章 大模型的有害性(上)
9.1 引言 本章将探讨大型语言模型(LLMs)可能带来的有害性,重点讨论以下几个方面: 性能差异社会偏见和刻板印象 在后续内容中,还会涉及其他层面的危害,如有害信息、虚假信息、隐私和安全风险、版权问题、…...
计算机视觉——相机标定(Camera Calibration)
文章目录 1. 简介2. 原理3. 相机模型3.1 四大坐标系3.2 坐标系间的转换关系3.2.1 世界坐标系到相机坐标系3.2.2 相机坐标系到图像坐标系3.2.3 像素坐标系转换为图像坐标系3.2.4 世界坐标转换为像素坐标 3.3 畸变3.3.1 畸变类型3.3.1.1 径向畸变(Radial Distortion&a…...
Java爬虫技术全解析:从入门到精通
引言 在信息爆炸的今天,数据成为了最宝贵的资源之一。爬虫技术作为获取网络数据的重要手段,广泛应用于数据采集、信息聚合、市场分析等多个领域。Java作为一种强类型、面向对象的编程语言,以其稳健的性能和跨平台的特性,成为了开…...
leetcode hot100【Leetcode 416.分割等和子集】java实现
Leetcode 416.分割等和子集 题目描述 给定一个非负整数的数组 nums ,你需要将该数组分割成两个子集,使得两个子集的元素和相等。如果可以分割,返回 true ,否则返回 false。 示例 1: 输入:nums [1,5,11,…...
位段详解+代码展示
系列文章目录 🎈 🎈 我的CSDN主页:OTWOL的主页,欢迎!!!👋🏼👋🏼 🎉🎉我的C语言初阶合集:C语言初阶合集,希望能…...
python实现c++中so库调用及dbus服务开发
本期介绍主要分两块,一块是python如何调用so库,另一块是dbus服务的注册与调用; python调用so库 1. c++源码 # test.h文件#include<iostream> using namespace std;extern "C"{ int cacl(int a, int b); struct student{char sname[50];int score;}; stud…...
如何进行GC调优
目录 1、GC是什么? 垃圾回收算法、收集器等 2、优化目标 3、优化策略 这个属于较为开放题目,可以结合自己项目实战出发,体现JVM调优。 1、GC是什么? 垃圾回收算法、收集器等 2、优化目标 (1) 将进入老年代的对象数量降到最低 (2) 减少FullGC的执行…...
JAVA |日常开发中读写TXT文本详解
JAVA |日常开发中读写TXT文本详解 前言一、读取 TXT 文本1.1 使用BufferedReader读取1.2 使用Scanner读取 二、写入 TXT 文本2.1 使用BufferedWriter写入2.2 使用PrintWriter写入2.3 字节流写入(FileOutputStream)后转换为字符流(…...
开源模型应用落地-安全合规篇-用户输入价值观判断(三)
一、前言 在深度合规功能中,对用户输入内容的价值观判断具有重要意义。这一功能不仅仅是对信息合法性和合规性的简单审核,更是对信息背后隐含的伦理道德和社会责任的深刻洞察。通过对价值观的判断,系统能够识别可能引发不当影响或冲突的内容,从而为用户提供更安全、更和谐的…...
apache部署若依前后端分离项目(开启SSL)
网站部署之后,大多数需要配置https,所以本章教程,介绍使用apache部署若依前后端项目的时候,如何开启SSL,以及如何配置SSL证书。 一、安装ssl模块 默认情况下,ssl模块是没有安装的。需要手动安装,否则直接配置SSL模块的时候,会报错。 sudo yum install mod_ssl二、查询s…...
VMware Workstation Pro安装教程 (全图文保姆级)
一、前言 系统:Windows 11时间:2024/12/04需求:注册:broadcom(邮箱)难点:在官网找到下载链接 二、说明 建议前往官网(https://www.vmware.com)下载,可能加…...
【机器学习】—Transformers的扩展应用:从NLP到多领域突破
好久不见!喜欢就关注吧~ 云边有个稻草人-CSDN博客 目录 引言 一、Transformer架构解析 (一)、核心组件 (二)、架构图 二、领域扩展:从NLP到更多场景 1. 自然语言处理(NLP) 2…...
Linux权限机制深度解读:系统安全的第一道防线
文章目录 前言‼️一、Linux权限的概念‼️二、Linux权限管理❕2.1 文件访问者的分类(人)❕2.2 文件类型和访问权限(事物属性)✔️1. 文件类型✔️2. 基本权限✔️3. 权限值的表示方法 ❕2.3 文件访问权限的相关设置方法✔️1. ch…...
【数据集】细胞数据集:肿瘤-胎儿重编程的内皮细胞驱动肝细胞癌中的免疫抑制性巨噬细胞(Sharma等人)
引用此数据集: Sharma, Ankur (2020), “Onco-fetal reprogramming of endothelial cells drives immunosuppressive macrophages in Hepatocellular Carcinoma (Sharma et al)”, Mendeley Data, V1, doi: 10.17632/6wmzcskt6k.1 下载地址:Onco-feta…...
LangChain学习笔记(一)-LangChain简介
LangChain学习笔记(一)-LangChain简介 langChain是一个人工智能大语言模型的开发框架,主要构成为下图。 一、核心模块 (一)模型I/O模块 负责与现有大模型进行交互,由三部分组成: 提…...
【Dubbo03】消息队列与微服务之dubbo-admin 二进制与编译安装
实战案例:二进制安装 dubbo-admin 新版用Golang重构,提供了二进制包,可以直接部署 #下载二进制包 [rootubuntu2204 ~]#wget https://github.com/apache/dubbo-admin/releases/download/0.5.0/apache-dubbo-admin-0.5.0-bin-release.tar.gz …...
常见问题QA的前端代码
这个的后端代码参见此文 使用语言向量建立常见问题的模糊搜索-CSDN博客https://blog.csdn.net/chenchihwen/article/details/144207262?spm1001.2014.3001.5501 这段代码实现了一个简单的问答页面,页面分为左右两部分,左侧用于展示对话记录,…...