【发布时间】:2015-08-22 09:32:50
【问题描述】:
这是我实现 alpha beta 剪枝和记忆的 minimax 方法:
public int[] newminimax499(int a, int b){
int bestPos=-1;
int alpha= a;
int beta= b;
int currentScore;
//boardShow();
String stateString = "";
for (int i=0; i<state.length; i++)
stateString += state[i];
int[] oldAnswer = oldAnswers.get(stateString);
if (oldAnswer != null)
return oldAnswer;
if(isGameOver2()!='N'){
int[] answer = {score(), bestPos};
oldAnswers.put (stateString, answer);
return answer;
}
else{
for(int x:getAvailableMoves()){
if(turn=='O'){ //O is maximizer
setO(x);
//System.out.println(stateID++);
currentScore = newminimax499(alpha, beta)[0];
//revert(x);
if(currentScore>alpha){
alpha=currentScore;
bestPos=x;
}
/*if(alpha>=beta){
break;
}*/
}
else { //X is minimizer
setX(x);
//System.out.println(stateID++);
currentScore = newminimax499(alpha, beta)[0];
//revert(x);
if(currentScore<beta){
beta=currentScore;
bestPos=x;
}
/*if(alpha>=beta)
break;*/
}
revert(x);
if(alpha>=beta)
break;
}
}
if(turn=='O'){
int[] answer = {alpha, bestPos};
oldAnswers.put (stateString, answer);
return answer;
}
else {
int[] answer = {beta, bestPos};
oldAnswers.put (stateString, answer);
return answer;
}
}
作为一个测试游戏,在我的主要方法中,我在某处放置了一个 X(X 是玩家),然后调用 newminimax499 来查看我应该放置 O(计算机)的位置:
public static void main(String[] args) {
State3 s=new State3(3);
int [] result=new int[2];
s.setX(4);
result=s.newminimax499(Integer.MIN_VALUE, Integer.MAX_VALUE);
System.out.println("Score: "+result[0]+" Position: "+ result[1]);
System.out.println("Run time: " + (endTime-startTime));
s.boardShow();
}
}
该方法返回计算机应该播放的位置是O(在这种情况下是6),所以我按照指示放置O,为自己播放一个X,调用newminimax499并再次运行代码以查看O要播放的位置以此类推。
public static void main(String[] args) {
State3 s=new State3(3);
int [] result=new int[2];
s.setX(4);
s.setO(6);//Position returned from previous code run
s.setX(2);
s.setO(8);//Position returned from previous code run
s.setX(3);
result=s.newminimax499(Integer.MIN_VALUE, Integer.MAX_VALUE);
System.out.println("Score: "+result[0]+" Position: "+ result[1]);
System.out.println("Run time: " + (endTime-startTime));
s.boardShow();
}
在这个特定的运行之后,我得到了结果
Score: 10 Position: 7
哪个好。但是,在我的 GUI 中,这不是调用 newminimax 的方式。每次放置新的 X 或 O 时,板都不会重置。如果我把它放在前面例子中的 main 方法中,它看起来像这样(请记住,它是完全相同的输入序列):
public static void main(String[] args) {
State3 s=new State3(3);
int [] result=new int[2];
s.setX(4); //Player makes his move
result=s.newminimax499(Integer.MIN_VALUE, Integer.MAX_VALUE);//Where should pc play?
s.setO(result[1]);//PC makes his move
s.setX(2);//Player makes his move
result=s.newminimax499(Integer.MIN_VALUE, Integer.MAX_VALUE);//Where should PC make his move?
s.setO(result[1]);//PC makes his move
s.setX(3);//Player makes his move
result=s.newminimax499(Integer.MIN_VALUE, Integer.MAX_VALUE);
System.out.println("Score: "+result[0]+" Position: "+ result[1]);
System.out.println("Run time: " + (endTime-startTime));
s.boardShow();
}
现在,当以这种方式调用该方法时(这是它在 GUI 中的调用方式),它会返回:
Score: 0 Position: 5
这意味着它没有采取获胜的行动,而是阻止了对手。以这种方式玩了几场比赛后,很明显PC实际上输了。那么为什么这两种调用 newminimax499 的方式会返回不同的结果呢?
这是它在 GUI 上的外观:
注意:运行程序所需的所有方法都可以在此post 中找到。
【问题讨论】:
标签: java algorithm artificial-intelligence tic-tac-toe minimax