-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTetromino.h
315 lines (269 loc) · 9.36 KB
/
Tetromino.h
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
#ifndef __TETROMINO_H__
#define __TETROMINO_H__
/**
* Tetromino.h
*
* $Revision$
* $Id$
*
* Tetromino is controllable figure that can be attached to one
* TetrisBoard at the time.
*
* Tetromino has shape defined by maximum of four coordinates
* relative to it's origo. Tetromino can have 90 degree rotations
* from 1 to 4 (0..3 in code).
*
* Tetromino is capable of attaching itself to TetrisBoard when
* there is no collapse. When attached, tetromino can be rotated
* clockwise or counterclockwise or moved to left, right, up, down.
* when new position is not colliding with anything.
*
* Tetromino detects collides by quering TetrisBoard's cells in it's
* possible new position. If there is no collision, it can remove
* itself from current position and write it's type to new position
* in board.
*
* Responsibilities:
* - has it's shape and rotations, can rotate itself
* - can attach to and detach from TetrisBoards
* - attach can be made if there is no collision
* - detach can be clean -> tetrominoe writes EMPTY to it's former
* location
* - can detect collisions in TetrisBoard
* - can be rotated and moved in board, if no collision
* - knows when it has landed (can't move down)
* - can write ghost marks to maximum location it could drop (can be
* toggled on/off)
*
*/
#include "TetrisCommon.h"
#include "TetrisBoard.h"
class CTetromino {
public:
/**
* Constructor that defines the Tetromino's form.
*
* @param cellCoordsX 4 origo-relative x-coordinates defining the shape
* @param cellCoordsY 4 origo-relative y-coordinates defining the shape
* @param maxRotation maximum 90degree rotations from 0 (value of 0..3)
* @param type CELL_TYPE that is written to it's location on board
*/
CTetromino(int cellCoordsX[4], int cellCoordsY[4], int maxRotation, CELL_TYPE type);
~CTetromino(void);
// ================= METODIT =============================================
/**
* Sets the ghost marking on/off. If ghost is on, ghost cell-type is written
* to location that tetromino would drop if hard-dropped.
*
* @param value true, if ghost piece is used
* @since Revision 115
' */
inline void setGhost(bool value) {
m_ghost = value;
}
/**
* Rotates tetrominoe clockwise, if possible. Tests collision in current
* attached board before rotation is made. If Tetromino is not attached
* to any board, nothing is done.
*/
bool rotateRight(void);
/**
* Rotates tetrominoe counterclockwise, if possible. Tests collision in current
* attached board before rotation is made. If Tetromino is not attached
* to any board, nothing is done.
*/
bool rotateLeft(void);
/**
* Checks if tetromino is attached to instance of TetrisBoard.
*
* @return true, it tetromino is attached to TetrisBoard
*/
bool isAttached(void);
/**
* Attaches Tetromino to TetrisBoard. While attaching, Tetromino checks
* that attaching could be done eg. there is no collision in board.
* In case of collision, no attach is done and false is returned.
*
* If attach is successful, Tetromino will position it's origo to horizontal
* center of board, and vertically to the top row of board.
*
* If Tetromino is already attached to another board, clean detach from it
* is made.
*
* @param targetBoard instance of TetrisBoard that Tetromino needs to attach
* @return true, if attaching was possible (no collision)
*/
bool attach(CTetrisBoard *targetBoard);
/**
* @see attach(CTetrisBoard)
*
* Vertical attach position is top row of board plus offsetY.
*
* @see attach(CTetrisBoard)
* @param targetBoard instance of TetrisBoard that Tetromino needs to attach
* @param offsetY offset from top row of TetrisBoard (negative shifts downwards)
* @return true, if attaching was possible (no collision)
*/
bool attach(CTetrisBoard *targetBoard, int offsetY);
/**
* @see attach(CTetrisBoard)
*
* Vertical attach position is top row of board plus offsetY.
* Horizontal attach position is board center plus offsetX.
*
* @param targetBoard instance of TetrisBoard that Tetromino needs to attach
* @param offsetY offset from top row of TetrisBoard (negative shifts downwards)
* @return true, if attaching was possible (no collision)
*/
bool attach(CTetrisBoard *targetBoard, int offsetX, int offsetY);
/**
* Detach from current TetrisBoard. If clear flag is set true, makes clean detach
* (writes EMPTY to current cells in TetrisBoard). If clear is set false,
* Tetromino's cells in board are left with Tetromino's type.
*
* @param clear if true, writes EMPTY to it's location
*/
bool detach(bool clear);
/**
* Make no-clean detach from current TetrisBoard.
*
* @see detach(bool)
*/
bool detach();
/**
* Try to move Tetromino one cell. If there would be
* collision in new coordinates in board, nothing is done.
*/
bool moveLeft(void);
bool moveRight(void);
bool moveDown(void);
/**
* Try to move Tetromino by given count of cells.
* If there would be collision in new coordinates in board,
* nothing is done.
*
* @param n number of cells to move
*/
bool moveUp(int n);
bool moveDown(int n);
/**
* Move Tetromino down until next move would collide.
*/
bool drop(void);
/**
* Check if Tetromino has landed. Tetromino has landed if next move
* downwards would collide.
* Tetromino is also [TODO: tulkittu laskeutuneeksi jos] it's not attached
* to any TetrisBoard.
*
* @return true, if next move downwards would collide, or not detached
*/
bool hasLanded(void);
/**
* Check if Tetromino is attached to TetrisBoard and all of it's cells are
* visible in board (cells can go over board from top).
*
* @return true, if all cells are inside TetrisBoard
*/
bool isFullyVisible(void);
// ===========================================================================
// PRIVATE MEMBERS
// TODO: lontoonna
private:
/**
* Kenttä (TetrisBoard), johon tämä palikka on kiinnittyneenä.
* NULL, jos palikka ei ole kiinni missään kentässä.
*/
CTetrisBoard *board;
/**
* palikan oma tyyppi, jota se piirtää pelikenttään
* omiin koordinaatteihinsa
*/
CELL_TYPE m_type;
static const CELL_TYPE m_ghostType = GHOST;
/**
* Palikan koordinaatit nykyisessä kentässään.
* Palikka tarkistaa kenttään kiinnittyessään, että sen sijainti
* koordinaateissa on sallittu, tai kiinnittymistä ei tapahdu.
*/
int m_x;
int m_y;
/**
* The form of the tetromino. 4 pairs of coordinates relative to
* Tetromino's origo defining the cells it has in rotation 0.
*/
int m_cellCoordsX[4];
int m_cellCoordsY[4];
/**
* Current 90degree rotation of Tetromino. Value of 0..3.
*/
int m_rotation;
/**
* Palikan suurin sallittu rotaatio (0 -> m_rotationMax)
* Asetetaan constructorissa.
*/
int m_rotationMax;
bool m_ghost;
bool m_ghostOnBoard; // kertoo removeGhostFromBoardille onko boardilla ghostia joka poistettaisiin
int m_gy;
// ===========================================================================
// PRIVATE METHODS
private:
/**
* Asettaa rotaaion r jos mahdollista
* @return asettamisen onnistuminen
*/
bool setRotation(int r);
/**
* Testaa voiko palikka olla laudalla annetuissa koordinaateissa,
* annetulla orientaatiolla.
*
* @return false, jos joku palikan ruuduista ei ole tyhjä laudalla,
* tai jos palikka menee ohi laudasta sivusuunnassa (tai pohjasta)
*/
bool canMoveTo(const int x, const int y, const int rotation);
/** Ylläoleva omalla laudalla */
bool canMoveTo(const int x, const int y, const int rotation, CTetrisBoard *targetBoard);
/**
* @return nykyinen rotaatio (arvo väliltä 0..3)
*/
inline int getRotation() {
return m_rotation;
}
/**
* @return nykyisestä seuraava rotaatio (pyöräytettäessä myötäpäivään)
* arvo väliltä 0..3
*/
inline int getNextRotation() {
return (m_rotation+1 > m_rotationMax) ? 0 : m_rotation+1;
}
/**
* @return nykyisestä edellinen rotaatio (pyöräytettäessä vastapäivään)
* arvo väliltä 0..3
*/
inline int getPreviousRotation() {
return (m_rotation-1 < 0) ? m_rotationMax : m_rotation-1;
}
/**
* Palauttaa halutun rotaation relatiivisen koordinaatin
*/
int getRelativeX(const int x, const int rotation);
int getRelativeY(const int y, const int rotation);
/** Laske mikä on boardin keski-x -koordinaatti */
int getBoardCenterX(CTetrisBoard *targetBoard);
/** Testaa onko boardin koordinaatti {x,y} tämän palikan */
bool containsBoardCoord(int x, int y);
/**
* "Polttaa" palikan pelilaudan kenttään, eli vaihtaa omat ruutunsa
* pelilaudassa oman tyyppinsä mukaisiksi.
*/
void insertToBoard();
void insertGhostToBoard();
/**
* Poistaa itsensä pelilaudalta, eli kirjoittaa tyhjän ruudun arvon
* jokaiseen ruutuunsa pelilaudassa
*/
void removeFromBoard();
void removeGhostFromBoard();
};
#endif //__TETROMINO_H__