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