Tetris: slightly better randomizer

This commit is contained in:
zvon 2020-08-23 15:49:38 +02:00
parent 74d8799ab5
commit 5d18c3b923

View File

@ -17,6 +17,14 @@
#define TICKS_TILL_FALL 500 #define TICKS_TILL_FALL 500
#define TICKS_TILL_DESCEND 50 #define TICKS_TILL_DESCEND 50
#define TETRIS_BRICK 0
#define TETRIS_T 1
#define TETRIS_L_RIGHT 2
#define TETRIS_Z_RIGHT 3
#define TETRIS_LINE 4
#define TETRIS_L_LEFT 5
#define TETRIS_Z_LEFT 6
bool pause = false; bool pause = false;
int pause_select = 0; int pause_select = 0;
int pause_max = 1; int pause_max = 1;
@ -30,10 +38,30 @@ bool update_score = false;
bool checked_line = false; bool checked_line = false;
bool wait_for_anim = false; bool wait_for_anim = false;
std::vector<int> bag = {28, 28, 28, 28, 28, 28, 28};
std::shared_ptr< SDLPP::Font > font; std::shared_ptr< SDLPP::Font > font;
std::shared_ptr< SDLPP::Scene > active_scene; std::shared_ptr< SDLPP::Scene > active_scene;
std::shared_ptr< SDLPP::Scene > pause_scene; std::shared_ptr< SDLPP::Scene > pause_scene;
class TetrisBlock : public SDLPP::RectangleRender {
public:
TetrisBlock() = delete;
TetrisBlock( double x, double y, double w, double h,
std::shared_ptr< SDLPP::Renderer > &r,
const std::string &img_or_color, bool is_polygon = false,
int index = 0)
: RectangleRender( x, y, w, h, r, img_or_color, is_polygon ) {
_index = index;
bag[_index]--;
}
~TetrisBlock() {
bag[_index]++;
}
private:
int _index = 0;
};
class TetrisPiece { class TetrisPiece {
public: public:
TetrisPiece() { TetrisPiece() {
@ -132,11 +160,11 @@ std::mutex movement_mutex;
std::shared_ptr< SDLPP::RectangleRender > std::shared_ptr< SDLPP::RectangleRender >
createTetrisBlock( double x, double y, const std::string &color, createTetrisBlock( double x, double y, const std::string &color,
const std::string &outline, const std::string &outline, int index,
std::shared_ptr< SDLPP::Renderer > renderer, std::shared_ptr< SDLPP::Renderer > renderer,
std::shared_ptr< SDLPP::Scene > scene ) { std::shared_ptr< SDLPP::Scene > scene ) {
auto ret = std::make_shared< SDLPP::RectangleRender >( auto ret = std::make_shared< TetrisBlock >(
x, y, BLOCK_SIZE, BLOCK_SIZE, renderer, color, true ); x, y, BLOCK_SIZE, BLOCK_SIZE, renderer, color, true, index );
ret->setOutlineColor( outline ); ret->setOutlineColor( outline );
ret->addCollision( SDLPP::Rect( 0.1, 0.1, 0.8, 0.8 ) ); ret->addCollision( SDLPP::Rect( 0.1, 0.1, 0.8, 0.8 ) );
ret->setId( BRICK_ID ); ret->setId( BRICK_ID );
@ -151,17 +179,17 @@ TetrisPiece tetrisBrick( std::shared_ptr< SDLPP::Renderer > renderer,
auto color = "#FF0000"; auto color = "#FF0000";
auto outline = "#AA0000"; auto outline = "#AA0000";
retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, TOP_BORDER, color, retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, TOP_BORDER, color,
outline, renderer, scene ), outline, TETRIS_BRICK, renderer, scene ),
0, 0 ); 0, 0 );
retPiece.addPiece( retPiece.addPiece(
createTetrisBlock( 0.5, TOP_BORDER, color, outline, renderer, scene ), createTetrisBlock( 0.5, TOP_BORDER, color, outline, TETRIS_BRICK, renderer, scene ),
0, 0 ); 0, 0 );
retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE,
TOP_BORDER + BLOCK_SIZE, color, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_BRICK, renderer, scene ),
0, 0 ); 0, 0 );
retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color, retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_BRICK, renderer, scene ),
0, 0 ); 0, 0 );
retPiece.setDefPos( 0.5, TOP_BORDER ); retPiece.setDefPos( 0.5, TOP_BORDER );
return retPiece; return retPiece;
@ -174,17 +202,17 @@ TetrisPiece tetrisT( std::shared_ptr< SDLPP::Renderer > renderer,
auto outline = "#00AA00"; auto outline = "#00AA00";
retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE,
TOP_BORDER + BLOCK_SIZE, color, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_T, renderer, scene ),
-1, 0 ); -1, 0 );
retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color, retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_T, renderer, scene ),
0, 0 ); 0, 0 );
retPiece.addPiece( retPiece.addPiece(
createTetrisBlock( 0.5, TOP_BORDER, color, outline, renderer, scene ), createTetrisBlock( 0.5, TOP_BORDER, color, outline, TETRIS_T, renderer, scene ),
0, -1 ); 0, -1 );
retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE, retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE,
TOP_BORDER + BLOCK_SIZE, color, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_T, renderer, scene ),
1, 0 ); 1, 0 );
retPiece.setDefPos( 0.5, TOP_BORDER ); retPiece.setDefPos( 0.5, TOP_BORDER );
return retPiece; return retPiece;
@ -197,17 +225,17 @@ TetrisPiece tetrisLRight( std::shared_ptr< SDLPP::Renderer > renderer,
auto outline = "#0000AA"; auto outline = "#0000AA";
retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE,
TOP_BORDER + BLOCK_SIZE, color, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_L_RIGHT, renderer, scene ),
-2, 0 ); -2, 0 );
retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color, retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_L_RIGHT, renderer, scene ),
-1, 0 ); -1, 0 );
retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE, retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE,
TOP_BORDER + BLOCK_SIZE, color, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_L_RIGHT, renderer, scene ),
0, 0 ); 0, 0 );
retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE, TOP_BORDER, color, retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE, TOP_BORDER, color,
outline, renderer, scene ), outline, TETRIS_L_RIGHT, renderer, scene ),
0, -1 ); 0, -1 );
retPiece.setDefPos( 0.5, TOP_BORDER ); retPiece.setDefPos( 0.5, TOP_BORDER );
return retPiece; return retPiece;
@ -220,16 +248,16 @@ TetrisPiece tetrisZRight( std::shared_ptr< SDLPP::Renderer > renderer,
auto outline = "#AA00AA"; auto outline = "#AA00AA";
retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE,
TOP_BORDER + BLOCK_SIZE, color, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_Z_RIGHT, renderer, scene ),
-1, 0 ); -1, 0 );
retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color, retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_Z_RIGHT, renderer, scene ),
0, 0 ); 0, 0 );
retPiece.addPiece( retPiece.addPiece(
createTetrisBlock( 0.5, TOP_BORDER, color, outline, renderer, scene ), createTetrisBlock( 0.5, TOP_BORDER, color, outline, TETRIS_Z_RIGHT, renderer, scene ),
0, -1 ); 0, -1 );
retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE, TOP_BORDER, color, retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE, TOP_BORDER, color,
outline, renderer, scene ), outline, TETRIS_Z_RIGHT, renderer, scene ),
1, -1 ); 1, -1 );
retPiece.setDefPos( 0.5, TOP_BORDER ); retPiece.setDefPos( 0.5, TOP_BORDER );
return retPiece; return retPiece;
@ -241,16 +269,16 @@ TetrisPiece tetrisLine( std::shared_ptr< SDLPP::Renderer > renderer,
auto color = "#FFFF00"; auto color = "#FFFF00";
auto outline = "#AAAA00"; auto outline = "#AAAA00";
retPiece.addPiece( createTetrisBlock( 0.5 - 2 * BLOCK_SIZE, TOP_BORDER, retPiece.addPiece( createTetrisBlock( 0.5 - 2 * BLOCK_SIZE, TOP_BORDER,
color, outline, renderer, scene ), color, outline, TETRIS_LINE, renderer, scene ),
-1, 0 ); -1, 0 );
retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, TOP_BORDER, color, retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, TOP_BORDER, color,
outline, renderer, scene ), outline, TETRIS_LINE, renderer, scene ),
0, 0 ); 0, 0 );
retPiece.addPiece( retPiece.addPiece(
createTetrisBlock( 0.5, TOP_BORDER, color, outline, renderer, scene ), createTetrisBlock( 0.5, TOP_BORDER, color, outline, TETRIS_LINE, renderer, scene ),
1, 0 ); 1, 0 );
retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE, TOP_BORDER, color, retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE, TOP_BORDER, color,
outline, renderer, scene ), outline, TETRIS_LINE, renderer, scene ),
2, 0 ); 2, 0 );
retPiece.setDefPos( 0.5, TOP_BORDER ); retPiece.setDefPos( 0.5, TOP_BORDER );
return retPiece; return retPiece;
@ -262,18 +290,18 @@ TetrisPiece tetrisLLeft( std::shared_ptr< SDLPP::Renderer > renderer,
auto color = "#00FFFF"; auto color = "#00FFFF";
auto outline = "#00AAAA"; auto outline = "#00AAAA";
retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, TOP_BORDER, color, retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, TOP_BORDER, color,
outline, renderer, scene ), outline, TETRIS_L_LEFT, renderer, scene ),
0, -1 ); 0, -1 );
retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE,
TOP_BORDER + BLOCK_SIZE, color, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_L_LEFT, renderer, scene ),
0, 0 ); 0, 0 );
retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color, retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_L_LEFT, renderer, scene ),
1, 0 ); 1, 0 );
retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE, retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE,
TOP_BORDER + BLOCK_SIZE, color, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_L_LEFT, renderer, scene ),
2, 0 ); 2, 0 );
retPiece.setDefPos( 0.5, TOP_BORDER ); retPiece.setDefPos( 0.5, TOP_BORDER );
return retPiece; return retPiece;
@ -285,17 +313,17 @@ TetrisPiece tetrisZLeft( std::shared_ptr< SDLPP::Renderer > renderer,
auto color = "#FFFFFF"; auto color = "#FFFFFF";
auto outline = "#AAAAAA"; auto outline = "#AAAAAA";
retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, TOP_BORDER, color, retPiece.addPiece( createTetrisBlock( 0.5 - BLOCK_SIZE, TOP_BORDER, color,
outline, renderer, scene ), outline, TETRIS_Z_LEFT, renderer, scene ),
-1, 0 ); -1, 0 );
retPiece.addPiece( retPiece.addPiece(
createTetrisBlock( 0.5, TOP_BORDER, color, outline, renderer, scene ), createTetrisBlock( 0.5, TOP_BORDER, color, outline, TETRIS_Z_LEFT, renderer, scene ),
0, 0 ); 0, 0 );
retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color, retPiece.addPiece( createTetrisBlock( 0.5, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_Z_LEFT, renderer, scene ),
0, 1 ); 0, 1 );
retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE, retPiece.addPiece( createTetrisBlock( 0.5 + BLOCK_SIZE,
TOP_BORDER + BLOCK_SIZE, color, TOP_BORDER + BLOCK_SIZE, color,
outline, renderer, scene ), outline, TETRIS_Z_LEFT, renderer, scene ),
1, 1 ); 1, 1 );
retPiece.setDefPos( 0.5, TOP_BORDER ); retPiece.setDefPos( 0.5, TOP_BORDER );
return retPiece; return retPiece;
@ -745,13 +773,20 @@ int main() {
renderer, main_scene ); renderer, main_scene );
next_object.setPos( 0.9, 0.5 ); next_object.setPos( 0.9, 0.5 );
while ( !quit ) { while ( !quit ) {
SDL_framerateDelay(&gFPS);
if ( cur_object.getObjects().size() == 0 && checked_line ) { if ( cur_object.getObjects().size() == 0 && checked_line ) {
std::lock_guard< std::mutex > guard( movement_mutex ); std::lock_guard< std::mutex > guard( movement_mutex );
cur_object = next_object; cur_object = next_object;
cur_object.setPos( 0.5, TOP_BORDER ); cur_object.setPos( 0.5, TOP_BORDER );
next_object = auto rand_index = std::rand() / ( ( RAND_MAX + 1u ) / 7 );
tetrisFunctions[std::rand() / ( ( RAND_MAX + 1u ) / 7 )]( int retries = 0;
renderer, main_scene ); while(bag[rand_index] < 4) {
rand_index = (rand_index + 1)%7;
retries++;
if(retries == 7)
quitGame();
}
next_object = tetrisFunctions[rand_index](renderer, main_scene);
next_object.setPos( 0.9, 0.5 ); next_object.setPos( 0.9, 0.5 );
checked_line = false; checked_line = false;
} }