-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoard.java
211 lines (172 loc) · 5.61 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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
//SEE INCLUDED DOC FOR EXPLANATION
import java.awt.Point;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Board extends JPanel {
//Board Number used to assign a position to the board on the frame
private int boardNumber;
Board(int boardNumber) {
this.boardNumber = boardNumber;
}
private int score;
//The current co-ordinate of the current piece, with 0,0 being the top right square
private Point piecePoint;
//The rotational position of the piece (one of four orientations)
private int curRot;
private int curPiece;
private int nextPiece;
private int heldPiece;
//Point [piece number][rotaion][points]
private Point[][][] pieceSet = Pieces.getPieceSet();
private int[][] board = new int[Const.BOARDWIDTH][Const.BOARDHEIGHT];
private int[][] pieceLookAheadBox = new int[5][5];
private int[][] piecePrisonCell = new int[5][5];
public void holdPiece() {
int tempPiece;
//if no piece is prisoned
if (heldPiece == -1) {
//"arrests" the current piece
heldPiece = curPiece;
//resets position and other variable for the next "free" piece
resetPiece();
curPiece = nextPiece;
nextPiece = getNextPiece();
} else {
tempPiece = heldPiece;
heldPiece = curPiece;
resetPiece();
//sets new piece to the piece that was previosouly trapped
curPiece = tempPiece;
}
repaint();
}
public void hardDrop() {
while (true) {
if (!checkCol(curRot, piecePoint.x, piecePoint.y + 1)) {
//continuosly drops the piece until it collides
piecePoint.y++;
} else {
//when collision occurs, lock the piece in place
lockPiece();
break;
}
}
repaint();
}
private int getNextPiece() {
return (int) Math.floor(Math.random() * (Pieces.getNumPieces()));
}
private Point generatePiecePointPosition() {
return new Point((int) Math.floor((Const.BOARDWIDTH - 5) / 2), -1);
}
public void rotate(int reqRotations) {
int newRotation = (curRot + reqRotations) % 4;
if (newRotation < 0) {
newRotation = newRotation + 4;
}
if (!checkCol(newRotation,piecePoint.x, piecePoint.y)) {
curRot = newRotation;
}
}
private void resetPieceRot() {
curRot = 0;
}
private void resetPiece() {
piecePoint = generatePiecePointPosition();
resetPieceRot();
}
public void resetBoard() {
//clears board and fills with -1 which is code for empty chunk
for (int x = 0; x < Const.BOARDWIDTH; x++) {
for (int y = 0; y < Const.BOARDHEIGHT; y++) {
board[x][y] = -1;
}
}
for (int x = 0; x < x; x++) {
for (int y = 0; y < 5; y++) {
piecePrisonCell[x][y] = -1;
pieceLookAheadBox[x][y] = -1;
}
}
resetPiece();
//gets the first piece on the board
curPiece = getNextPiece();
nextPiece = getNextPiece();
//sets the held piece to be empty
heldPiece = -1;
}
public void softDrop(int deltaY) {
//checks whetjer tje desired change in y is valid
if (!checkCol(curRot, piecePoint.x, piecePoint.y + deltaY)) {
piecePoint.y += deltaY;
} else {
//if a piece can no longer travel downwards it is trapped in place
lockPiece();
}
}
public void move(int deltaX){
//checks whetjer tje desired change in x is valid
if (!checkCol(curRot, piecePoint.x + deltaX, piecePoint.y)) {
piecePoint.x += deltaX;
}
}
private void generatePiece(int nextGeneratedPiece) {
resetPiece();
curPiece = nextGeneratedPiece;
}
private boolean checkCol(int rotation, int pieceX, int pieceY) {
//for each of possible chunks in a shape in the current rotation, we check whether that point will collide or is out of bounds
for (Point checkerPoint : pieceSet[curPiece][rotation]) {
try {
if (board[checkerPoint.x + pieceX][checkerPoint.y + pieceY] != -1) {
return true;
}
}
//only occurs when moving/rotating into a wall
catch (IndexOutOfBoundsException ex){
return true;
}
}
return false;
}
public void lockPiece() {
//for each of 5 possible chunks in a shape, we add that point into the board since we know it doesnt collide
for (Point p : pieceSet[curPiece][curRot]) {
try {
board[piecePoint.x + p.x][piecePoint.y + p.y] = curPiece;
}
// only occurs when piece is above row 0 and thus game is voer
catch (IndexOutOfBoundsException ex){
//Game Over
Tetris.gameOver();
}
}
//checks whether a row is full so it can be ermoved
for (int y = Const.BOARDHEIGHT - 1; y > 0; y--) {
boolean isHole = false;
for (int x = 0; x < Const.BOARDWIDTH; x++) {
if (board[x][y] == -1) {
isHole = true;
break;
}
}
if (!isHole) {
for (int tempY = y-1; tempY > 0; tempY--) {
for (int x = 0; x < Const.BOARDWIDTH; x++) {
//copies the value of the grid above into itself
board[x][tempY+1] = board[x][tempY];
}
}
score++;
y ++;
}
}
generatePiece(nextPiece);
nextPiece = getNextPiece();
repaint();
}
@Override
public void paintComponent(Graphics g) {
GameGraphics.paintComponent(g, this.boardNumber, board, pieceSet, curPiece, curRot, piecePoint, nextPiece, heldPiece, score);
}
}