好的,我的这个问题对于玩过棋盘游戏编程的人来说应该很熟悉,问题如下:
- 我实现了一个MiniMax算法的变体(返回的是移动而不是最小/最大值)。
- 我还尝试将其设置为Alpha-Beta搜索,但最终完全失败了。
所以,这里是我的MiniMax代码:
Move* Board::miniMax(int depth){ return this->maxMove(1, depth);}Move* Board::maxMove(int ply, int depth){ vector<Move*> moves = this->possibleMoves(); int movesSize = moves.size(); Move* maxMove = new Move(MINUS_INF); for (int i=0; i<movesSize; i++) { Move* move = moves[i]; HASHMAKE(move,this); move->value = (ply<depth) ? (this->minMove(ply+1, depth))->value : this->eval(); maxMove = MAXMOVE(maxMove,move); UNHASHMAKE(move,this); } return maxMove;}Move* Board::minMove(int ply, int depth){ vector<Move*> moves = this->possibleMoves(); int movesSize = moves.size(); Move* minMove = new Move(PLUS_INF); for (int i=0; i<movesSize; i++) { Move* move = moves[i]; HASHMAKE(move,this); move->value = (ply<depth) ? (this->maxMove(ply+1, depth))->value : this->eval(); minMove = MINMOVE(minMove,move); UNHASHMAKE(move,this); } return minMove;}
关于如何调整上述代码以实现Alpha-Beta搜索,有什么建议吗?
这是我尝试进行Alpha-Beta转换的代码(结果非常失败):
Move* Board::alphaBeta(int depth){ return this->alphaMax(1,depth,MINUS_INF,PLUS_INF);}Move* Board::alphaMax(int ply, int depth, int a, int b){ vector<Move*> moves = this->possibleMoves(); int movesSize = moves.size(); Move* maxMove = new Move(MINUS_INF); for (int i=0; i<movesSize; i++) { Move* move = moves[i]; HASHMAKE(move,this); move->value = (ply<depth) ? (this->alphaMin(ply+1, depth,a,b))->value : this->eval(); maxMove = MAXMOVE(maxMove,move); if (maxMove->value>=b) return maxMove; a = MAXVAL(a,maxMove->value); UNHASHMAKE(move,this); } return maxMove;}Move* Board::alphaMin(int ply, int depth, int a, int b){ vector<Move*> moves = this->possibleMoves(); int movesSize = moves.size(); Move* minMove = new Move(PLUS_INF); for (int i=0; i<movesSize; i++) { Move* move = moves[i]; HASHMAKE(move,this); move->value = (ply<depth) ? (this->alphaMax(ply+1, depth,a,b))->value : this->eval(); minMove = MINMOVE(minMove,move); if (minMove->value<=a) return minMove; b = MINVAL(b,minMove->value); UNHASHMAKE(move,this); } return minMove;}
提示 (为了避免任何误解) :
-
this->eval()
函数返回的是从玩家A的角度来看的得分。例如,+100的得分意味着位置对玩家A有利,而-100的得分意味着位置对玩家B有利。 -
MINUS_INF
和PLUS_INF
分别被定义为任意小的和大的值。 -
这不是作业或类似的东西(如果是的话,我很可能永远不会对这种东西感兴趣…哈哈)
-
Move
是一个简单的类,包含移动的详细信息以及由eval
函数分配的相应值。 -
HASHMAKE
和UNHASHMAKE
只是两个移动(取消)制作和移动(取消)哈希的宏,不应该有太大影响。 -
MAXMOVE
定义如下:#define MAXMOVE(A,B) (((A)->value>=(B)->value)?(A):(B))
MINMOVE
定义如下:#define MINMOVE(A,B) (((A)->value<=(B)->value)?(A):(B))
回答:
不确定这是不是问题所在,但我认为在alphaMin
中
if (minMove->value<=a) return minMove;b = MINVAL(b,minMove->value);UNHASHMAKE(move,this);
应该改为
UNHASHMAKE(move,this);if (minMove->value<=a) return minMove;b = MINVAL(b,minMove->value);
在alphaMax
中也应该进行类似的更改。