From 5b8b0f8fb8a41f463101a431ab09bae8b141a957 Mon Sep 17 00:00:00 2001 From: NaiJi Date: Wed, 24 Mar 2021 17:19:55 +0300 Subject: [PATCH] Clean code --- application.cpp | 7 +- board.cpp | 192 ++++++++++++++++++++++++++++-------------------- board.h | 26 ++++--- main.cpp | 2 +- 4 files changed, 132 insertions(+), 95 deletions(-) diff --git a/application.cpp b/application.cpp index a70e43d..fb19661 100644 --- a/application.cpp +++ b/application.cpp @@ -61,14 +61,13 @@ void Application::onGameState(sf::Event& event) break; case sf::Event::KeyPressed: - // Go to selection mode if (event.key.code == sf::Keyboard::Z) board.onSelectionMode(); - else // if it wasn't selection mode, then try to handle direction - board.moveSelection(getDirection(event.key.code)); + else + board.tryProcessDirection(getDirection(event.key.code)); break; - default: // otherwise - do nothing + default: break; } diff --git a/board.cpp b/board.cpp index 9119394..9671c1d 100644 --- a/board.cpp +++ b/board.cpp @@ -28,32 +28,43 @@ Board::~Board() bool Board::init(const std::string& path, int splitting, const sf::RenderWindow &window) { - // PREPARING INITIAL BOARD STATE // - if (!global_texture.loadFromFile(path) ) return false; + calculateBoardProperties(splitting); + splitImageIntoTiles(Cell::side_length); + scaleImageToWindow(window); + shuffleTiles(); + setSelectionVertex(selection_index); + + return true; +} + +void Board::calculateBoardProperties(int splitting) +{ const int width = global_texture.getSize().x; const int height = global_texture.getSize().y; Cell::side_length = (width < height) ? width / splitting : height / splitting; cells_on_height = height / Cell::side_length; cells_on_width = width / Cell::side_length; +} - vec_field.reserve(cells_on_height * cells_on_width); +void Board::splitImageIntoTiles(int tile_length) +{ + const int width = global_texture.getSize().x; + const int height = global_texture.getSize().y; - /* Iterating board cells' screen positions. - * The initial image after this would look exactly like the loaded picture, not shuffled yet. */ Cells::size_type index = 0; - for (int x = 0; x < height; x += Cell::side_length) + for (int x = 0; x < height; x += tile_length) { - if ((height - x) >= Cell::side_length) + if ((height - x) >= tile_length) { - for (int y = 0; y < width; y += Cell::side_length) + for (int y = 0; y < width; y += tile_length) { - if ((width - y) >= Cell::side_length) + if ((width - y) >= tile_length) { - sf::Sprite* sp = new sf::Sprite(global_texture, sf::IntRect(y, x, Cell::side_length, Cell::side_length)); + sf::Sprite* sp = new sf::Sprite(global_texture, sf::IntRect(y, x, tile_length, tile_length)); sp->setPosition(static_cast(y), static_cast(x)); vec_field.push_back(new Cell({index, index, sp})); @@ -62,43 +73,63 @@ bool Board::init(const std::string& path, int splitting, const sf::RenderWindow } } } +} - // SCALING // +void Board::scaleImageToWindow(const sf::RenderWindow &window) +{ + float scaling = calculateScalingToWindow(window); + scaleTiles(scaling); +} + +float Board::calculateScalingToWindow(const sf::RenderWindow &window) const +{ + int texture_width = global_texture.getSize().x; + int texture_height = global_texture.getSize().y; float scaling = 0.; - if (width >= height && width > static_cast(window.getSize().x)) - scaling = static_cast(window.getSize().x) / static_cast(width); - if (height >= width && height > static_cast(window.getSize().y)) - scaling = static_cast(window.getSize().y) / static_cast(height); + if (texture_width >= texture_height && texture_width > static_cast(window.getSize().x)) + scaling = static_cast(window.getSize().x) / static_cast(texture_width); + if (texture_height >= texture_width && texture_height > static_cast(window.getSize().y)) + scaling = static_cast(window.getSize().y) / static_cast(texture_height); - if (scaling != 0.) + return scaling; +} + +void Board::scaleTiles(float scaling) +{ + if (scaling == 0.) + return; + + int old_side_length = Cell::side_length; + Cell::side_length = static_cast(static_cast(Cell::side_length) * scaling); + int shift = Cell::side_length - old_side_length; + + for (Cells::size_type i = 0; i < vec_field.size(); ++i) { - // Calculating new size of each tile - int old_side_length = Cell::side_length; - Cell::side_length = static_cast(static_cast(Cell::side_length) * scaling); - int shift = Cell::side_length - old_side_length; - float move_x, move_y; - // Moving all scaled tiles up and left, to remove spacing - for (Cells::size_type i = 0; i < vec_field.size(); ++i) - { - move_x = 0.f; - move_y = 0.f; - // The first column isn't allowed to move by x - if (!(((i % cells_on_width == 0) && (i >= cells_on_width)))) - move_x = static_cast(shift) * static_cast((i < cells_on_width) ? i : i % cells_on_width); - // The first row isn't allowed to move by y - if (i >= cells_on_width) - move_y = static_cast(shift) * static_cast(i / cells_on_width); - - vec_field[i]->sprite->scale(scaling, scaling); - vec_field[i]->sprite->move(move_x, move_y); - } + vec_field[i]->sprite->scale(scaling, scaling); + const auto shift_vector = calculateTileShiftVector(i, shift); + vec_field[i]->sprite->move(shift_vector.first, shift_vector.second); } +} +std::pair Board::calculateTileShiftVector(Cells::size_type tile_index, int shift) const +{ + float move_x = 0.f, move_y = 0.f; - // SHUFFLING // + // The first column isn't allowed to move by x + if (!(((tile_index % cells_on_width == 0) && (tile_index >= cells_on_width)))) + move_x = static_cast(shift) * static_cast((tile_index < cells_on_width) ? tile_index : tile_index % cells_on_width); + // The first row isn't allowed to move by y + if (tile_index >= cells_on_width) + move_y = static_cast(shift) * static_cast(tile_index / cells_on_width); + + return {move_x, move_y}; +} + +void Board::shuffleTiles() +{ solved_tiles = vec_field.size(); // all tiles are solved for now srand(static_cast(time(nullptr))); @@ -112,11 +143,6 @@ bool Board::init(const std::string& path, int splitting, const sf::RenderWindow swapCells(curr_i, swap_i); } - - // Set initial position of cursor - setSelectionVertex(selection_index); - - return true; } void Board::draw(sf::RenderWindow& window) @@ -131,48 +157,56 @@ void Board::draw(sf::RenderWindow& window) window.draw(rect_selection); } +bool Board::tryProcessDirection(const DIRECTION &direction) +{ + if (on_selection) + return swapOnSelection(direction); + + return moveSelection(direction); +} + bool Board::moveSelection(const DIRECTION &direction) { - if (!on_selection) - { - switch (direction) { - case DIRECTION::UP: - if (selection_index < cells_on_width) // if upper row - return false; - selection_index -= cells_on_width; - setSelectionVertex(selection_index); - break; - - case DIRECTION::DOWN: - if (selection_index >= (cells_on_width * (cells_on_height - 1))) // if bottom row - return false; - selection_index += cells_on_width; - setSelectionVertex(selection_index); - break; - - case DIRECTION::RIGHT: - ++selection_index; - if (selection_index == vec_field.size()) // if the last cell of right bottom corner - selection_index = 0; // move to the first cell of upper left corner - setSelectionVertex(selection_index); - break; - - case DIRECTION::LEFT: - if (selection_index == 0) // if the first cell of of upper left corner - selection_index = vec_field.size() - 1; // move to the last cell of right bottom corner - else - --selection_index; - setSelectionVertex(selection_index); - break; - - default: + switch (direction) { + case DIRECTION::UP: + if (selection_index < cells_on_width) // if upper row return false; - break; - } + selection_index -= cells_on_width; + setSelectionVertex(selection_index); + break; - return true; + case DIRECTION::DOWN: + if (selection_index >= (cells_on_width * (cells_on_height - 1))) // if bottom row + return false; + selection_index += cells_on_width; + setSelectionVertex(selection_index); + break; + + case DIRECTION::RIGHT: + ++selection_index; + if (selection_index == vec_field.size()) // if the last cell of right bottom corner + selection_index = 0; // move to the first cell of upper left corner + setSelectionVertex(selection_index); + break; + + case DIRECTION::LEFT: + if (selection_index == 0) // if the first cell of of upper left corner + selection_index = vec_field.size() - 1; // move to the last cell of right bottom corner + else + --selection_index; + setSelectionVertex(selection_index); + break; + + default: + return false; + break; } + return true; +} + +bool Board::swapOnSelection(const DIRECTION &direction) +{ switch (direction) { case DIRECTION::UP: if (selection_index < cells_on_width) // if upper row @@ -291,4 +325,4 @@ void Board::setCursorVisibility(bool visible) is_cursor_visible = visible; } -int Board::Cell::side_length = 0; +int Board::Cell::side_length = 1; diff --git a/board.h b/board.h index 285d5db..560b8e4 100644 --- a/board.h +++ b/board.h @@ -27,27 +27,20 @@ public: explicit Board(); ~Board(); - // Set play image bool init(const std::string& path, int splitting, const sf::RenderWindow& window); - - // Output current graphical state on application window void draw(sf::RenderWindow& window); + bool isWinCondition() const; - // Move cursor to next tile by given direction + void setCursorVisibility(bool visible); + bool tryProcessDirection(const DIRECTION& direction); bool moveSelection(const DIRECTION& direction); + bool swapOnSelection(const DIRECTION& direction); // Go to or leave from selection mode void onSelectionMode(); - // Did player win the game - bool isWinCondition() const; - - // Show or hide selection cursos - void setCursorVisibility(bool visible = false); - private: - // Game tile struct Cell { std::vector::size_type inital_index; @@ -76,4 +69,15 @@ private: // Draw selection cursor on given tile void setSelectionVertex(Cells::size_type index); + + void calculateBoardProperties(int splitting); + + void splitImageIntoTiles(int tile_length); + + void scaleImageToWindow(const sf::RenderWindow &window); + float calculateScalingToWindow(const sf::RenderWindow &window) const; + void scaleTiles(float scaling); + std::pair calculateTileShiftVector(Cells::size_type tile_index, int shift) const; + + void shuffleTiles(); }; diff --git a/main.cpp b/main.cpp index cbcfb6b..25e6271 100644 --- a/main.cpp +++ b/main.cpp @@ -99,7 +99,7 @@ int main(int argc, char **argv) { const auto&[ret_code, splitting, resolution, path] = parseInput(argc, argv); - if (ret_code) // Error code is EXIT_FAILURE + if (ret_code) return ret_code; Application app(resolution.x, resolution.y);