-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBoard.java
More file actions
320 lines (297 loc) · 9.63 KB
/
Board.java
File metadata and controls
320 lines (297 loc) · 9.63 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
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
package game;
import java.util.ArrayList;
/**
* 2048 Board
* Methods to complete:
* updateOpenSpaces(), addRandomTile(), swipeLeft(), mergeLeft(),
* transpose(), flipRows(), makeMove(char letter)
*
* @author Kal Pandit
* @author Ishaan Ivaturi
**/
public class Board {
private int[][] gameBoard; // the game board array
private ArrayList<BoardSpot> openSpaces; // the ArrayList of open spots: board cells without numbers.
/**
* Zero-argument Constructor: initializes a 4x4 game board.
**/
public Board() {
gameBoard = new int[4][4];
openSpaces = new ArrayList<>();
}
/**
* One-argument Constructor: initializes a game board based on a given array.
*
* @param board the board array with values to be passed through
**/
public Board(int[][] board) {
gameBoard = new int[board.length][board[0].length];
for (int r = 0; r < gameBoard.length; r++) {
for (int c = 0; c < gameBoard[r].length; c++) {
gameBoard[r][c] = board[r][c];
}
}
openSpaces = new ArrayList<>();
}
/**
* 1. Initializes the instance variable openSpaces (open board spaces) with an
* empty array.
* 2. Adds open spots to openSpaces (the ArrayList of open BoardSpots).
*
* Note: A spot (i, j) is open when gameBoard[i][j] = 0.
*
* Assume that gameBoard has been initialized.
**/
public void updateOpenSpaces() {
// WRITE YOUR CODE HERE
openSpaces = new ArrayList<>();
for (int r = 0; r < gameBoard.length; r++) {
for (int c = 0; c < gameBoard[r].length; c++) {
if (gameBoard[r][c] == 0) {
BoardSpot newOpenSpace = new BoardSpot(r, c);
openSpaces.add(newOpenSpace);
}
}
}
}
/**
* Adds a random tile to an open spot with a 90% chance of a 2 value and a 10%
* chance of a 4 value.
* Requires separate uses of StdRandom.uniform() to find a random open space and
* determine probability of a 4 or 2 tile.
*
* 1. Select a tile t by picking a random open space from openSpaces
* 2. Pick a value v by picking a double from 0 to 1 (not inclusive of 1); < .1
* means the tile is a 4, otherwise 2
* 3. Update the tile t on gameBoard with the value v
*
* Note: On the driver updateOpenStapes() is called before this method to ensure
* that openSpaces is up to date.
**/
public void addRandomTile() {
// WRITE YOUR CODE HERE
int a = 0;
int b = openSpaces.size();
int index = StdRandom.uniform(a, b);
BoardSpot closedSpot = openSpaces.get(index);
openSpaces.remove(closedSpot);
double v = StdRandom.uniform(0.0, 1.0);
if (v <= 0.1) {
gameBoard[closedSpot.getRow()][closedSpot.getCol()] = 4;
} else {
gameBoard[closedSpot.getRow()][closedSpot.getCol()] = 2;
}
}
/**
* Swipes the entire board left, shifting all nonzero tiles as far left as
* possible.
* Maintains the same number and order of tiles.
* After swiping left, no zero tiles should be in between nonzero tiles.
* (ex: 0 4 0 4 becomes 4 4 0 0).
**/
public void swipeLeft() {
// WRITE YOUR CODE HERE
int ptr = 0;
for (int c = 0; c < gameBoard.length; c++) {
ptr = 0;
for (int r = 0; r < gameBoard.length; r++) {
if (gameBoard[c][r] != 0) {
int temp = gameBoard[c][r];
gameBoard[c][r] = 0;
gameBoard[c][ptr] = temp;
ptr++;
}
}
}
}
/**
* Find and merge all identical left pairs in the board. Ex: "2 2 2 2" will
* become "2 0 2 0".
* The leftmost value takes on double its own value, and the rightmost empties
* and becomes 0.
**/
public void mergeLeft() {
// WRITE YOUR CODE HERE
for (int c = 0; c < gameBoard.length; c++) {
for (int r = 0; r < (gameBoard.length - 1); r++) {
if (gameBoard[c][r] == (gameBoard[c][r + 1]) && gameBoard[c][r]!=0) {
gameBoard[c][r] = (gameBoard[c][r]) * 2;
(gameBoard[c][r + 1]) = 0;
}
}
}
}
/**
* Rotates 90 degrees clockwise by taking the transpose of the board and then
* reversing rows.
* (complete transpose and flipRows).
* Provided method. Do not edit.
**/
public void rotateBoard() {
transpose();
flipRows();
}
/**
* Updates the instance variable gameBoard to be its transpose.
* Transposing flips the board along its main diagonal (top left to bottom
* right).
*
* To transpose the gameBoard interchange rows and columns.
* Col 1 becomes Row 1, Col 2 becomes Row 2, etc.
*
**/
public void transpose() {
// WRITE YOUR CODE HERE
for (int r = 0; r < gameBoard.length; r++) {
for (int c = r; c < gameBoard[r].length; c++) {
int temp = gameBoard[r][c];
gameBoard[r][c] = gameBoard[c][r];
gameBoard[c][r] = temp;
}
}
}
/**
* Updates the instance variable gameBoard to reverse its rows.
*
* Reverses all rows. Columns 1, 2, 3, and 4 become 4, 3, 2, and 1.
*
**/
public void flipRows() {
// WRITE YOUR CODE HERE
for (int r = 0; r < gameBoard.length; r++) {
int ptr = (gameBoard.length - 1);
for (int c = 0; c < (0.5 * gameBoard.length); c++) {
int temp = gameBoard[r][c];
gameBoard[r][c] = gameBoard[r][ptr];
gameBoard[r][ptr] = temp;
ptr--;
}
}
}
/**
* Calls previous methods to make right, left, up and down moves.
* Swipe, merge neighbors, and swipe. Rotate to achieve this goal as needed.
*
* @param letter the first letter of the action to take, either 'L' for left,
* 'U' for up, 'R' for right, or 'D' for down
* NOTE: if "letter" is not one of the above characters, do
* nothing.
**/
public void makeMove(char letter) {
// WRITE YOUR CODE HERE
if (letter == 'L') {
swipeLeft();
mergeLeft();
swipeLeft();
}
if (letter == 'U') {
rotateBoard();
rotateBoard();
rotateBoard();
swipeLeft();
mergeLeft();
swipeLeft();
rotateBoard();
}
if (letter == 'R') {
rotateBoard();
rotateBoard();
swipeLeft();
mergeLeft();
swipeLeft();
rotateBoard();
rotateBoard();
}
if (letter == 'D') {
rotateBoard();
swipeLeft();
mergeLeft();
swipeLeft();
rotateBoard();
rotateBoard();
rotateBoard();
}
}
/**
* Returns true when the game is lost and no empty spaces are available. Ignored
* when testing methods in isolation.
*
* @return the status of the game -- lost or not lost
**/
public boolean isGameLost() {
return openSpaces.size() == 0;
}
/**
* Shows a final score when the game is lost. Do not edit.
**/
public int showScore() {
int score = 0;
for (int r = 0; r < gameBoard.length; r++) {
for (int c = 0; c < gameBoard[r].length; c++) {
score += gameBoard[r][c];
}
}
return score;
}
/**
* Prints the board as integer values in the text window. Do not edit.
**/
public void print() {
for (int r = 0; r < gameBoard.length; r++) {
for (int c = 0; c < gameBoard[r].length; c++) {
String g = Integer.toString(gameBoard[r][c]);
StdOut.print((g.equals("0")) ? "-" : g);
for (int o = 0; o < (5 - g.length()); o++) {
StdOut.print(" ");
}
}
StdOut.println();
}
}
/**
* Prints the board as integer values in the text window, with open spaces
* denoted by "**"". Used by TextDriver.
**/
public void printOpenSpaces() {
for (int r = 0; r < gameBoard.length; r++) {
for (int c = 0; c < gameBoard[r].length; c++) {
String g = Integer.toString(gameBoard[r][c]);
for (BoardSpot bs : getOpenSpaces()) {
if (r == bs.getRow() && c == bs.getCol()) {
g = "**";
}
}
StdOut.print((g.equals("0")) ? "-" : g);
for (int o = 0; o < (5 - g.length()); o++) {
StdOut.print(" ");
}
}
StdOut.println();
}
}
/**
* Seed Constructor: Allows students to set seeds to debug random tile cases.
*
* @param seed the long seed value
**/
public Board(long seed) {
StdRandom.setSeed(seed);
gameBoard = new int[4][4];
}
/**
* Gets the open board spaces.
*
* @return the ArrayList of BoardSpots containing open spaces
**/
public ArrayList<BoardSpot> getOpenSpaces() {
return openSpaces;
}
/**
* Gets the board 2D array values.
*
* @return the 2D array game board
**/
public int[][] getBoard() {
return gameBoard;
}
}