diff options
Diffstat (limited to 'src/games/tetris')
| -rw-r--r-- | src/games/tetris/Board.cpp | 52 | ||||
| -rw-r--r-- | src/games/tetris/Board.hpp | 9 | ||||
| -rw-r--r-- | src/games/tetris/Tetris.cpp | 259 | ||||
| -rw-r--r-- | src/games/tetris/Tetris.hpp | 45 | ||||
| -rw-r--r-- | src/games/tetris/Tetromino.cpp | 100 | ||||
| -rw-r--r-- | src/games/tetris/Tetromino.hpp | 20 | 
6 files changed, 250 insertions, 235 deletions
diff --git a/src/games/tetris/Board.cpp b/src/games/tetris/Board.cpp index 1e57b2f..c1af5e1 100644 --- a/src/games/tetris/Board.cpp +++ b/src/games/tetris/Board.cpp @@ -1,23 +1,27 @@ -#include <games/tetris/Tetromino.hpp>  #include <games/tetris/Board.hpp> +#include <games/tetris/Tetromino.hpp>  #include <renderer/Renderer.hpp> -Board::Board() { +void +Board::Reset() +{      for (int y = 0; y < 2; y++) { -        m_Bitmap[y] = 0xffff; // 1111111111111111 +        m_bitmap[y] = 0xffff; // 1111111111111111      }      for (int y = 2; y < 24; y++) { -        m_Bitmap[y] = 0xe007; // 1110000000000111 +        m_bitmap[y] = 0xe007; // 1110000000000111      }      for (int y = 0; y < 22; y++) {          for (int x = 0; x < 10; x++) { -            m_Idmap[y][x] = Tetromino::tetromino_id_none; +            m_idmap[y][x] = Tetromino::id_none;          }      }  } -int32_t Board::PlaceTetromino(Tetromino &tetromino) { +int32_t +Board::PlaceTetromino(Tetromino &tetromino) +{      BoardPos pos = tetromino.GetPos();      Tetromino::TetrominoId id = tetromino.GetId();      uint16_t tetromino_bitmap[4]; @@ -25,10 +29,10 @@ int32_t Board::PlaceTetromino(Tetromino &tetromino) {      // place in Board's Bitmap -    m_Bitmap[pos.y+0] |= tetromino_bitmap[0]; -    m_Bitmap[pos.y+1] |= tetromino_bitmap[1]; -    m_Bitmap[pos.y+2] |= tetromino_bitmap[2]; -    m_Bitmap[pos.y+3] |= tetromino_bitmap[3]; +    m_bitmap[pos.y+0] |= tetromino_bitmap[0]; +    m_bitmap[pos.y+1] |= tetromino_bitmap[1]; +    m_bitmap[pos.y+2] |= tetromino_bitmap[2]; +    m_bitmap[pos.y+3] |= tetromino_bitmap[3];      // place in Board's Idmap @@ -38,7 +42,7 @@ int32_t Board::PlaceTetromino(Tetromino &tetromino) {              if (tetromino_bitmap[y] & bitmap_x) {                  int32_t idmap_x = pos.x + x - 3;                  int32_t idmap_y = pos.y + y - 2; -                m_Idmap[idmap_y][idmap_x] = id; +                m_idmap[idmap_y][idmap_x] = id;              }          }      } @@ -47,7 +51,9 @@ int32_t Board::PlaceTetromino(Tetromino &tetromino) {      return rows_cleared;  } -int32_t Board::ClearRows(int32_t y0) { +int32_t +Board::ClearRows(int32_t y0) +{      int32_t rows_cleared = 0;      int32_t y1 = y0 + 3; @@ -57,28 +63,30 @@ int32_t Board::ClearRows(int32_t y0) {      }      for (int32_t y = y0; y <= y1; y++) { -        if (m_Bitmap[y] == 0xffff) { +        if (m_bitmap[y] == 0xffff) {              rows_cleared++;          }          else { -            m_Bitmap[y-rows_cleared] = m_Bitmap[y]; -            std::copy(m_Idmap[y-2], m_Idmap[y-2] + 10, m_Idmap[y-2-rows_cleared]); +            m_bitmap[y-rows_cleared] = m_bitmap[y]; +            std::copy(m_idmap[y-2], m_idmap[y-2] + 10, m_idmap[y-2-rows_cleared]);          }      }      for (int32_t y = y1+1; y < 24; y++) { -        m_Bitmap[y-rows_cleared] = m_Bitmap[y]; -        std::copy(m_Idmap[y-2], m_Idmap[y-2] + 10, m_Idmap[y-2-rows_cleared]); +        m_bitmap[y-rows_cleared] = m_bitmap[y]; +        std::copy(m_idmap[y-2], m_idmap[y-2] + 10, m_idmap[y-2-rows_cleared]);      }      for (int32_t y = 24-rows_cleared; y < 24; y++) { -        m_Bitmap[y] = 0xe007; -        std::fill(m_Idmap[y-2], m_Idmap[y-2] + 10, Tetromino::tetromino_id_none); +        m_bitmap[y] = 0xe007; +        std::fill(m_idmap[y-2], m_idmap[y-2] + 10, Tetromino::id_none);      }      return rows_cleared;  } -void Board::Draw(int32_t level) { +void +Board::Draw(int32_t level) +{      float world_width = 4.0f;      float world_height = 3.0f;      float tetromino_size_with_border = world_height / 20.0f; @@ -113,8 +121,8 @@ void Board::Draw(int32_t level) {      // tetromino parts      for (size_t y = 0; y < 20; y++) {          for (size_t x = 0; x < 10; x++) { -            Tetromino::TetrominoId tetromino_id = (Tetromino::TetrominoId)m_Idmap[y][x]; -            if (tetromino_id < Tetromino::tetromino_id_count) { +            Tetromino::TetrominoId tetromino_id = (Tetromino::TetrominoId)m_idmap[y][x]; +            if (tetromino_id < Tetromino::id_count) {                  V2F32 local_pos = {                      (float)x * tetromino_size_with_border + tetromino_offset,                      (float)y * tetromino_size_with_border + tetromino_offset diff --git a/src/games/tetris/Board.hpp b/src/games/tetris/Board.hpp index 2e2edb2..a91556b 100644 --- a/src/games/tetris/Board.hpp +++ b/src/games/tetris/Board.hpp @@ -13,8 +13,7 @@ struct BoardPos {  class Board {  public: -    Board(); - +    void Reset();      int32_t PlaceTetromino(Tetromino &tetromino);      void Draw(int32_t level); @@ -24,8 +23,8 @@ private:  private: -    friend class Tetromino; -    uint16_t m_Bitmap[24]; -    uint8_t m_Idmap[22][10]; +    friend class Tetris; +    uint16_t m_bitmap[24]; +    uint8_t m_idmap[22][10];  }; diff --git a/src/games/tetris/Tetris.cpp b/src/games/tetris/Tetris.cpp index d26649f..3370e78 100644 --- a/src/games/tetris/Tetris.cpp +++ b/src/games/tetris/Tetris.cpp @@ -1,3 +1,4 @@ +#include <games/Game.hpp>  #include <games/tetris/Tetromino.hpp>  #include <games/tetris/Tetris.hpp>  #include <renderer/Renderer.hpp> @@ -8,76 +9,72 @@  #include <fstream> -// Todo: change to new font scaling api in imgui first -// Todo: test text with hardcoded gap + dummy to ensure it gets placed as expected -Tetris::Tetris() : -    m_ActiveTetromino(m_Board), -    m_NextTetromino(m_Board) +void +Tetris::Start()  { -    m_TetrominoCounters[(size_t)m_ActiveTetromino.GetId()] += 1; +    m_game_status = game_resuming; + +    m_tlast_milliseconds = SDL_GetTicks(); +    m_dt_remaining_seconds = 0.0f; + +    m_board.Reset(); +    m_active_tetromino.Reinit(m_board.m_bitmap); +    m_next_tetromino.Reinit(m_board.m_bitmap); +    m_tetromino_counters[(size_t)m_active_tetromino.GetId()] += 1; + +    memset(m_tetromino_counters, 0, sizeof(m_tetromino_counters)); +    m_score = 0; +    m_line_counter = 0; +    m_starting_level = 0; +    m_level = 0; +    m_softdrop_counter = 0;  } -void Tetris::Restart() { -    m_RunningState = TetrisRunningState::Resume; -    m_DtInSecondsRemaining = 0.0f; -    m_MillisecondsSinceT0Last = SDL_GetTicks(); - -    // Todo: Don't reconstruct! Make reset methods. -    m_Board = Board(); -    m_ActiveTetromino = Tetromino(m_Board); -    m_NextTetromino = Tetromino(m_Board); - -    memset(m_TetrominoCounters, 0, sizeof(m_TetrominoCounters)); -    m_Score = 0; -    m_LineCounter = 0; -    m_StartingLevel = 0; -    m_Level = 0; -    m_SoftdropCounter = 0; -} - -bool Tetris::Update(std::vector<SDL_Event> &events) { +bool +Tetris::Update(std::vector<SDL_Event> &events) +{      Color clear_color = {0.2f, 0.2f, 0.2f, 1.0f};      g_renderer.SetCameraSize(4.0f, 3.0f);      g_renderer.Clear(clear_color); -    if (m_RunningState == TetrisRunningState::Restart) { -        Restart(); + +    if (m_game_status == game_starting) { +        Start();      } -    uint64_t milliseconds_since_t0 = SDL_GetTicks(); -    uint64_t milliseconds_since_t0_last = m_MillisecondsSinceT0Last; -    uint64_t milliseconds_dt = milliseconds_since_t0 - milliseconds_since_t0_last; -    float seconds_dt = static_cast<float>(milliseconds_dt) / 1000.0f; -    m_MillisecondsSinceT0Last = milliseconds_since_t0; +    float dt = ProcessDt(); -    if (m_RunningState == TetrisRunningState::Resume) { -        uint32_t harddrop_count = GetHarddropCount(seconds_dt); -        while (harddrop_count) { -            bool moved_down = m_ActiveTetromino.MaybeMoveDown(); + +    if (m_game_status == game_resuming) { +        uint32_t softdrop_count = GetSoftdropCount(dt); // side-effect: m_dt_remaining_seconds +        for (uint32_t i{0}; i < softdrop_count; i++) { +            bool moved_down = m_active_tetromino.MaybeMoveDown();              if (!moved_down) {                  HandleTetrominoPlacement();              } -            harddrop_count--;          }      }      for (auto &event : events) { -        using enum TetrisRunningState; -        switch (m_RunningState) { -        case Resume: UpdateResumeState(event); break; -        case Pause: UpdatePauseState(event); break; +        switch (m_game_status) { +        case game_resuming: UpdateResumeState(event); break; +        case game_paused: UpdatePauseState(event); break;          default:;          }      } -    Draw(); + +    if (m_game_status == game_exit) { +        return false; +    } -    bool keep_running = m_RunningState != TetrisRunningState::Exit; -    return keep_running; +    Draw(); + +    return true;  }  void Tetris::UpdateResumeState(SDL_Event &event) { @@ -85,23 +82,23 @@ void Tetris::UpdateResumeState(SDL_Event &event) {      case SDL_EVENT_KEY_DOWN: {          auto key = event.key.key;          if (key == SDLK_RIGHT) { -            m_ActiveTetromino.MaybeMoveHorizontally(Tetromino::right); +            m_active_tetromino.MaybeMoveHorizontally(Tetromino::right);          } else if (key == SDLK_LEFT) { -            m_ActiveTetromino.MaybeMoveHorizontally(Tetromino::left); +            m_active_tetromino.MaybeMoveHorizontally(Tetromino::left);          } else if (key == SDLK_DOWN) { -            bool moved_down = m_ActiveTetromino.MaybeMoveDown(); +            bool moved_down = m_active_tetromino.MaybeMoveDown();              if (!moved_down) {                  HandleTetrominoPlacement();              }              else { -                m_SoftdropCounter++; +                m_softdrop_counter++;              }          } else if (key == SDLK_X) { -            m_ActiveTetromino.MaybeRotate(Tetromino::rotate_clockwise); +            m_active_tetromino.MaybeRotate(Tetromino::rotate_clockwise);          } else if (key == SDLK_Z || key == SDLK_Y) { -            m_ActiveTetromino.MaybeRotate(Tetromino::rotate_counter_clockwise); +            m_active_tetromino.MaybeRotate(Tetromino::rotate_counter_clockwise);          } else if (key == SDLK_ESCAPE) { -            m_RunningState = TetrisRunningState::Pause; +            m_game_status = game_paused;          }      }      default:; @@ -113,75 +110,81 @@ void Tetris::UpdatePauseState(SDL_Event &event) {      case SDL_EVENT_KEY_DOWN: {          auto key = event.key.key;          if (key == SDLK_ESCAPE) { -            m_RunningState = TetrisRunningState::Resume; +            m_game_status = game_resuming;          }      }      default:;      }  } -void Tetris::HandleTetrominoPlacement() { -    int32_t rows_cleared = m_Board.PlaceTetromino(m_ActiveTetromino); +void +Tetris::HandleTetrominoPlacement() +{ +    int32_t rows_cleared = m_board.PlaceTetromino(m_active_tetromino); -    m_ActiveTetromino = m_NextTetromino; -    m_NextTetromino = Tetromino{m_Board}; +    m_active_tetromino = m_next_tetromino; +    m_next_tetromino.Reinit(m_board.m_bitmap); -    if (m_ActiveTetromino.IsCollisionWithBoard()) { +    if (m_active_tetromino.IsCollisionWithBoard()) {          HandleGameOver();          return;      } -    m_LineCounter += rows_cleared; -    m_TetrominoCounters[m_ActiveTetromino.GetId()] += 1; +    m_line_counter += rows_cleared; +    m_tetromino_counters[m_active_tetromino.GetId()] += 1;      if (rows_cleared == 1) { -        m_Score += 40 * (m_Level + 1); +        m_score += 40 * (m_level + 1);      }      else if (rows_cleared == 2) { -        m_Score += 100 * (m_Level + 1); +        m_score += 100 * (m_level + 1);      }      else if (rows_cleared == 3) { -        m_Score += 300 * (m_Level + 1); +        m_score += 300 * (m_level + 1);      }      else if (rows_cleared == 4) { -        m_Score += 1200 * (m_Level + 1); +        m_score += 1200 * (m_level + 1);      } -    m_Score += m_SoftdropCounter; -    m_SoftdropCounter = 0; +    m_score += m_softdrop_counter; +    m_softdrop_counter = 0; -    m_Level = m_StartingLevel + m_LineCounter / 10; +    m_level = m_starting_level + m_line_counter / 10;  } -uint32_t Tetris::GetHarddropCount(float dt) { +uint32_t +Tetris::GetSoftdropCount(float dt) +{      float nes_frame_time = 1.0f / 60;      int32_t nes_frames_per_cell; -    if      (m_Level <= 8)  nes_frames_per_cell = 48 - m_Level * 5; -    else if (m_Level == 9)  nes_frames_per_cell = 6; -    else if (m_Level <= 12) nes_frames_per_cell = 5; -    else if (m_Level <= 15) nes_frames_per_cell = 4; -    else if (m_Level <= 18) nes_frames_per_cell = 3; -    else if (m_Level <= 28) nes_frames_per_cell = 2; +    if      (m_level <= 8)  nes_frames_per_cell = 48 - m_level * 5; +    else if (m_level == 9)  nes_frames_per_cell = 6; +    else if (m_level <= 12) nes_frames_per_cell = 5; +    else if (m_level <= 15) nes_frames_per_cell = 4; +    else if (m_level <= 18) nes_frames_per_cell = 3; +    else if (m_level <= 28) nes_frames_per_cell = 2;      else                    nes_frames_per_cell = 1;      float dt_level = static_cast<float>(nes_frames_per_cell) * nes_frame_time; -    float dt_total = m_DtInSecondsRemaining + dt; -    uint32_t harddrop_count = 0; -    while (dt_total > dt_level) { -        harddrop_count += 1; -        dt_total -= dt_level; +    uint32_t softdrop_count = 0; +    while (dt > dt_level) { +        softdrop_count += 1; +        dt -= dt_level;      } -    m_DtInSecondsRemaining = dt_total; -    return harddrop_count; + +    m_dt_remaining_seconds = dt; +    return softdrop_count;  } -void Tetris::HandleGameOver() { -    m_RunningState = TetrisRunningState::GameOver; +void +Tetris::HandleGameOver() +{ +    m_game_status = game_over;      const char *filepath = "tetris_highscore.txt";      int32_t highscore = 0; @@ -195,16 +198,16 @@ void Tetris::HandleGameOver() {          SDL_LogInfo(0, "Tetris: cannot open tetris_highscore.txt for reading");      } -    if (highscore > 0 && highscore > m_HighScore) { -        m_HighScore = highscore; +    if (highscore > 0 && highscore > m_highscore) { +        m_highscore = highscore;      } -    if (m_Score > m_HighScore) { -        m_HighScore = m_Score; +    if (m_score > m_highscore) { +        m_highscore = m_score;          std::ofstream highscore_file_out { filepath };          if (highscore_file_out) { -            highscore_file_out << m_HighScore << std::endl; +            highscore_file_out << m_highscore << std::endl;              highscore_file_out.close();          }          else { @@ -213,9 +216,11 @@ void Tetris::HandleGameOver() {      }  } -void Tetris::Draw() { -    m_Board.Draw(m_Level); -    m_ActiveTetromino.Draw(); +void +Tetris::Draw() +{ +    m_board.Draw(m_level); +    m_active_tetromino.Draw();      DrawNextTetromino();      DrawStatistics(); @@ -224,52 +229,44 @@ void Tetris::Draw() {      DrawScore();      // Todo: Use transparency -    if (m_RunningState  == TetrisRunningState::Pause) { -        DrawPauseMenu(); +    if (m_game_status  == game_paused) { +        DrawGamePausedMenu();      } -    else if (m_RunningState == TetrisRunningState::GameOver) { +    else if (m_game_status == game_over) {          DrawGameOverMenu();      }  } -void Tetris::DrawPauseMenu() { -    ImGui::Begin("TetrisPause", nullptr, s_MenuImGuiWindowFlags); -    if (ImGui::Button("Resume")) { -        m_RunningState = TetrisRunningState::Resume; -    } -    if (ImGui::Button("Restart")) { -        m_RunningState = TetrisRunningState::Restart; -    } -    if (ImGui::Button("Exit")) { -        m_RunningState = TetrisRunningState::Exit; -    } -    ImGui::End(); -} - -void Tetris::DrawGameOverMenu() { +void +Tetris::DrawGameOverMenu() +{      ImGui::Begin("TetrisGameOver", nullptr, s_MenuImGuiWindowFlags); -    ImGui::Text("Score = %d", m_Score); -    ImGui::Text("HighScore = %d", m_HighScore); +    ImGui::Text("Score = %d", m_score); +    ImGui::Text("HighScore = %d", m_highscore);      if (ImGui::Button("Restart")) { -        m_RunningState = TetrisRunningState::Restart; +        m_game_status = game_starting;      }      if (ImGui::Button("Exit")) { -        m_RunningState = TetrisRunningState::Exit; +        m_game_status = game_exit;      }      ImGui::End();  } -void Tetris::DrawLineCounter() { +void +Tetris::DrawLineCounter() +{      V2F32 view_pos = {0.5f, 2.6f};      ImVec2 screen_pos = g_renderer.ViewPosToScreenPosImGui(view_pos);      ImGui::SetNextWindowPos(screen_pos);      ImGui::Begin("TetrisLines", nullptr, s_DefaultImGuiWindowFlags); -    ImGui::Text("LINES - %d", m_LineCounter); +    ImGui::Text("LINES - %d", m_line_counter);      ImGui::End();  } -void Tetris::DrawStatistics() { +void +Tetris::DrawStatistics() +{      V2F32 view_tetrominoes_pos = {0.4f, 1.8f};      V2F32 view_advance = {0.0f, 0.2f}; @@ -313,36 +310,40 @@ void Tetris::DrawStatistics() {      ImGui::SetNextWindowPos(screen_text_pos);      ImGui::Begin("TetrisStatistics", nullptr, s_DefaultImGuiWindowFlags); -    ImGui::Text("%d", m_TetrominoCounters[Tetromino::t_piece]); +    ImGui::Text("%d", m_tetromino_counters[Tetromino::t_piece]);      ImGui::Dummy(screen_text_gap); -    ImGui::Text("%d", m_TetrominoCounters[Tetromino::j_piece]); +    ImGui::Text("%d", m_tetromino_counters[Tetromino::j_piece]);      ImGui::Dummy(screen_text_gap); -    ImGui::Text("%d", m_TetrominoCounters[Tetromino::z_piece]); +    ImGui::Text("%d", m_tetromino_counters[Tetromino::z_piece]);      ImGui::Dummy(screen_text_gap); -    ImGui::Text("%d", m_TetrominoCounters[Tetromino::o_piece]); +    ImGui::Text("%d", m_tetromino_counters[Tetromino::o_piece]);      ImGui::Dummy(screen_text_gap); -    ImGui::Text("%d", m_TetrominoCounters[Tetromino::s_piece]); +    ImGui::Text("%d", m_tetromino_counters[Tetromino::s_piece]);      ImGui::Dummy(screen_text_gap); -    ImGui::Text("%d", m_TetrominoCounters[Tetromino::l_piece]); +    ImGui::Text("%d", m_tetromino_counters[Tetromino::l_piece]);      ImGui::Dummy(screen_text_gap); -    ImGui::Text("%d", m_TetrominoCounters[Tetromino::i_piece]); +    ImGui::Text("%d", m_tetromino_counters[Tetromino::i_piece]);      ImGui::Dummy(screen_text_gap);      ImGui::End();  } -void Tetris::DrawScore() { +void +Tetris::DrawScore() +{      V2F32 view_pos = {3.0f, 2.2f};      ImVec2 screen_pos = g_renderer.ViewPosToScreenPosImGui(view_pos);      ImGui::SetNextWindowPos(screen_pos);      ImGui::Begin("TetrisScore", nullptr, s_DefaultImGuiWindowFlags);      ImGui::Text("Score"); -    ImGui::Text("%d", m_Score); +    ImGui::Text("%d", m_score);      ImGui::End();  } -void Tetris::DrawNextTetromino() { +void +Tetris::DrawNextTetromino() +{      V2F32 text_view_pos = {3.0f, 1.8f};      ImVec2 text_screen_pos = g_renderer.ViewPosToScreenPosImGui(text_view_pos); @@ -353,17 +354,19 @@ void Tetris::DrawNextTetromino() {      V2F32 tetromino_view_pos = {3.0, 1.4f}; -    Tetromino::Draw(m_NextTetromino.GetId(), 0, tetromino_view_pos, 0.5f); +    Tetromino::Draw(m_next_tetromino.GetId(), 0, tetromino_view_pos, 0.5f);  } -void Tetris::DrawLevel() { +void +Tetris::DrawLevel() +{      V2F32 view_pos = {3.0f, 1.2f};      ImVec2 screen_pos = g_renderer.ViewPosToScreenPosImGui(view_pos);      ImGui::SetNextWindowPos(screen_pos);      ImGui::Begin("TetrisLevel", nullptr, s_DefaultImGuiWindowFlags);      ImGui::Text("Level"); -    ImGui::Text("%d", m_Level); +    ImGui::Text("%d", m_level);      ImGui::End();  } diff --git a/src/games/tetris/Tetris.hpp b/src/games/tetris/Tetris.hpp index e517f1c..b3ace1d 100644 --- a/src/games/tetris/Tetris.hpp +++ b/src/games/tetris/Tetris.hpp @@ -6,27 +6,18 @@  #include <games/tetris/Board.hpp> -enum class TetrisRunningState { -    Resume, -    Pause, -    GameOver, -    Restart, -    Exit -}; - -  class Tetris : public Game {  public: -    Tetris(); +    Tetris() = default;      bool Update(std::vector<SDL_Event> &events) override;      void HandleTetrominoPlacement();  private: -    void Restart(); +    void Start();      void UpdateResumeState(SDL_Event &event);      void UpdatePauseState(SDL_Event &event); -    uint32_t GetHarddropCount(float dt); +    uint32_t GetSoftdropCount(float dt);      void HandleGameOver();      void Draw(); @@ -36,7 +27,6 @@ private:      void DrawNextTetromino();      void DrawLevel(); -    void DrawPauseMenu();      void DrawGameOverMenu();  private: @@ -45,23 +35,18 @@ private:  private: -    TetrisRunningState m_RunningState = TetrisRunningState::Resume; - -    float m_DtInSecondsRemaining = 0.0f; -    uint64_t m_MillisecondsSinceT0Last = SDL_GetTicks(); - -    Board m_Board; -    Tetromino m_ActiveTetromino; -    Tetromino m_NextTetromino; - -    int32_t m_TetrominoCounters[Tetromino::tetromino_id_count] {}; -    int32_t m_Score = 0; -    int32_t m_LineCounter = 0; -    int32_t m_StartingLevel = 0; -    int32_t m_Level = 0; -    int32_t m_SoftdropCounter = 0; - -    int32_t m_HighScore = 0; +    Board m_board; +    Tetromino m_active_tetromino; +    Tetromino m_next_tetromino; + +    int32_t m_tetromino_counters[Tetromino::id_count] {}; +    int32_t m_score = 0; +    int32_t m_line_counter = 0; +    int32_t m_starting_level = 0; +    int32_t m_level = 0; +    int32_t m_softdrop_counter = 0; + +    int32_t m_highscore = 0;  }; diff --git a/src/games/tetris/Tetromino.cpp b/src/games/tetris/Tetromino.cpp index 9179d6d..97c8808 100644 --- a/src/games/tetris/Tetromino.cpp +++ b/src/games/tetris/Tetromino.cpp @@ -59,85 +59,101 @@ static const uint16_t s_left_aligned_bitmaps[7][4][4] = {  }; -Tetromino::TetrominoId Tetromino::GetRandomId() { -    static std::uniform_int_distribution<int> s_Dist(0, tetromino_id_count-1); +Tetromino::TetrominoId Tetromino::GetRandomId() +{ +    static std::uniform_int_distribution<int> s_Dist(0, id_count-1);      static std::mt19937 s_Rng((std::random_device()()));      TetrominoId id = static_cast<TetrominoId>(s_Dist(s_Rng));      return id;  } -Tetromino::Tetromino(uint16_t *board_bitmap) : -    m_Id(GetRandomId()), -    m_Pos{6, 20}, -    m_Ori{0}, -    m_BoardBitmap(board_bitmap) -{ -} -Tetromino::Tetromino(Board &board) : -    Tetromino(board.m_Bitmap) +void +Tetromino::Reinit(uint16_t* board_bitmap)  { +    m_id = GetRandomId(); +    m_pos = {6, 20}; +    m_ori = {0}; +    m_board_bitmap = board_bitmap;  } -Tetromino::TetrominoId Tetromino::GetId() { -    return m_Id; +Tetromino::TetrominoId +Tetromino::GetId() +{ +    return m_id;  } -BoardPos Tetromino::GetPos() { -    return m_Pos; +BoardPos +Tetromino::GetPos() +{ +    return m_pos;  } -void Tetromino::GetBitmap(uint16_t *bitmap) { -    GetBitmap(m_Id, m_Pos, m_Ori, bitmap); +void +Tetromino::GetBitmap(uint16_t* bitmap) +{ +    GetBitmap(m_id, m_pos, m_ori, bitmap);  } -bool Tetromino::IsCollisionWithBoard() { -    bool is_collision = IsCollisionWithBoard(m_Id, m_Pos, m_Ori, m_BoardBitmap); +bool +Tetromino::IsCollisionWithBoard() +{ +    bool is_collision = IsCollisionWithBoard(m_id, m_pos, m_ori, m_board_bitmap);      return is_collision;  } -void Tetromino::MaybeRotate(TetrominoRotation rotation) { -    int32_t ori = (m_Ori + rotation) % 4; -    if (!IsCollisionWithBoard(m_Id, m_Pos, ori, m_BoardBitmap)) { -        m_Ori = ori; +void +Tetromino::MaybeRotate(TetrominoRotation rotation) +{ +    int32_t ori = (m_ori + rotation) % 4; +    if (!IsCollisionWithBoard(m_id, m_pos, ori, m_board_bitmap)) { +        m_ori = ori;      }  } -void Tetromino::MaybeMoveHorizontally(TetrominoDirection direction) { -    BoardPos pos = m_Pos; +void +Tetromino::MaybeMoveHorizontally(TetrominoDirection direction) +{ +    BoardPos pos = m_pos;      pos.x += static_cast<int32_t>(direction); -    if (!IsCollisionWithBoard(m_Id, pos, m_Ori, m_BoardBitmap)) { -        m_Pos.x = pos.x; +    if (!IsCollisionWithBoard(m_id, pos, m_ori, m_board_bitmap)) { +        m_pos.x = pos.x;      }  } -bool Tetromino::MaybeMoveDown() { -    BoardPos pos = m_Pos; +bool +Tetromino::MaybeMoveDown() +{ +    BoardPos pos = m_pos;      pos.y -= 1; -    if (!IsCollisionWithBoard(m_Id, pos, m_Ori, m_BoardBitmap)) { -        m_Pos.y = pos.y; +    if (!IsCollisionWithBoard(m_id, pos, m_ori, m_board_bitmap)) { +        m_pos.y = pos.y;          return true;      }      return false;  } -void Tetromino::Draw() const { +void +Tetromino::Draw() +{      float world_width = 4.0f;      float world_height = 3.0f;      float tetromino_size_with_border = world_height / 20.0f; -    float x0 = static_cast<float>(m_Pos.x - 3); -    float y0 = static_cast<float>(m_Pos.y - 2); +    float x0 = static_cast<float>(m_pos.x - 3); +    float y0 = static_cast<float>(m_pos.y - 2);      V2F32 world_pos = {          ((world_width - tetromino_size_with_border*10) / 2.0f) + x0 * tetromino_size_with_border,          y0 * tetromino_size_with_border      }; -    Tetromino::Draw(m_Id, m_Ori, world_pos, 1.0f); +    Tetromino::Draw(m_id, m_ori, world_pos, 1.0f);  } -bool Tetromino::IsCollisionWithBoard(TetrominoId id, BoardPos pos, int32_t ori, uint16_t *board_bitmap) { +bool +Tetromino::IsCollisionWithBoard(TetrominoId id, BoardPos pos, int32_t ori, uint16_t *board_bitmap) +{      uint16_t tetromino_bitmap[16];      GetBitmap(id, pos, ori, tetromino_bitmap); @@ -147,14 +163,18 @@ bool Tetromino::IsCollisionWithBoard(TetrominoId id, BoardPos pos, int32_t ori,      return is_collision;  } -void Tetromino::GetBitmap(TetrominoId id, BoardPos pos, int32_t ori, uint16_t *bitmap) { +void +Tetromino::GetBitmap(TetrominoId id, BoardPos pos, int32_t ori, uint16_t *bitmap) +{      size_t id_ = static_cast<size_t>(id);      uint64_t *src  = (uint64_t*)s_left_aligned_bitmaps[id_][ori];      uint64_t *dest = (uint64_t*)bitmap;      *dest = *src >> pos.x;  } -Color Tetromino::GetColor(TetrominoId id) { +Color +Tetromino::GetColor(TetrominoId id) +{      using enum TetrominoId;      Color color; @@ -179,7 +199,9 @@ Color Tetromino::GetColor(TetrominoId id) {      return color;  } -void Tetromino::Draw(TetrominoId id, int32_t ori, V2F32 pos, float scale) { +void +Tetromino::Draw(TetrominoId id, int32_t ori, V2F32 pos, float scale) +{      int32_t id_ = static_cast<int32_t>(id);      float world_height = 3.0f; diff --git a/src/games/tetris/Tetromino.hpp b/src/games/tetris/Tetromino.hpp index 88f71f5..b40555b 100644 --- a/src/games/tetris/Tetromino.hpp +++ b/src/games/tetris/Tetromino.hpp @@ -15,8 +15,8 @@ public:          l_piece,          j_piece,          i_piece, -        tetromino_id_count, -        tetromino_id_none, +        id_count, +        id_none,      };      enum TetrominoRotation { @@ -31,21 +31,19 @@ public:  public: -    Tetromino() = delete; -    Tetromino(Board &board); -    Tetromino(uint16_t *board_bitmap); +    void Reinit(uint16_t* board_bitmap);      TetrominoId GetId();      BoardPos GetPos();      int32_t GetOri();      void GetBitmap(uint16_t *bitmap); -    bool IsCollisionWithBoard(); // for last tetromino to check game over +    bool IsCollisionWithBoard();      bool MaybeMoveDown();      void MaybeMoveHorizontally(TetrominoDirection direction);      void MaybeRotate(TetrominoRotation rotation); -    void Draw() const; +    void Draw();  public: @@ -60,9 +58,9 @@ private:  private: -    TetrominoId m_Id; -    BoardPos m_Pos; -    int32_t m_Ori; -    uint16_t *m_BoardBitmap; +    TetrominoId m_id; +    BoardPos m_pos; +    int32_t m_ori; +    uint16_t *m_board_bitmap;  };  | 
