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

基于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、引言 此报告将详细介绍本次课程设计的动机、设计思路及编写技术的详细过程&#xff0c;展现我所学过的C知识以及我通过本次课程设计所学到例如MFC等知识。在文档最后我也会记录我所编写过程遇到的问题以及解决方案。 1.1 背景 五子棋是…...

AIGC 时代的文学:变革与坚守

目录 一.AIGC 带来的文学变革 1.创作方式的改变 2.阅读体验的升级 3.文学市场的重塑 二.文学在 AIGC 时代的坚守 1.人类情感的表达 2.文学的艺术性 3.文学的社会责任 三.AIGC 与人类作家的共生之路 1.相互学习 2.合作创作 3.共同发展 另&#xff1a; 总结 随着人…...

InfluxDB 集成 Grafana

将InfluxDB集成到Grafana进行详细配置通常包括以下几个步骤&#xff1a;安装与配置InfluxDB、安装与配置Grafana、在Grafana中添加InfluxDB数据源以及创建和配置仪表板。以下是一个详细的配置指南&#xff1a; 一、安装与配置InfluxDB 下载与安装&#xff1a; 从InfluxDB的官…...

笔记本电脑usb接口没反应怎么办?原因及解决方法

笔记本电脑的USB接口是我们日常使用中非常频繁的一个功能&#xff0c;无论是数据传输、充电还是外接设备&#xff0c;都离不开它。然而&#xff0c;当USB接口突然没有反应时&#xff0c;这无疑会给我们的工作和学习带来不小的困扰。下面&#xff0c;我们就来探讨一下笔记本USB接…...

【开源】A060-基于Spring Boot的游戏交易系统的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看项目链接获取⬇️&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600个选题ex…...

static关键字在嵌入式C编程中的应用

目录 一、控制变量的存储周期和可见性 1.1. 局部静态变量 1.2. 全局静态变量 二、控制函数的可见性 2.1. 静态函数 2.2. 代码示例&#xff08;假设有两个文件&#xff1a;file1.c和file2.c&#xff09; 三、应用场景 3.1. 存储常用数据 3.2. 实现内部辅助函数 四、注…...

集合框架(1)

集合框架&#xff08;1&#xff09; 1、数组的特点与弊端 &#xff08;1&#xff09;特点&#xff1a; 数组初始化以后&#xff0c;长度就确定了。数组中的添加的元素是依次紧密排列的&#xff0c;有序的&#xff0c;可以重复的。数组声明的类型&#xff0c;就决定了进行元素初…...

Java 基础之泛型:类型安全的保障与灵活运用

在 Java 编程的世界里&#xff0c;泛型是一个至关重要且非常实用的特性。它在 Java 5 中被引入&#xff0c;从根本上改变了我们处理数据类型的方式&#xff0c;提供了更强的类型安全保障&#xff0c;同时也增加了代码的复用性和可读性。 一、什么是泛型 泛型&#xff08;Gener…...

开发者如何使用GCC提升开发效率Opencv操作

看此篇前请先阅读 https://blog.csdn.net/qq_20330595/article/details/144134160?spm=1001.2014.3001.5502 https://blog.csdn.net/qq_20330595/article/details/144134160?spm=1001.2014.3001.5502 https://blog.csdn.net/qq_20330595/article/details/144216351?spm=1001…...

矩阵加法        ‌‍‎‏

矩阵加法 C语言代码C 语言代码Java语言代码Python语言代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 输入两个n行m列的矩阵A和B&#xff0c;输出它们的和AB。 输入 第一行包含两个整数n和m&#xff0c;表示矩阵的行数和列数。1 <…...

yarn : 无法加载文件 E:\node\node_global\yarn.ps1,因为在此系统上禁止运行脚本

先确保安装了yarn —— npm install -g yarn 终端输入set-ExecutionPolicy RemoteSigned 若要在本地计算机上运行您编写的未签名脚本和来自其他用户的签名脚本&#xff0c;请使用以下命令将计算机上的执行策略更改为RemoteSigned 再去使用yarn okk~...

详解C++类与对象(四)

文章目录 1.类型转换1.1 前言1.2 类型转换的性质 2.static成员2.1 前言2.2 static的基本概念 3.友元4.内部类5.匿名对象 1.类型转换 1.1 前言 在C中&#xff0c;由于程序员可以自己显示定义一个新的类。这样就会出现一个问题&#xff1a;程序员自己显示定义的类类型与编译器中…...

Pandas处理和分析嵌套JSON数据:从字符串到结构化DataFrame

在数据分析领域&#xff0c;我们经常遇到需要从非结构化数据中提取有用信息的场景。特别是当数据以JSON字符串的形式出现时&#xff0c;如何有效地将其转换为结构化的表格形式&#xff0c;以便进行进一步的分析和处理&#xff0c;成为了一个常见的挑战。本文将通过一个具体的例…...

【强化学习入门笔记】1.5 贝尔曼最优公式

本系列为学习赵世钰老师的《强化学习的数学原理》所作的学习笔记. 课程视频网址&#xff1a;https://space.bilibili.com/2044042934 1.5.1 定义 1.5.1.1 Contraction mapping theorem (收缩映射定理) fixed point(不动点) 如果 x ∗ x^* x∗满足下式, x ∗ x^* x∗称之为…...

编码问题技术探讨:IDE全局GBK与项目UTF-8引发的中文乱码

在软件开发过程中&#xff0c;编码问题一直是开发者们需要面对和解决的难题之一。尤其是在使用IDE&#xff08;集成开发环境&#xff09;时&#xff0c;如果全局编码设置与项目编码设置不一致&#xff0c;往往会导致中文乱码的问题。本文将深入探讨这一问题的背景、示例以及解决…...

SpringBoot两天

SpringBoot讲义 什么是SpringBoot&#xff1f; Spring Boot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。通过这种方式&#xf…...

自动化立体仓库项目任务调度系统中任务流程可视化实现

在运维自动化平台中,任务系统无疑是最核心的组成部分之一。它承担着所有打包编译、项目上线、日常维护等运维任务的执行。通过任务系统,我们能够灵活地构建满足不同需求的自定义任务流。早期的任务流后端采用了类似列表的存储结构,根据任务流内子任务的排序依次执行,尽管通…...

计算机毕业设计hadoop+spark民宿推荐系统 民宿数据分析可视化大屏 民宿爬虫 民宿大数据 知识图谱 机器学习 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

Java中OGNL表达式语言的使用

文章目录 OGNL 介绍OGNL 使用场景- ognl- 主要功能- 注意事项- Ognl类的主要方法- 设置值- 获取值- 使用示例 - MybatisJava原生表达式的使用 - Fastjson- JSONPath类的主要方法- 主要功能- JSONPath的优势- 使用示例 Spring不选择OGNL的原因 OGNL 介绍 OGNL&#xff08;Objec…...

[HCTF 2018]WarmUp-滑稽

启动场景打开链接&#xff0c;出现一下图片 F12查看代码出现一个注释&#xff0c;应该在这个文件中&#xff0c; 进入到该页面&#xff0c;出现一段代码 <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$whitelist ["sourc…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...