-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoard.java
191 lines (155 loc) · 4.76 KB
/
Board.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
package codecup2022.data;
public abstract class Board {
public static final byte EMPTY = -1;
public static final byte STRAIGHT = 0;
public static final byte LEFT = 1;
public static final byte RIGHT = 2;
private int turn = -2;
private int scoreBlue = 50;
private int scoreRed = 50;
public abstract byte get(int loc);
public byte get(int row, int col) {
return get(Move.location(row, col));
}
public boolean isEmpty(int loc) {
return get(loc) == EMPTY;
}
public boolean isEmpty(int row, int col) {
return isEmpty(Move.location(row, col));
}
protected abstract int applyRegularMove(int move);
protected abstract int undoRegularMove(int move);
public int getTurn() {
return turn;
}
public int getNumFreeSpaces() {
return 61 - turn; // 63 - 2 (jury) - turn
}
public boolean isGameOver() {
return turn == 61; // getNumFreeSpaces() == 0
}
public boolean isLegalMove(int move) {
return isEmpty(Move.getLocation(move));
}
public void applyMove(int move) {
updateScore(applyRegularMove(move));
turn++;
}
public void undoMove(int move) {
turn--;
updateScore(undoRegularMove(move));
}
private void updateScore(int scoreDelta) {
if (isCurrentPlayerBlue()) {
scoreBlue += scoreDelta;
} else {
scoreRed += scoreDelta;
}
}
public int getScore(boolean blue) {
return blue ? scoreBlue : scoreRed;
}
public boolean isCurrentPlayerBlue() {
return turn % 2 == 0;
}
public int scoreAfterMove(int move, boolean blue) {
applyMove(move);
int score = getScore(blue);
undoMove(move);
return score;
}
protected void initialize(Board board) {
turn = board.getTurn();
scoreBlue = board.getScore(true);
scoreRed = board.getScore(false);
}
protected void initializeTurn() {
int nTiles = 0;
for (int loc = 0; loc < 63; loc++) {
if (!isEmpty(loc)) {
nTiles++;
}
}
turn = nTiles - 2;
}
private static final int LEFT_TILE = Move.fromLocationTile(0, LEFT);
private static final int RIGHT_TILE = Move.fromLocationTile(0, RIGHT);
/**
* Returns a list of moves by the given player that includes each empty
* space with each possible tile.
*
* @return
*/
public int[] possibleMoves() {
int[] moves = new int[3 * getNumFreeSpaces()];
int index = 0;
for (int loc = 0; loc < 63; loc++) {
if (isEmpty(loc)) {
moves[index] = loc;
moves[index + 1] = loc | LEFT_TILE;
moves[index + 2] = loc | RIGHT_TILE;
index += 3;
}
}
return moves;
}
/**
* Returns a list of moves by the given player that includes each empty
* space with the STRAIGHT tile.
*
* @return
*/
public int[] emptySpaces() {
int[] moves = new int[getNumFreeSpaces()];
int index = 0;
for (int loc = 0; loc < 63; loc++) {
if (isEmpty(loc)) {
moves[index] = loc;
index++;
}
}
return moves;
}
/**
* @return Returns all moves in squares that could connect the left and right sides of the board.
*/
public abstract int[] connectingMoves();
/**
* @return Returns all moves in squares that could never create a cycle or same-side connection.
*/
public abstract int[] nonNegativeMoves();
public void print() {
System.err.println(" abcdefg");
for (int row = 0; row < 9; row++) {
System.err.print((char) (row + 'a'));
for (int col = 0; col < 7; col++) {
System.err.print(charForValue(get(row, col)));
}
System.err.println();
}
System.err.printf("B: %3d R: %3d%n", scoreBlue, scoreRed);
}
private char charForValue(int boardValue) {
switch (boardValue) {
case EMPTY:
return ' ';
case Board.STRAIGHT:
return 'S';
case Board.LEFT:
return 'L';
case Board.RIGHT:
return 'R';
default:
throw new IllegalArgumentException();
}
}
public void printMoves() {
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 7; col++) {
if (!isEmpty(row, col)) {
System.err.println(Move.toString(Move.fromRowColumnTile(row, col, get(row, col))));
}
}
}
}
}