您的位置:首页 > 大数据 > 人工智能

怎么编一个五子棋游戏?(带ai)

2010-06-01 23:17 330 查看
源代码下载

本教程适合初学者,用到的工具VC++ 6.0

五子棋游戏算法比较简单,实现起来比较容易,适合初学者练习。

我这个五子棋游戏是自己花了2天的时间完成的,当时刚学mfc,想练一下手就做了这个游戏。
棋盘和棋子可以用GDI来实现,棋盘用GDI划线,基本上就是LineTo(x,y),MoveTo(x,y),一个棋盘就出来了。具体代码如下
在OnPaint()函数的else内加入如下代码

CPaintDC dc(this);
dc.SelectStockObject(BLACK_PEN);
int i,j;
for(i=60;i!=420;i=i+40)
{
dc.MoveTo(i,60);
dc.LineTo(i,380);
}
for(j=60;j!=420;j=j+40)
{
dc.MoveTo(60,j);
dc.LineTo(380,j);
}
一个9×9的棋盘就画好了。至于如何画棋子,我思考了很长时间,贴图太麻烦,就用GDI来画圆,然后填充上不同的颜色,黑子、白子也就实现了。这里的棋子不应该是一个独立的量,它有自己的区域,应该能判断鼠标是不是点击到了这个区域,当点击这个区域的时候是否应该显示,应该显示什么颜色的旗子…… 把这么多东西集合在一起,应该定义一个类,于是CQuyu这个类就出现了。
CQuyu有四个变量如下:
int
flag;
CRect rect;
int y;
int x;
x,y表示这个区域的中心,rect为以x,y为中心的边长为30的矩形,flag用来表示该对象的状态(0:空白 1:黑子 2:白字)。
然后又定义了5个方法
bool isWhite();//如果为白子,返回true
CRect getRect();//获得该对象对应的CRect
bool isBlack();//如果为黑子,返回true
bool isEmpty();//如果为空,返回true
bool isOn(CPoint point);//如果该点出在该区域返回true,用来判断鼠标单击对应的区域

在view类中定义了一个vector容器,(需要包含#include <vector>)
vector<CQuyu>
qy;
在OnInitDialog()内对qy进行初始化
int i,j;
CQuyu q;
for(i=60;i!=420;i=i+40)
{
for(j=60;j!=420;j=j+40)
{
q.x=i;
q.y=j;
qy.push_back(q);
}
}
当鼠标单击的时候,判断单击的是哪一个区域,如果该区域为空则修改区域状态
void CWuziqidlgDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
int i;
for(i=0;i!=qy.size();i++)
if(qy[i].isOn(point)&&!over&&qy[i].isEmpty())
{
qy[i].flag=1;
ison=1;
break;
}
Invalidate();//引发重绘
}
在OnLButtonUp()中实现ai,电脑走棋
void
CWuziqidlgDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here
and/or call default
//flag 1:black 2:white
//color 1:white 2:black
int i,temp1,temp2,max1,max2;
max1=0;
max2=0;
temp1=0;
temp2=0;
for(i=0;i!=qy.size();i++)
{
if(qy[i].isEmpty())
{
qy[i].flag=2;
if(getScore(1)>max1)
{
temp1=getScore(1);
max1=temp1;
temp1=i;
}
qy[i].flag=1;
if(getScore(2)>max2)
{
temp2=getScore(2);
max2=temp2;
temp2=i;
}
qy[i].flag=0;
}
}
if(ison==1&&!over)
{
if(max1>=max2)
qy[temp1].flag=2;
else
qy[temp2].flag=2;
}
ison=0;

if(!isWin())
Invalidate();

CDialog::OnLButtonUp(nFlags, point);
}
OnPaint()函数中实现绘制,每次先把棋盘画好,然后遍历各区域,如果不为空就绘制相应的棋子。还要判断是否有一方获胜,如果有就结束游戏。(具体代码见源程序)
这个程序主关键的是算分,对不同的走法进行算法,得分最高的为要真正要走的。这也就是ai,这一点我参考了网上的五子棋经典算法(自己做了一些修改):

判断是否能成5, 如果能给予10500分
判断是否能成活4,如果能给予10400分
判断是否能成双死4,如果能给予10300分
判断是否能成死4活3,如果能给予10000分
判断是否已成双活3,如果能给予5000分,如果是人方的话给予-5000 分;
判断是否成死3活3,如果是机器方的话给予1000分
判断是否能成死4,如果能给予500分
判断是否能成单活3,如果能给予200分
判断是否已成双活2,如果能给予100分
判断是否能成死3,如果能给予50分
判断是否能成双活2,如果能给予10分
判断是否能成活2,如果能给予5分
判断是否能成死2,如果能给予3分
否则给0分

下五子棋不光要进攻,还要防守,所以要先对假设那些空的格子下自己的棋子能得多少分,得出一个最高分,然后假设这些格子放上对方的棋子,得出一个最高分,如果进攻的最高分大于等于防守的最高分,则进攻,否则先进行防守。还有一些具体的细节没有写出,如怎么判断活4,活5之类的。这些问题比较简单,留给读者去思考。

我的源程序实现了上述所有功能,有疑问可以去看源代码。也可以直接和我联系,我的邮箱jianger2005@163.com
源代码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: