-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGameTree.java
More file actions
executable file
·94 lines (80 loc) · 2.42 KB
/
GameTree.java
File metadata and controls
executable file
·94 lines (80 loc) · 2.42 KB
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
// Game trees for abstract games two-person games with outcomes in the
// type of integers, parametrized by a type of moves.
import java.util.*;
public class GameTree<Move> {
private final Board<Move> board;
private final Map<Move,GameTree<Move>> children;
private final int optimalOutcome;
public GameTree(Board<Move> board,
Map<Move,GameTree<Move>> children,
int optimalOutcome) {
assert(board != null && children != null);
this.board = board;
this.children = children;
this.optimalOutcome = optimalOutcome;
}
public boolean isLeaf() {
return(children.isEmpty());
}
// Getter methods:
public Board<Move> board () {
return board;
}
public Map<Move,GameTree<Move>> children() {
return children;
}
public int optimalOutcome() {
return optimalOutcome;
}
// The following two methods are for game tree statistics only.
// They are not used for playing.
// Number of tree nodes:
public int size() {
int size = 1;
for (Map.Entry<Move,GameTree<Move>> child : children.entrySet()) {
size += child.getValue().size();
}
return size;
}
// We take the height of a leaf to be zero (rather than -1):
public int height() {
int height = -1;
for (Map.Entry<Move,GameTree<Move>> e : children.entrySet()) {
height = Math.max(height,e.getValue().height());
}
return 1+height;
}
// Plays first using this tree:
public void firstPlayer(MoveChannel<Move> c) {
c.comment(board + "\nThe optimal outcome is " + optimalOutcome);
if (isLeaf()) {
assert(optimalOutcome == board.value());
c.end(board.value());
}
else {
Map.Entry<Move,GameTree<Move>> optimalEntry = null;
for (Map.Entry<Move,GameTree<Move>> child : children.entrySet()) {
if (optimalOutcome == child.getValue().optimalOutcome) {
optimalEntry = child;
break;
}
}
assert(optimalEntry != null);
c.giveMove(optimalEntry.getKey());
optimalEntry.getValue().secondPlayer(c);
}
}
// Plays second using this tree:
public void secondPlayer(MoveChannel<Move> c) {
c.comment(board + "\nThe optimal outcome is " + optimalOutcome);
if (isLeaf()) {
assert(optimalOutcome == board.value());
c.end(board.value());
}
else {
Move m = c.getMove();
assert(children.containsKey(m));
children.get(m).firstPlayer(c);
}
}
}