-
Notifications
You must be signed in to change notification settings - Fork 1
/
AlphaBeta.java
126 lines (112 loc) · 4.1 KB
/
AlphaBeta.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mancala;
import java.io.*;
import java.util.ListIterator;
/**
*
* @author Neelam
*/
/* Get next best move based on Alpha Beta technique
* And traverse log shows the exploration of game
* tree in order to select best next move.
*/
public class AlphaBeta {
Utility util=new Utility();
private final int depth;
private static int count=0;
public AlphaBeta(int depth){
this.depth=depth;
}
//Game tree exploration
public void alphabeta(Game g) throws IOException{
try{
FileOutputStream fileOutputStreamTraverseLog=new FileOutputStream("traverse_log.txt");
OutputStreamWriter outputStreamWriterTraverseLog=new OutputStreamWriter(fileOutputStreamTraverseLog);
BufferedWriter bufferedWriterTraverseLog=new BufferedWriter(outputStreamWriterTraverseLog);
bufferedWriterTraverseLog.write("Node,Depth,Value,Alpha,Beta");
bufferedWriterTraverseLog.newLine();
Node root=new Node("root", g, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 0, true, null);
getAllMoves(root,bufferedWriterTraverseLog);
util.nextState(root);
bufferedWriterTraverseLog.close();
outputStreamWriterTraverseLog.close();
fileOutputStreamTraverseLog.close();
}
catch(Exception ex){
System.out.println("Exception in AlphaBeta : "+ex.getMessage());
}
}
/* Get all the valid moves based on current state
* and select next best move
*/
public void getAllMoves(Node n, BufferedWriter bw) throws IOException{
count=n.depth;
//Leaf Node
if(count>=depth && !n.game.getGetAnotherTurn()){
n.eval=util.eval(n.game.getPlayer(), n.game.getMancalaPlayer1(), n.game.getMancalaPlayer2());
bw.write(n.name+","+n.depth+","+util.evalToString(n.eval)+","+util.evalToString(n.alpha)+","+util.evalToString(n.beta));
bw.newLine();
return;
}
boolean valid=false;
if(count==depth && n.game.getGetAnotherTurn())
valid=true;
while((count<depth || valid) && !util.GameOver(n.game)){
bw.write(n.name+","+n.depth+","+util.evalToString(n.eval)+","+util.evalToString(n.alpha)+","+util.evalToString(n.beta));
bw.newLine();
util.expansion(n);
valid=false;
ListIterator<Node> listIterator=n.children.listIterator();
while(listIterator.hasNext()){
Node temp=listIterator.next();
temp.alpha=n.alpha;
temp.beta=n.beta;
getAllMoves(temp,bw);
if(n.max){
if(temp.eval>n.eval)
n.eval=temp.eval;
if(!prun(n)){
if(temp.eval>n.alpha)
n.alpha=temp.eval;
}
}
else{
if(temp.eval<n.eval)
n.eval=temp.eval;
if(!prun(n)){
if(temp.eval<n.beta)
n.beta=temp.eval;
}
}
bw.write(n.name+","+n.depth+","+util.evalToString(n.eval)+","+util.evalToString(n.alpha)+","+util.evalToString(n.beta));
bw.newLine();
if(prun(n))
break;
}
count++;
}
}
//Check pruning condition
public boolean prun(Node n){
if(n.max){
if(n.beta<=n.eval){ //Pruning
return true;
}
else{
return false;
}
}
else{
if(n.alpha>=n.eval){ //Pruning
return true;
}
else{
return false;
}
}
}
}