五子棋AI设计

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               
 

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

分类: 人工智能 AI 五子棋 Naive   278人阅读  评论(0)  收藏  举报

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

第一个实验就是基于带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”代码如下,

[cpp]  view plain copy
  1. void CWuZiQi::Naive( const int points[16][16], bool first, int oldp[16][16], int newp[16][16], int *nx, int *ny )  
  2. {  
  3.     int x, y;  
  4.     int k = 0;  
  5.     // current state quick save  
  6.     for ( int i = 1; i <= 15; i++ )  
  7.         for ( int j = 1; j <= 15; j++ )  
  8.         {  
  9.             oldp[i][j] = points[i][j];  
  10.             newp[i][j] = points[i][j];  
  11.         }  
  12.     // place a chess on board  
  13.     do  
  14.     {  
  15.         for ( int j = 0; j < 1000; j++ )  
  16.             for ( int k = 0; k < j; k++ )  
  17.                 ;  
  18.         x = rand() % 15 + 1;  
  19.         for ( int j = 0; j < 1000; j++ )  
  20.             for ( int k = 0; k < j; k++ )  
  21.                 ;  
  22.         y = rand() % 15 + 1;  
  23.         k++;  
  24.     }while ( oldp[x][y] != 0 || k > 20 );  
  25.     if ( k >= 20 )  
  26.     {  
  27.         *nx = -1; *ny = -1;  
  28.         return;  
  29.     }  
  30.     else  
  31.     {  
  32.         *nx = x; *ny = y;  
  33.     }  
  34.     if ( first )  
  35.     {  
  36.         newp[x][y] = 1;  
  37.     }  
  38.     else  
  39.     {  
  40.         newp[x][y] = 2;  
  41.     }  
  42. }  

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

分类: AI wuziq 五子棋 人工智能   235人阅读  评论(0)  收藏  举报

第二天:防守,堵堵堵

为了提高对五子棋游戏的感性认识,我又在网上找了几个写的很好的五子棋游戏,与电脑进行了若干次对弈。作为一个门外汉,防守总是最好的选择。那么在什么条件下防守,在什么位置防守,这些位置如何确定……在这一系列的问题的驱动下,我开始学习模拟对象的AI部分。

首先我选择了总是防守,所以在这一天,我的第一个问题解决了。那么在什么位置放手呢?

之前定义了棋盘用points[i][j]表示,那么最直观的想法是看看棋盘上的棋子,可是棋盘既有白子又有黑子,还有空位。怎么判断呢?好吧,从AI的角度出发,他现在要做的事情是:在当前棋盘状态选择一个合法位置——空位,然后在该位置出招。那么既然是在空位置出招,那么是不是评估棋盘上的空位置来指导出招就可以了?

作为门外汉我现在能够想到的就这么多了,好吧先不管3721,走起。

如何评估棋盘上的空位?

为了大家看起来方便,我先展示一个7*7的棋盘,示意一下。人先执黑,电脑后手执白,现在轮到电脑出招。棋盘如下

  1234567

10000000

20000000

30021000

40001000

50000000

60000000

70000000

那么有子周围的空位置中,(2,4)向下看有一个2连,在(5,4)向上看有一个2连,在其他位置看到的都是1连。好了,从防守的角度出发,现在最危险的位置是(2,4)和(5,4)。通过这次观察,我们可以得到一种评估方法,那就是枚举棋盘上的每个空位,然后统计其8个方向上,相同颜色的棋子连成一线的棋子的个数。

为什么是8个方向?

因为空位填上子后,可能将以前的阴线(可能连成一线的线)变成阳线(已经连成一线的线)。因此,我们要在空位置上向八个方向都看看,看看这个位置能够连成多少条阳线,如果连成的阳线越多,阳线中棋子的数目越多,那么这个空位的威胁就越大。

定义int qiju[16][16][8][2]表示棋盘某个位置某个方向某种颜色的棋子连成一线的棋子的个数

定义int a1[16][16], a2[16][16]表示棋盘上某空位的评分。

如何评分呢?我们先考虑一线式的吧,就是横、竖、左斜、右斜这四种。定义int t1 = qiju[i][j][k][0]+qiju[i][j][k+4][0]表示,涵盖了空位在某一方向上一侧或两侧连成一线的棋子数目。

if t1 >= 4 a1[i][j] += 10000000;

if t1 == 3 a1[i][j] += 100000;

if t1 == 2 a1[i][j] += 1000;

if t1 == 1 a1[i][j] += 10;

同理可以计算a2。

好了在a1和a2中找到最大值的位置,如果人执黑,那么AI就用a1的最大值的位置作为落子的位置,如果AI执黑,那么AI就用a2的最大值的位置作为落子的位置。AI就可以成功的封堵住对自己威胁最大的位置,完成防守。


可是AI只会防守怎么行,好吧,那么我们只能重新考虑第一个问题将AI定义为攻守兼备,在什么条件下进攻呢,欲知后事如何,且听下回分解。

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

AI的代码如下,

[cpp]  view plain copy
  1. void CWuZiQi::AI_1( const int points[16][16], bool first, int oldp[16][16], int newp[16][16], int *nx, int *ny )  
  2. {  
  3.     int i, j;  
  4.     
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值