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

五子棋AI设计——从门外到门内不得不说的事儿1

2012-06-08 09:48 281 查看
这学期选了人工智能原理,上课的时候完全没搞懂老师要讲什么,所以听课听得云里雾里的,幸好有几个小实验,可以帮助理解人工智能的精髓。

第一个实验就是基于带alpha-beta剪枝的MinMax搜索的五子棋AI设计。好久没有写过MFC界面了,所以在pudn上down了几个例程,测试了一下,选了两个比较规范的工程作为开发的基础。

第一天:Naive AI——一个称不上AI的AI

比对着选好的工程进行复制,在复制的过程中删去一些暂时用不到的功能,就搞出了如下界面。



有了棋盘,让我们开始下棋吧。可是这是我还对五子棋的规则一知半解,是个门外汉。只好采用投石问路的方法,先来个简单的吧,随机生成合法落子位置。

首先将棋盘定义为一个整形的二维数组points[16][16],0表示空,1表示黑子,2表示白子。为什么是16,只是觉得用1-15比用0-14直观一些,其实模仿程序是这么定义的。

那么,什么样的位置是合法的呢?就是棋盘上满足points[i][j] == 0的(i,j)。这样随机生成1-15之间的任意整数x = rand()%15 + 1; y =rand()%15 + 1;建议在两个语句中间加若干空循环,避免x和y一样,提高“随机性”,虽然这个随机性并不怎么样吧。

这样,一个称不上AI的AI诞生了,我们就叫他Naive吧。

观赏Naive下棋是一种享受,因为他的表现比我还差,我可以很轻易的在五步之内秒杀他。

在解决了有无问题后,应该着眼于提高AI的水平,使其成为真的AI。

如何提高,路在何方?且听下回分解。

--------------------分割线--------------------

“AI”代码如下,

void CWuZiQi::Naive( const int points[16][16], bool first, int oldp[16][16], int newp[16][16], int *nx, int *ny )
{
int x, y;
int k = 0;
// current state quick save
for ( int i = 1; i <= 15; i++ )
for ( int j = 1; j <= 15; j++ )
{
oldp[i][j] = points[i][j];
newp[i][j] = points[i][j];
}
// place a chess on board
do
{
for ( int j = 0; j < 1000; j++ )
for ( int k = 0; k < j; k++ )
;
x = rand() % 15 + 1;
for ( int j = 0; j < 1000; j++ )
for ( int k = 0; k < j; k++ )
;
y = rand() % 15 + 1;
k++;
}while ( oldp[x][y] != 0 || k > 20 );
if ( k >= 20 )
{
*nx = -1; *ny = -1;
return;
}
else
{
*nx = x; *ny = y;
}
if ( first )
{
newp[x][y] = 1;
}
else
{
newp[x][y] = 2;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: