-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPerfectGame.java
More file actions
127 lines (110 loc) · 4.07 KB
/
PerfectGame.java
File metadata and controls
127 lines (110 loc) · 4.07 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
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
126
127
public class PerfectGame {
TicTacToe game;
GameOutcome overallOutcome;
int overallRemaining;
GameOutcome[] moveOutcomes;
int[] moveRemainings;
public PerfectGame(TicTacToe aGame) {
game = aGame;
moveOutcomes = new GameOutcome[game.board.length];
moveRemainings = new int[game.board.length];
resetOutcome();
setOutcome(game.gameState);
}
public void setOutcome(GameState state) {
overallRemaining = 0;
switch(state) {
case XWIN:
overallOutcome = game.nextPlayer() == CellValue.O ? GameOutcome.LOSE : GameOutcome.WIN;
break;
case OWIN:
overallOutcome = game.nextPlayer() == CellValue.X ? GameOutcome.LOSE : GameOutcome.WIN;
break;
case DRAW:
overallOutcome = GameOutcome.DRAW;
break;
default:
overallOutcome = GameOutcome.UNKNOWN;
}
}
public void setOutcome(PerfectGame nextMove, int position) {
GameOutcome currentOutcome;
int currentRemaining = nextMove.overallRemaining + 1;
switch (nextMove.overallOutcome) {
case WIN:
currentOutcome = GameOutcome.LOSE;
break;
case LOSE:
currentOutcome = GameOutcome.WIN;
break;
case DRAW:
currentOutcome = GameOutcome.DRAW;
break;
default:
throw new IllegalStateException("Unable to set the outcome on " + nextMove.overallOutcome + " for position " + position);
}
boolean shouldUpdate;
if (currentOutcome == GameOutcome.WIN) {
shouldUpdate = true;
} else if (currentOutcome == GameOutcome.DRAW && overallOutcome != GameOutcome.WIN) {
shouldUpdate = true;
} else if (currentOutcome == GameOutcome.LOSE && overallOutcome == GameOutcome.UNKNOWN) {
shouldUpdate = true;
} else {
shouldUpdate = false;
}
int index = position - 1;
moveOutcomes[index] = currentOutcome;
moveRemainings[index] = currentRemaining;
if (shouldUpdate) {
if (overallRemaining == 0 || currentRemaining < overallRemaining) {
overallRemaining = currentRemaining;
}
overallOutcome = currentOutcome;
}
}
public String toString() {
StringBuilder b = new StringBuilder();
int maxRowsIndex = game.numRows - 1;
int maxColumnsIndex = game.numColumns - 1;
String lineSeparator = Utils.repeat("---", game.numColumns) + Utils.repeat("-", game.numColumns - 1);
b.append("OVERALL: " + overallOutcome + "("+ overallRemaining +")\n");
for (int i = 0; i < game.numRows; i++) {
for (int j = 0; j < game.numColumns; j++) {
int index = i*game.numColumns + j;
b.append(" ");
b.append(toString(index));
b.append(" ");
if (j < maxColumnsIndex) {
b.append("|");
}
}
// Line separator after each row, except the last
if (i < maxRowsIndex) {
b.append("\n");
b.append(lineSeparator);
b.append("\n");
}
}
return b.toString();
}
private String toString(int index) {
int lookupIndex = game.boardIndexes[index];
switch (moveOutcomes[lookupIndex]) {
case WIN:
return "W " + moveRemainings[lookupIndex];
case LOSE:
return "L " + moveRemainings[lookupIndex];
case DRAW:
return "D " + moveRemainings[lookupIndex];
default:
return game.board[lookupIndex] + "";
}
}
private void resetOutcome() {
for (int i = 0; i < moveOutcomes.length; i++) {
moveOutcomes[i] = GameOutcome.UNKNOWN;
moveRemainings[i] = 0;
}
}
}