基于MFC的五子棋应用(四)实践
在第一部分已经提前在构造函数中写好了相应的内容,但是人有需要添加的内容,所以我们在(一)的基础上添加:
//AI
//保存计算机落子时白棋位置
CPoint vspoint;
int vscomputer; //vscomputer=1 为人机对战 2为人人
//用作判断落子位置
CPoint bpointcan4,//这个位置空,它旁边有四个黑棋
wpointcan4,//这个位置空,它旁边有四个白棋
bpointcan3,//这个位置空,它的旁边有三个黑棋
wpointcan3,//这个位置空,它的旁边有三个白棋
bpointcan2,//这个位置空,它的旁边有两个黑棋
wpointcan2,//这个位置空,它的旁边有两个白棋
bpointcan1;//不是以上情况,这个位置空
//在得到最大值和方向上寻找落棋点
//其中i、j表示搜索起点,n表示方向
void searchcandown1(int i,int j,int n);
void searchcandown2(int i,int j,int n);
void searchcandown3(int i,int j,int n);
void searchcandown4(int i,int j,int n);
//计算最大值及方向
CPoint maxnum(int a,int b,int c,int d);
//最好落棋点
void bestputdown(int i,int j);
//计算机下棋
void computerdown();
//在位置point放下棋子
void putdown(CPoint point);
由于我们添加了菜单项 VS 人 和 VS AI
需要在WuZiQiView.cpp中添加函数
//VS 人
void CWuZiQiView::OnPlayer()
{
vscomputer=2;
OnStart();
}
//VS 机器
void CWuZiQiView::OnComputer()
{
vscomputer=1;
OnStart();
}
接下来是将其中一方变为计算机落子,即在OnButtonUp()函数中添加语句:
//人机对战
if(vscomputer==1)
{
if(point.x>30&&point.x<=410&&point.y>30&&point.y<410)
{
int px=(point.x-30)/20;
int py=(point.y-30)/20;
//是否已经有棋子
if(colorwhite&&wzq[px][py]==0)
{
//记录当前棋子坐标
wprex=px;
wprey=py;
Dc.SelectObject(m_bmwhite);
pDC->BitBlt(px*20+32,py*20+32,160,160,&Dc,0,0,SRCCOPY);
//表示存在白棋
wzq[px][py]=1;
//检查是否结束
over(point);
//换黑棋下
colorwhite=false;
//保存白棋位置
vspoint=point;
//计算机落子
computerdown();
}
}
}
计算机是怎样下棋?这就是定位的问题了。即搜索棋盘,找出一个最佳点,放下黑棋。我们实现的方法是:全盘搜索,并把搜索到的位置,保存在变量。由于有多种情况,我们定义变量如下:
CPoint bpointcan4, //这个位置空,它旁边有四个黑棋
wpointcan4, //这个位置空,它旁边有四个白棋
bpointcan3, //这个位置空,它的旁边有三个黑棋
wpointcan3, //这个位置空,它的旁边有三个白棋
bpointcan2, //这个位置空,它的旁边有两个黑棋
wpointcan2, //这个位置空,它的旁边有两个白棋
bpointcan1; //不是以上情况,这个位置空
在搜索前,先将所有值赋为(-1,-1),然后进行搜索,并保存对应情况下的变量值,如果操作时已经对变量进行过赋值,那么就用新值代替旧值。为了避免每次搜索棋盘都从左上角开始,我们只保存最后的一个值。
全盘搜索完之后,由于上面的变量中至少有一个已经被赋值,即不是(-1,-1),我们可以采用多数优先的方法,让已经有多个同色棋子的位置先下棋。其原理是,如果已经有四个黑