-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTetromino.h
374 lines (327 loc) · 8.17 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
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
/*****************************************************************//**
* \file Tetromino.h
* \brief Tetromino representation. Rotate, move, etc...
*
* \author Chau Le
* \date July 2021
*********************************************************************/
#pragma once
#ifndef TETROMINO_H
#define TETROMINO_H
#include "Board.h"
#include <SFML/Graphics.hpp>
#include <iostream>
#include <array>
#include <iterator>
#include <algorithm>
enum class Type { Z = 0, L = 1, O = 2, S = 3, I = 4, J = 5, T = 6 };
enum class Orientation { SPAWN = 0, RIGHT = 1, FLIP = 2, LEFT = 3 };
enum class Rotational_Direction { CCW = -1, NORO = 0, CW = 1, R180 = 2 };
enum class Moving_Direction { UP_DIR = 0, LEFT_DIR = 1, RIGHT_DIR = 2, DOWN_DIR = 3 };
const static std::vector<Type> allPieces{ Type::Z, Type::L, Type::O, Type::S, Type::I, Type::J, Type::T };
const static std::map<Type, sf::Color> pieceColorMap{
{Type::Z, sf::Color(255, 0, 0)},
{ Type::L, sf::Color(255,74,2) },
{ Type::O, sf::Color(255, 191, 0)},
{ Type::S, sf::Color(0, 219, 100)},
{ Type::I, sf::Color(0, 219, 255) },
{ Type::J, sf::Color(0, 0, 124) },
{ Type::T, sf::Color(241, 10, 249)}
};
const static std::array<std::array<std::array<int, 4>, 4>, 7> tetrominos = { {
{{ //Z block
{1, 1, 0, 0},
{0, 1, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
}},
{{ //L block
{0, 0, 2, 0},
{2, 2, 2, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
}},
{{ //O block
{0, 3, 3, 0},
{0, 3, 3, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
}},
{{ //S block
{0, 4, 4, 0},
{4, 4, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
}},
{{ //I block
{0, 0, 0, 0},
{5, 5, 5, 5},
{0, 0, 0, 0},
{0, 0, 0, 0}
}},
{{ //J block
{6, 0, 0, 0},
{6, 6, 6, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
}},
{{ //T block
{0, 7, 0, 0},
{7, 7, 7, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
}},
} };
// orientational mapping from mouse moving direction
const static std::array<std::array<Orientation, 4>, 7> orientationFromMouse = { {
{{ // Z piece
{Orientation::LEFT}, // UP
{Orientation::SPAWN}, // LEFT
{Orientation::FLIP}, // RIGHT
{Orientation::RIGHT} // DOWN
}},
{{ // L piece
{Orientation::LEFT}, // UP
{Orientation::FLIP}, // LEFT
{Orientation::SPAWN}, // RIGHT
{Orientation::RIGHT} // DOWN
}},
{{ // O piece
{Orientation::RIGHT}, // UP
{Orientation::FLIP}, // LEFT
{Orientation::SPAWN}, // RIGHT
{Orientation::LEFT} // DOWN
}},
{{ // S piece
{Orientation::RIGHT}, // UP
{Orientation::FLIP}, // LEFT
{Orientation::SPAWN}, // RIGHT
{Orientation::LEFT} // DOWN
}},
{{ // I piece
{Orientation::LEFT}, // UP
{Orientation::SPAWN}, // LEFT
{Orientation::FLIP}, // RIGHT
{Orientation::RIGHT} // DOWN
}},
{{ // J piece
{Orientation::RIGHT}, // UP
{Orientation::SPAWN}, // LEFT
{Orientation::FLIP}, // RIGHT
{Orientation::LEFT} // DOWN
}},
{{ // T piece
{Orientation::SPAWN}, // UP
{Orientation::LEFT}, // LEFT
{Orientation::RIGHT}, // RIGHT
{Orientation::FLIP} // DOWN
}},
} };
// shiftPos[type][orientation][x or y]
const static std::array<std::array<std::array<int, 2>, 4>, 7> shiftPos = { {
{{ // Z piece
{-2,-1}, // SPAWN
{-2,0}, // RIGHT
{0,-1}, // FLIP
{0,-2} // LEFT
}},
{{ // L piece
{-1,-1}, // SPAWN
{-1,-1}, // RIGHT
{-1,-1}, // FLIP
{-1,-1} // LEFT
}},
{{ // O piece
{-1,-1}, // SPAWN
{-2,-1}, // RIGHT
{-2,-1}, // FLIP
{-1,0} // LEFT
}},
{{ // S piece
{0,-1}, // SPAWN
{-2,-2}, // RIGHT
{-2,-1}, // FLIP
{0,0} // LEFT
}},
{{ // I piece
{-2,-1}, // SPAWN
{-2,-1}, // RIGHT
{-1,-2}, // FLIP
{-1,-2} // LEFT
}},
{{ // J piece
{-1,-1}, // SPAWN
{-1,-1}, // RIGHT
{-1,-1}, // FLIP
{-1,-1} // LEFT
}},
{{ // T piece
{-1,-1}, // SPAWN
{-1,-1}, // RIGHT
{-1,-1}, // FLIP
{-1,-1} // LEFT
}},
}};
/**
* Tetromino representation.
*/
class Tetromino
{
private:
static const int squareSize = 90;
sf::Texture cellsTexture;
sf::Sprite cellImage;
Orientation orientation = Orientation::SPAWN;
std::array<std::array<int, 4>, 4> cells = { 0 };
Type type;
// Spawn position
//*****************************************
int xPos = 3;
int yPos = 0;
bool isOnGround = false;
bool rotateLast = false;
/**
* Rotate the top left corner array of Tetromino in specified direction.
*
* \param arr Array
* \param size Size of the square. (Max:4)
* \param rDir Direction of rotation
*/
void rotateArray(std::array<std::array<int, 4>, 4>& arr, int size, Rotational_Direction rDir);
public:
Tetromino(Type type);
Tetromino(Type type, bool isGhost);
~Tetromino();
/**
* Get the ghost of the current tetromino.
*
* \param board Board that the tetromino is on
* \return A copy tetromino of the current tetromino with ghost color and hard drop on the board
*/
Tetromino getGhost(Board& board);
/**
* Make the tetromino have the ghost color.
*
*/
void turnToGhostColor();
bool setPiece(int x, int y, Moving_Direction mDir, Board& board);
bool rotate(Rotational_Direction rDir);
/**
* Rotate the tetromino on the board. Wall kick is implemented
*
* \param rDir Direction of rotation
* \param board Board the tetromino is on
* \return true if succeed, false otherwise
*/
bool rotate(Rotational_Direction rDir, Board& board);
/**
* Set xPos and yPos. (Only set the variable, not on the actual board)
*
* \param xPos
* \param yPos
* \param board To be placed on
* \return true if succeed, false otherwise
*/
bool setXY(int xPos, int yPos, Board& board);
void setXY(int xPos, int yPos);
/**
* Hard drop the tetromino on the board.
*
* \return number of cells dropped
* \param board To be placed on
*/
int hardDrop(Board& board);
/**
* Set the tetromino on the board.
*
* \param board To be placed on
*/
void setPiece(Board& board);
/**
* Check if tetromino is touching the ground or hanging.
*
* \param board
* \return true if tetromino on ground or hanging, false otherwise
*/
bool checkIsOnGround(Board& board);
//void softDrop();
/**
* Move tetromino in the specified direction 1 space.
*
* \param dir Direction of moving
* \param board
* \return true if succeed, false otherwise
*/
bool move(Moving_Direction dir, Board& board);
/**
* Check if there is a collision between tetromino and board.
*
* \param xPos
* \param yPos
* \param cells Array of tetromino
* \param board
* \return true if there's no collision, false if it is
*/
bool checkCollision(int xPos, int yPos, Board& board);
/**
* Check if there is a collision between tetromino and board.
*
* \param board
* \return true if there's no collision, false if it is
*/
bool checkCollision(Board& board);
std::array<int, 3> firstPossibleMoveNoRo(Board& board);
std::array<int, 4> firstPossibleMove(Board& board);
/**
* Render tetromino with the board position.
*
* \param window
* \param board
*/
void render(sf::RenderWindow& window, Board& board);
void setTransparency(sf::Uint8 transparency);
void renderBorder(sf::RenderWindow& window, Board& board, sf::Color color);
/**
* Render tetromino with a definite x and y on the window.
*
* \param window
* \param x
* \param y
*/
void render(sf::RenderWindow& window, int x, int y, int scale = 2);
/**
* Reset back to spawn condition.
*/
void reset();
/**
* Get tetromino's type.
*
* \return The type of the tetromino
*/
Type getType();
/**
* Get the current orientation of tetromino.
*
* \return The orientation of tetromino
*/
Orientation getOrientation();
int getXPos();
int getYPos();
/**
* Check if the last move is a rotation.
*
* \return rotateLast
*/
bool getRotateLast();
sf::Color getBaseColor()
{
return pieceColorMap.find(this->type)->second;
};
int getMinX();
int getMinY();
int getMaxX();
int getMaxY();
int getSquareCountX();
int getSquareCountY();
};
#endif