游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2050|回复: 1

对于极大极小算法。。。实现失败。。。求解

[复制链接]

7

主题

12

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2009-12-23 04:18:00 | 显示全部楼层 |阅读模式
先上菜:

  1. Move MinMax_AI::FindBestStep()
  2. {
  3.     int maxVal = -99999999;
  4.     Move bestMove;
  5.     int tmp=0;
  6.     char* curStep;
  7.     int cur;
  8.     actionInfo info;
  9.     for(int j=0; j<8 ;j++)
  10.     {
  11.         for(int i=0; i<8 ;i++)
  12.         {
  13.             if((_board->GetBoardInfo(i,j)^AI_PLAYER) < 0x10)//只控制是自己的棋子就够了。。。
  14.             {
  15.                 cur = 0;
  16.                 info = _board->GetPieceBonusPoints(i,j);//获得棋盘上这个点的所有移动可能
  17.                 curStep = (char*)&info.moveList;//moveList是short数组,前面8个字是x,后8个字是y
  18.                     while(info.moveList[cur] != 0)//对所有可以移动的可能
  19.                     {
  20.                         _board->MovePieceWithOutCheck(i,j,*curStep,*(curStep+1));//直接无需检查就移动,因为这次移动是通过检查后得到的。
  21.                         tmp = Min(_depth-1);//轮到对方走了。。。
  22.                         if(tmp > maxVal)
  23.                         {
  24.                             maxVal = tmp;
  25.                             bestMove.srcPt = MyPOINT(i,j);
  26.                             bestMove.dstPt = MyPOINT(*curStep,*(curStep+1));
  27.                         }
  28.                         _board->MovePieceWithOutCheck(*curStep,*(curStep+1),i,j);//然后把棋子弄回来。
  29.                         curStep+=2;//继续下个移动
  30.                         cur++;
  31.                     }
  32.             }
  33.         }
  34.     }
  35.     return bestMove;
  36. }

  37. int MinMax_AI::Min(int dp)
  38. {
  39.     if(dp==0)
  40.     {
  41.         //返回棋盘估价,2是代表 AI分-人类分,eval是一个类的实现
  42.         //把棋盘传过去
  43.         return _eval.GetVal(_board,2);
  44.     }

  45.     int min = 99999999;
  46.     int tmp=0;
  47.     char* curStep;
  48.     int cur;
  49.     actionInfo info;

  50.     for(int j=0;j<8;j++)
  51.     {
  52.         for(int i=0; i<8; i++)
  53.         {
  54.             if((_board->GetBoardInfo(i,j)^HUMAN_PLAYER) < 0x10)//只用模拟人类防。。。
  55.             {
  56.                 cur = 0;
  57.                 info = _board->GetPieceBonusPoints(i,j);
  58.                 curStep = (char*)&info.moveList;
  59.                 while(info.moveList[cur] != 0)
  60.                 {
  61.                     _board->MovePieceWithOutCheck(i,j,*curStep,*(curStep+1));
  62.                     tmp = Max(dp-1);
  63.                     if(tmp < min)
  64.                     {
  65.                         min = tmp;
  66.                     }
  67.                     _board->MovePieceWithOutCheck(*curStep,*(curStep+1),i,j);
  68.                     curStep+=2;
  69.                     cur++;
  70.                 }
  71.             }
  72.         }
  73.     }
  74.     return min;
  75. }

  76. int MinMax_AI::Max(int dp)
  77. {
  78.     if(dp == 0)
  79.         return _eval.GetVal(_board,2);

  80.     int max = -99999999;
  81.     int tmp=0;
  82.     char* curStep;
  83.     int cur;
  84.     actionInfo info;

  85.     for(int j=0; j<8 ;j++)
  86.     {
  87.         for(int i=0; i<8; i++)
  88.         {
  89.             if((_board->GetBoardInfo(i,j)^AI_PLAYER) < 0x10)
  90.             {
  91.                 cur = 0;
  92.                 info = _board->GetPieceBonusPoints(i,j);
  93.                 curStep = (char*)&info.moveList;
  94.                 while(info.moveList[cur] != 0)
  95.                 {
  96.                     _board->MovePieceWithOutCheck(i,j,*curStep,*(curStep+1));
  97.                     tmp = Min(dp-1);
  98.                     if(tmp > max)
  99.                     {
  100.                         max = tmp;
  101.                     }
  102.                     _board->MovePieceWithOutCheck(*curStep,*(curStep+1),i,j);
  103.                     curStep+=2;
  104.                     cur++;
  105.                 }
  106.             }
  107.         }
  108.     }
  109.     return max;
  110. }
复制代码


对于上面的算法类,不知道为什么。在计算时会改变棋盘的布局,也就是没办法在模拟对战后把布局改回原来的样子。。
我觉得应该是下面这个的问题,因为我不记得除了MovePieceWithOutCheck这个函数外还调用过其他能改变棋盘布局的函数,,。。。

  1. _board->MovePieceWithOutCheck(i,j,*curStep,*(curStep+1));
  2.                     tmp = Min(dp-1);
  3.                     if(tmp > max)
  4.                     {
  5.                         max = tmp;
  6.                     }
  7.                     _board->MovePieceWithOutCheck(*curStep,*(curStep+1),i,j);
复制代码

这个部分的问题。。。因为移动后的棋子因为深度的原因没有办法很好的回到它自己的原地。。。 [em17]

MovePieceWithOutCheck的实现:

  1. void chessboard::MovePieceWithOutCheck(int srcX, int srcY, int dstX, int dstY)
  2. {
  3.     if(    _board[srcX][srcY]!=EMPTYPLACE)
  4.     {
  5.         _board[dstX][dstY] = _board[srcX][srcY];
  6.         _board[srcX][srcY] = EMPTYPLACE;
  7.     }
  8.     else std::cout<<"!";//如果是错误的移动。。。也就是移动空格子就打印!
  9. }
复制代码


而在深度为>=3的情况下打印了很多"!!!!!!!!!!!!!!"。。。也就是说很多错误的移动。。。
不知道哪里出问题了 哎 [em4]

3

主题

101

帖子

101

积分

注册会员

Rank: 2

积分
101
发表于 2009-12-29 09:38:00 | 显示全部楼层

Re:对于极大极小算法。。。实现失败。。。求解

记得A*中的"权值",与,"父结点"吗,这都是很重要的,否则没有办法回退,就会造成无结果!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-16 04:43

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表