正文

简单五子棋人机对弈(19×19)二2006-06-29 10:43:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/bakers/16260.html

分享到:

上一页 8.void robot() 也是人机对弈五子棋最核心的部分,其中包括了评价机制,估值,搜索部分 搜索空格的八个方向,如:                         1       0      2   7      空格    3   6       5      4   最后将权值最大的几个点的位置信息保存于xposition[]与yposition[]数组中,如果极值权重相同,使用随机函数选择其中一点下棋。 void robot(void) {     int x, y, X, Y, i, j;     int *p, *mp;  //用于指向特定数组     long int xposition[38], yposition[38];  //存储相同得权值     long int max;  //当前最大权值 //将空格信息填入特定数组,用于bot评分并下子,将 360 度分成 8 个方向 //即同一个空格可能五子相连的八个方向,具体看 readme 文件     for( X = 0; X < 19; X++)   //0方向检查         for( Y = 18; Y > 4; Y--)             if( map[Y][X].player == blank)                 for( i = 0, x = X, y = Y; y > Y - 5; i++, y--)                     map[Y][X].value[0][i] = map[y-1][x].player;     for( X = 0; X < 19; X++)   //4 方向检查         for( Y = 0; Y < 10; Y++)             if( map[Y][X].player == blank)                 for( i = 0, x = X, y = Y; y < Y + 5; i++, y++)                     map[Y][X].value[4][i] = map[y+1][x].player; // '/' 检查, 1 方向检查开始     for( i = 4; i < 19; i++)    //'/'检查, 1 方向检查,左上部分         for( X = 0, Y = i; Y > 3; X++, Y--)  //检查一斜行             if( map[Y][X].player == blank)                 for( j = 0, x = X, y = Y; (y > Y - 5) || (y > 0); j++, x++, y--)                     map[Y][X].value[1][j] = map[y-1][x+1].player;     for( i = 1; i < 11; i++)         for( X = i, Y = 18; X < 11; X++, Y--)// 1 方向检查,右下部分             if( map[Y][X].player == blank)                 for( j = 0, x = X, y = Y; (x < X + 5) || (x < 18); j++, x++, y--)                     map[Y][X].value[1][j] = map[y-1][x+1].player;     for( i = 18; i > 3; i--)//'/'检查, 5 方向检查,左上部分         for( X = i, Y = 0; X > 3; X--, Y++)             if( map[Y][X].player == blank)                 for( j = 0, x = X, y = Y; (x > X - 5) || (x > 0); j++, x--, y++)                     map[Y][X].value[5][j] = map[y+1][x-1].player;     for( i = 1; i < 11; i++)// 5 方向检查,右下部分         for( X = 18, Y = i; Y < 11; X--, Y++)             if( map[Y][X].player == blank)                 for( j = 0, x = X, y = Y; (y < Y + 5) || (y < 14); j++, x--, y++)                     map[Y][X].value[5][j] = map[y+1][x-1].player; // '/' 检查结束, 5 方向检查结束     for( Y = 0; Y < 19; Y++)// 2 方向检查,从左到右         for( X = 0; X < 10; X++)             if( map[Y][X].player == blank)                 for( j = 0, x = X, y = Y; x < X + 5; j++, x++)                     map[Y][X].value[2][j] = map[y][x+1].player;     for( Y = 0; Y < 19; Y++)//6 方向检查,从右到左         for( X = 18; X > 4; X--)             if( map[Y][X].player == blank)                 for( j = 0, x = X, y = Y; x > X - 5; j++, x--)                     map[Y][X].value[6][j] = map[y][x-1].player; // '\' 检查开始, 3 方向检查开始     for( i = 0; i < 11; i++)// 3 方向检查,右上部分         for( X = i, Y = 0; X < 11; X++, Y++)             if( map[Y][X].player == blank)                 for( j = 0, x = X, y = Y; (x < X + 5) || (x < 18); j++, x++, y++)                     map[Y][X].value[3][j] = map[y+1][x+1].player;     for( i = 1; i < 11; i++)// 3 方向检查,左下部分         for( X = 0, Y = i; Y < 11; X++, Y++)             if( map[Y][X].player == blank)                 for( j = 0, x = X, y = Y; (y < Y + 5) || (y < 18); j++, x++, y++)                     map[Y][X].value[3][j] = map[y+1][x+1].player;     for( i = 18; i > 3; i--)// 7 方向检查,右上部分         for( X = 18, Y = i; Y > 3; X--, Y--)             if( map[Y][X].player == blank)                 for( j = 0, x = X, y = Y; (y > Y - 5) || (y > 0); j++, x--, y--)                     map[Y][X].value[7][j] = map[y-1][x-1].player;     for( i = 17; i > 3; i--)// 7 方向检查,左下部分         for( X = i, Y = 18; X > 3; X--, Y--)             if( map[Y][X].player == blank)                 for( j = 0, x = X, y = Y; (x > X - 5) || (x > 0); j++, x--, y--)                     map[Y][X].value[7][j] = map[y-1][x-1].player; //'\' 检查结束, 7 方向检查结束, bot 检查棋盘空格结束 //进入bot判断,对棋盘上每一个空格进行评分     for( y = 0; y < 19; y++)         for( x = 0; x < 19; x++)             if( map[y][x].player == blank)                 for( i = 0; i < 8; i++)                 { // for控制对一个空格的8个方向评分         p = &map[y][x].value[i][0];//mp 与 p 刚好组成 空格 的两头         if( i < 4)mp = &map[y][x].value[i+4][0];         else  mp = &map[y][x].value[i-4][0]; //b 为bot, m 为man, o 为空格, x为评分点 //己方已经可以赢,或是对方可能有四子相连的评分为 100,000,000 一亿 的情况         if( *p == bot && *(p+1) == bot && *(p+2) == bot && *(p+3) == bot )             map[y][x].score += 100000000;                             if( *p == man && *(p+1) == man && *(p+2) == man && *(p+3) == man )             map[y][x].score += 100000000;                             if( *p == bot && *(p+1) == bot && *(p+2) == bot && *mp == bot )             map[y][x].score += 100000000;                           if( *p == man && *(p+1) == man && *(p+2) == man && *mp == man )             map[y][x].score += 100000000;                            if( *p == bot && *(p+1) == bot && *mp == bot &&*(mp+1) == bot )             map[y][x].score += 100000000;                              if( *p == man && *(p+1) == man && *mp == man && *(mp+1) == man )             map[y][x].score += 100000000;                   //活四评分为 10,000,000 一千万 的情况         if( *p == bot && *(p+1) == bot && *(p+2) == bot && *(p+3) == blank && *mp == blank )             map[y][x].score += 10000000;                            if( *p == man && *(p+1) == man && *(p+2) == man && *(p+3) == blank )             map[y][x].score += 10000000;                             if( *p == bot && *(p+1) == bot && *(p+2) == blank && *mp == man && *(mp+1) == blank )             map[y][x].score += 10000000;                            if( *p == man && *(p+1) == man && *(p+2) == blank && *mp == man && *(mp+1) == blank )             map[y][x].score += 10000000;                             if( *p == blank && *(p+1) == bot && *(p+2) == bot && *(p+3) == bot && *(p+4) == blank && *mp == blank )             map[y][x].score += 10000000;                    //冲四评分为 8,000,000 八百万 的情况         if( *p == bot && *(p+1) == bot && *(p+2) == bot && *(p+3) == man && *mp == blank )             map[y][x].score += 8000000;                              if( *p == bot && *(p+1) == bot && *(p+2) == man && *mp == bot && *(mp+1) == blank )             map[y][x].score += 8000000;                             if( *p == bot && *(p+1) == man && *mp == bot && *(mp+1) == bot && *(mp+2) == bot && *(mp+3) == blank )             map[y][x].score += 8000000;                             if( *mp == blank && *p == blank && *(p+1) == bot && *(p+2) == bot && *(p+3) == bot && *(p+4) == man )             map[y][x].score += 8000000;                             if( *mp == bot && *(mp+1) == blank && *p == blank && *(p+1) == bot && *(p+2) == bot && *(p+3) == man )             map[y][x].score += 8000000;                     //防对方冲四评分为 6,000,000 的情况         if( *p == man && *(p+1) == man && *(p+2) == man && *(p+3) == bot && *mp == blank )             map[y][x].score += 6000000;                            if( *p == man && *(p+1) == man && *(p+2) == bot && *mp == man && *(mp+1) == blank )             map[y][x].score += 6000000;                      //活三评分为 4,000,000 四百万 的情况         if( *p == bot && *(p+1) == bot && *(p+2) == blank && *mp == blank )             map[y][x].score += 4000000;                               if( *p == man && *(p+1) == man && *(p+2) == blank && *mp == blank )             map[y][x].score += 4000000;                              if( *p == man && *(p+1) == blank && *(p+2) == man && *(p+3) == blank && *mp == blank )             map[y][x].score += 4000000;                              if( *p == bot && *(p+1) == blank && *mp == bot && *(mp+1) == blank )             map[y][x].score += 4000000;                               if( *p == man && *(p+1) == blank && *mp == bot && *(mp+1) == blank )             map[y][x].score += 4000000;                      //死三评分为 1,500,000 一百五十万 的情况,进攻为主         if( *p == bot && *(p+1) == bot && *(p+2) == man && *mp == blank )             map[y][x].score += 1500000;                              if( *p == bot && *(p+1) == man && *mp == bot && *(mp+1) == blank )             map[y][x].score += 1500000;                             if( *mp == man && *p == bot && *(p+1) == bot && *(p+2) == blank )             map[y][x].score += 1500000;                              if( *mp == blank && *p == blank && *(p+1) == bot && *(p+2) == bot && *(p+3) == man )             map[y][x].score += 1500000;                     //活二评分为 100,000 十万 的情况         if( *p == bot && *(p+1) == blank && *mp == blank )             map[y][x].score += 100000;                                  if( *p == blank && *(p+1) == bot && *(p+2) == blank && *mp == blank )             map[y][x].score += 100000;                       //活二评分为 70,000 七万 的情况         if( *p == man && *(p+1) == blank && *mp == blank )             map[y][x].score += 70000;                                 if( *p == blank && *(p+1) == man && *(p+2) == blank && *mp == blank )             map[y][x].score += 70000;                        //冲二评分为 30,000 三万 的情况         if( *mp == blank && *p == bot && *(p+1) == man )             map[y][x].score += 30000;                               if( *mp == blank && *p == blank && *(p+1) == bot && *(p+2) == man)             map[y][x].score += 30000;                        //冲二评分为 10,000 一万 的情况,防守为主         if( *mp == blank && *p == man && *(p+1) == bot )             map[y][x].score += 10000;                          //开局情况,并限定下子范围         if( step == blank){             do{                 x = random(19);                 y = random(19);                 if( map[y][x].player != blank)x = blank;             }while( x - 5 < 0 || x - 10 > 0 || y - 5 < 0 || y - 10 > 0 );             map[y][x].score += 5000;             step += 1;         }     }     max = blank;   //权值评分机制初始化     for( y = 0; y < 19; y++)  //搜寻权值最大点         for( x = 0; x < 19; x++)             if( map[y][x].player == blank){                 if( map[y][x].score > max)                 {                     max = map[y][x].score;                     for( i = 0; i < 38; i++) {                         xposition[i] = blank;                         yposition[i] = blank;                     }                     xposition[0] = x;                     yposition[0] = y;                 }                 else if( map[y][x].score == max)                 {                     i+=1;                     xposition[i] = x;                     xposition[i] = y;                 }             }     if( xposition[2] == blank)//选择最大权值点做下子点     {         map[ yposition[0] ][ xposition[0] ].player = bot;         mark( xposition[0], yposition[0]);     }     else  //在最大权值相等的位置中随机选择下子点*/     {         i = random(10);         x = xposition[i];         y = yposition[i];         map[y][x].player = bot;         mark( x, y);     } } 【相关知识】篇幅所限制,活三,冲四等棋型在此就不赘述. 【心得体会】通过本次实践,初步掌握了五子棋“人机博弈”的基本算法,由于开发较为智能的程序,算法复杂度较高,固在此只进行了一层搜索。采用博弈树的算法,搜索最佳位置后,然后剪枝,选择最优。实际上按照王小春的说法,要进行深度为4搜索,计算机可能要思考15秒左右,算法时间性能较差,况且时间较仓促,没有进行更深层次的思考,期间遇到不少挫折,程序规模较以前相比庞大了不少,参照了不少源码(15×15)。   人工智能算法博大精深,日前在网上看到一种所谓“稀疏矩阵”的算法,采用“易语言”编译,时间性能尚可。有机会向作者请教请教。 【参考文献及相关资料】   《PC游戏编程(人机博弈)》 ――――  王小春 《算法分析与设计技术》    ―――― 马绍汉                                    CSDN专栏                                     Programfan.Com论坛                                                             baker                                                                  6/28

阅读(5260) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册