Clean code
This commit is contained in:
parent
3257e534c3
commit
5b8b0f8fb8
|
@ -61,14 +61,13 @@ void Application::onGameState(sf::Event& event)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sf::Event::KeyPressed:
|
case sf::Event::KeyPressed:
|
||||||
// Go to selection mode
|
|
||||||
if (event.key.code == sf::Keyboard::Z)
|
if (event.key.code == sf::Keyboard::Z)
|
||||||
board.onSelectionMode();
|
board.onSelectionMode();
|
||||||
else // if it wasn't selection mode, then try to handle direction
|
else
|
||||||
board.moveSelection(getDirection(event.key.code));
|
board.tryProcessDirection(getDirection(event.key.code));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // otherwise - do nothing
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
192
board.cpp
192
board.cpp
|
@ -28,32 +28,43 @@ Board::~Board()
|
||||||
|
|
||||||
bool Board::init(const std::string& path, int splitting, const sf::RenderWindow &window)
|
bool Board::init(const std::string& path, int splitting, const sf::RenderWindow &window)
|
||||||
{
|
{
|
||||||
// PREPARING INITIAL BOARD STATE //
|
|
||||||
|
|
||||||
if (!global_texture.loadFromFile(path) )
|
if (!global_texture.loadFromFile(path) )
|
||||||
return false;
|
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 width = global_texture.getSize().x;
|
||||||
const int height = global_texture.getSize().y;
|
const int height = global_texture.getSize().y;
|
||||||
|
|
||||||
Cell::side_length = (width < height) ? width / splitting : height / splitting;
|
Cell::side_length = (width < height) ? width / splitting : height / splitting;
|
||||||
cells_on_height = height / Cell::side_length;
|
cells_on_height = height / Cell::side_length;
|
||||||
cells_on_width = width / 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;
|
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<float>(y), static_cast<float>(x));
|
sp->setPosition(static_cast<float>(y), static_cast<float>(x));
|
||||||
|
|
||||||
vec_field.push_back(new Cell({index, index, sp}));
|
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.;
|
float scaling = 0.;
|
||||||
if (width >= height && width > static_cast<int>(window.getSize().x))
|
if (texture_width >= texture_height && texture_width > static_cast<int>(window.getSize().x))
|
||||||
scaling = static_cast<float>(window.getSize().x) / static_cast<float>(width);
|
scaling = static_cast<float>(window.getSize().x) / static_cast<float>(texture_width);
|
||||||
if (height >= width && height > static_cast<int>(window.getSize().y))
|
if (texture_height >= texture_width && texture_height > static_cast<int>(window.getSize().y))
|
||||||
scaling = static_cast<float>(window.getSize().y) / static_cast<float>(height);
|
scaling = static_cast<float>(window.getSize().y) / static_cast<float>(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<int>(static_cast<float>(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
|
vec_field[i]->sprite->scale(scaling, scaling);
|
||||||
int old_side_length = Cell::side_length;
|
|
||||||
Cell::side_length = static_cast<int>(static_cast<float>(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<float>(shift) * static_cast<float>((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<float>(shift) * static_cast<float>(i / cells_on_width);
|
|
||||||
|
|
||||||
vec_field[i]->sprite->scale(scaling, scaling);
|
|
||||||
vec_field[i]->sprite->move(move_x, move_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const auto shift_vector = calculateTileShiftVector(i, shift);
|
||||||
|
vec_field[i]->sprite->move(shift_vector.first, shift_vector.second);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<float, float> 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<float>(shift) * static_cast<float>((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<float>(shift) * static_cast<float>(tile_index / cells_on_width);
|
||||||
|
|
||||||
|
return {move_x, move_y};
|
||||||
|
}
|
||||||
|
|
||||||
|
void Board::shuffleTiles()
|
||||||
|
{
|
||||||
solved_tiles = vec_field.size(); // all tiles are solved for now
|
solved_tiles = vec_field.size(); // all tiles are solved for now
|
||||||
|
|
||||||
srand(static_cast<unsigned int>(time(nullptr)));
|
srand(static_cast<unsigned int>(time(nullptr)));
|
||||||
|
@ -112,11 +143,6 @@ bool Board::init(const std::string& path, int splitting, const sf::RenderWindow
|
||||||
|
|
||||||
swapCells(curr_i, swap_i);
|
swapCells(curr_i, swap_i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set initial position of cursor
|
|
||||||
setSelectionVertex(selection_index);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Board::draw(sf::RenderWindow& window)
|
void Board::draw(sf::RenderWindow& window)
|
||||||
|
@ -131,48 +157,56 @@ void Board::draw(sf::RenderWindow& window)
|
||||||
window.draw(rect_selection);
|
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)
|
bool Board::moveSelection(const DIRECTION &direction)
|
||||||
{
|
{
|
||||||
if (!on_selection)
|
switch (direction) {
|
||||||
{
|
case DIRECTION::UP:
|
||||||
switch (direction) {
|
if (selection_index < cells_on_width) // if upper row
|
||||||
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:
|
|
||||||
return false;
|
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) {
|
switch (direction) {
|
||||||
case DIRECTION::UP:
|
case DIRECTION::UP:
|
||||||
if (selection_index < cells_on_width) // if upper row
|
if (selection_index < cells_on_width) // if upper row
|
||||||
|
@ -291,4 +325,4 @@ void Board::setCursorVisibility(bool visible)
|
||||||
is_cursor_visible = visible;
|
is_cursor_visible = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Board::Cell::side_length = 0;
|
int Board::Cell::side_length = 1;
|
||||||
|
|
26
board.h
26
board.h
|
@ -27,27 +27,20 @@ public:
|
||||||
explicit Board();
|
explicit Board();
|
||||||
~Board();
|
~Board();
|
||||||
|
|
||||||
// Set play image
|
|
||||||
bool init(const std::string& path, int splitting, const sf::RenderWindow& window);
|
bool init(const std::string& path, int splitting, const sf::RenderWindow& window);
|
||||||
|
|
||||||
// Output current graphical state on application window
|
|
||||||
void draw(sf::RenderWindow& 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 moveSelection(const DIRECTION& direction);
|
||||||
|
bool swapOnSelection(const DIRECTION& direction);
|
||||||
|
|
||||||
// Go to or leave from selection mode
|
// Go to or leave from selection mode
|
||||||
void onSelectionMode();
|
void onSelectionMode();
|
||||||
|
|
||||||
// Did player win the game
|
|
||||||
bool isWinCondition() const;
|
|
||||||
|
|
||||||
// Show or hide selection cursos
|
|
||||||
void setCursorVisibility(bool visible = false);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Game tile
|
|
||||||
struct Cell
|
struct Cell
|
||||||
{
|
{
|
||||||
std::vector<Cell*>::size_type inital_index;
|
std::vector<Cell*>::size_type inital_index;
|
||||||
|
@ -76,4 +69,15 @@ private:
|
||||||
|
|
||||||
// Draw selection cursor on given tile
|
// Draw selection cursor on given tile
|
||||||
void setSelectionVertex(Cells::size_type index);
|
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<float, float> calculateTileShiftVector(Cells::size_type tile_index, int shift) const;
|
||||||
|
|
||||||
|
void shuffleTiles();
|
||||||
};
|
};
|
||||||
|
|
2
main.cpp
2
main.cpp
|
@ -99,7 +99,7 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const auto&[ret_code, splitting, resolution, path] = parseInput(argc, 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;
|
return ret_code;
|
||||||
|
|
||||||
Application app(resolution.x, resolution.y);
|
Application app(resolution.x, resolution.y);
|
||||||
|
|
Loading…
Reference in New Issue