我正在尝试编写极小化极大函数,使计算机总是赢或平局。我的算法已经到了反应性的阶段,大多数情况下会打成平局(有时赢有时输)。以下是我目前的代码。
public int minimax(char[][] state, int depth, boolean maximizingPlayer){ BoardState node = new BoardState(state); if(depth == 0 || new BoardState(state).terminalState()){ return score(node); } if(maximizingPlayer){ int bestValue = Integer.MIN_VALUE; ArrayList<int[]> moves = node.moves(); for(int[] move : moves){ state[move[0]][move[1]] = mark; int value = minimax(state, depth - 1, false); if(value > bestValue){ bestValue = value; bestX = move[0]; bestY = move[1]; } state[move[0]][move[1]] = '-'; } return bestValue; } else{ int bestValue = Integer.MAX_VALUE; ArrayList<int[]> moves = node.moves(); for(int[] move : moves){ state[move[0]][move[1]] = context.getOpposingMark(); int value = minimax(state, depth - 1, true); if(value < bestValue){ bestValue = value; bestX = move[0]; bestY = move[1]; } state[move[0]][move[1]] = '-'; } return bestValue; }}private int score(BoardState node){ if(node.winner(mark)){ return 10; } else if(node.winner(context.getOpposingMark())){ return -10; } else if(node.winningPosition(mark)){ return 1; } else if(node.winningPosition(context.getOpposingMark())){ return -1; } else{ return 0; }}
我的函数调用看起来像这样。
minimax(state, 2, true);
我遇到的问题是,如果增加深度,计算机就更不可能阻止对手获胜。然而,由于深度只有二,我认为算法没有足够的洞察力来阻止分叉移动(当对方玩家有一个可以放置在两个位置以赢得游戏的移动时)。有没有人能给我一些建议或指导,告诉我如何修改这个算法?我可以根据需要提供额外的源代码。
回答:
你所有的非终止位置的得分都是0。请仔细查看前终止位置,即那些一步可以导致立即获胜的位置。
例如,尝试为你在该位置的每一步获胜移动评分+1,而为对手在该位置的每一步获胜移动评分-1或-2。这将使算法更容易修剪对手有多种获胜方式而你只有少数几种的分支。
计算即时获胜移动应该相当便宜。当然,这基本上是内置的下降步骤,所以你的下降深度实际上会多一层。你可以减少初始允许的深度。