我到处寻找修复代码的答案,但在花了很长时间调试代码后,我发现自己陷入了绝望。问题是,我的minimax函数不会为可能的最佳移动返回正确的值,我甚至试图通过存储最佳的第一个移动(当深度=0时)来修复它,但如果解决方案不明显,那么该算法将严重失败。我还尝试修改基本案例的返回值,以便优先考虑早期的胜利,但这并没有解决问题。
目前我正在TictoE板上测试这个函数,助手类(如getMoves()或getWinner)工作正常,我知道我的风格不是最有效的,但我需要代码相当明确。通过添加大量打印声明,我意识到在某些情况下,我的bestFinalMoves ArrayList没有被修改,因此这可能与问题有关。另一个相关的问题是,除非算法(在下一步)找到一个直接的胜利,否则它不会选择一个可能导致未来胜利或平局的动作,而是通过阻止一个导致立即阻止的方块,它只会为最小化的玩家提供获胜的空间。
例如在黑板上:
aBoard= new int[][] {
{0,1,0}, // 1 is MAX (AI), -1 is MIN (Human)
{-1,0,0},
{-1,0,0}
};
产生不正确的结果2,0,很明显它应该是0,0,因此它阻止最小化玩家的胜利,并且最佳FinalMoves ArrayList是空的。
private result miniMaxEnd2(Board tmpGame, int depth){
String winner = tmpGame.whoWon();
ArrayList<Move> myMoves = tmpGame.getMoves();
if (winner == 'computer'){ //Base Cases
return new result(1000);
}else if (winner == 'human'){
return new result(-1000);
}
else if (winner == 'tie'){
return new result(0);
}
if (tmpGame.ComputerTurn) {//MAX
bestScore = -99999;
for (Move m : tmpGame.getMoves()){
Board newGame = new Board(tmpGame,!tmpGame.ComputerTurn, m);
result aScore = miniMaxEnd2(newGame, depth+1);
if (aScore.score > bestScore) {
bestScore = aScore.score;
bestMove = m;
if (depth == 0) {
bestFinalMoves.add(m);
}
}
}
return new result(bestScore, bestMove);
} else {//MIN
bestScore = 99999;
for (Move m : tmpGame.getMoves()) {
Board newGame = new Board(tmpGame,!tmpGame.ComputerTurn, m);
result aScore = miniMaxEnd2(newGame, depth + 1);
if (aScore.score < bestScore) {
bestScore = aScore.score;
bestMove = m;
}
}
return new result(bestScore,bestMove);
}
}
我知道这是一个很长的帖子,但我真的很感谢你的帮助。完整代码可访问https://github.com/serch037/UTC_Connect
Best Score
和Best Mobile
变量必须在minMaxEnd2
方法中声明为本地变量,以便该逻辑正常工作。这些变量的值被递归调用替换。
我在为游戏筷子做一个C程序。 这是一个非常简单的游戏,总共只有625个游戏状态(如果考虑到对称性和不可到达的状态,它甚至更低)。我读过minimax和alpha-beta算法,主要是针对tic-tac-toe的,但我遇到的问题是,在tic-tac-toe中,不可能循环回到以前的状态,而这在筷子中很容易发生。因此,当运行代码时,它将以堆栈溢出结束。 我通过添加以前访问过的州的标志来解决这个问题(我不
我想我终于对minimax和Alpha-beta修剪有所了解了,但实现它完全是另一回事! 根据我的理解,基础是:您为某些动作分配一个启发式函数分数(Gomoku为例)。 如果一行有5个,我们应该分配一个高值,比如9999,因为这是一个胜利的举动 当我们必须在Java中实现这一点时,我的问题来了! 我有一块彩色[][]板(8x8),其中黑色是播放器1,白色是播放器2,null表示空白,我不知道我们应
我已经为游戏跳棋编写了一个带有alpha-beta修剪的minimax算法,现在我正尝试使用negamax方法重写它。我希望这两者是等价的,因为negamax只是一种编写minimax的技术。但由于某种原因,我的两种算法表现不同。当我在相同的输入上运行它们时,negamax版本似乎评估了更多的状态,所以我认为alpha-beta修剪一定有问题。 下面的代码显示了这两种算法(
我正在尝试用Alpha-beta剪枝来实现Minimax,这是一款3D Tic-Tac-Toe游戏。然而,该算法似乎选择了次优路径。 例如,你可以通过直接跑过立方体的中间或穿过单板来赢得比赛。人工智能似乎选择了下一轮最佳的细胞,而不是当前一轮。 我尝试过重新创建并使用我返回的启发式算法,但没有取得多大进展。不管是哪一层,它似乎都有同样的问题。 代码在这里。 相关部分是和(以及'2'变体,这些只是我
极小极大算法的一个缺点是每个板状态必须被访问两次:一次查找其子级,第二次评估启发式值。 极小极大算法还有其他缺点或优点吗?对于像象棋这样的游戏,还有更好的选择吗?(当然是带有α-β修剪的极小极大算法,但还有其他吗?)
我一直在尝试使用极小值和阿尔法-贝塔修剪为计算机实现人工智能,但我面临着一个无法识别的错误。算法应该计算自己和其他玩家的所有可能移动,但它没有以应有的方式回放。 这是我的最小值代码: 未定义函数的详细信息: =检查棋盘是否有可能获胜或平局或不完整的棋盘,并将获胜者返回为1或2(玩家X或O),0表示平局,以及-1表示不完整的棋盘。 =返回一个数组列表,其中包含给定板中所有空位置的位置。 =简单地将X