Add -r support
This commit is contained in:
parent
5a8fbddd93
commit
8f8c2918f3
|
@ -4,14 +4,14 @@
|
||||||
// Hardcoded for now
|
// Hardcoded for now
|
||||||
const sf::Time TIME_PER_SECOND = sf::seconds(1.f / 60.f);
|
const sf::Time TIME_PER_SECOND = sf::seconds(1.f / 60.f);
|
||||||
|
|
||||||
Application::Application() :
|
Application::Application(unsigned int window_width, unsigned int window_height) :
|
||||||
render_window({SCREEN_WIDTH, SCREEN_HEIGHT}, "Sliding Puzzle")
|
render_window({window_width, window_height}, "Sliding Puzzle")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool Application::init(const std::string &path, int splitting)
|
bool Application::init(const std::string &path, int splitting)
|
||||||
{
|
{
|
||||||
render_window.setFramerateLimit(60);
|
render_window.setFramerateLimit(60);
|
||||||
return board.init(path, splitting);
|
return board.init(path, splitting, render_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::run()
|
void Application::run()
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
class Application
|
class Application
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Application();
|
explicit Application(unsigned int window_width, unsigned int window_height);
|
||||||
|
|
||||||
// Init game
|
// Init game
|
||||||
bool init(const std::string& path, int splitting);
|
bool init(const std::string& path, int splitting);
|
||||||
|
|
19
board.cpp
19
board.cpp
|
@ -157,7 +157,7 @@ bool Board::isWinCondition() const
|
||||||
return std::all_of(vec_field.begin(), vec_field.end(), [](const Cell *cell){ return cell->current_index == cell->inital_index; });
|
return std::all_of(vec_field.begin(), vec_field.end(), [](const Cell *cell){ return cell->current_index == cell->inital_index; });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Board::init(const std::string& path, int splitting)
|
bool Board::init(const std::string& path, int splitting, const sf::RenderWindow &window)
|
||||||
{
|
{
|
||||||
// PREPARING INITIAL BOARD STATE //
|
// PREPARING INITIAL BOARD STATE //
|
||||||
|
|
||||||
|
@ -197,24 +197,27 @@ bool Board::init(const std::string& path, int splitting)
|
||||||
// SCALING //
|
// SCALING //
|
||||||
|
|
||||||
float scaling = 0.;
|
float scaling = 0.;
|
||||||
if (width > height && width > SCREEN_WIDTH)
|
if (width >= height && width > static_cast<int>(window.getSize().x))
|
||||||
scaling = static_cast<float>(SCREEN_WIDTH) / static_cast<float>(width);
|
scaling = static_cast<float>(window.getSize().x) / static_cast<float>(width);
|
||||||
if (height > width && height > SCREEN_HEIGHT)
|
if (height >= width && height > static_cast<int>(window.getSize().y))
|
||||||
scaling = static_cast<float>(SCREEN_HEIGHT) / static_cast<float>(height);
|
scaling = static_cast<float>(window.getSize().y) / static_cast<float>(height);
|
||||||
|
|
||||||
if (scaling != 0.)
|
if (scaling != 0.)
|
||||||
{
|
{
|
||||||
|
// Calculating new size of each tile
|
||||||
int old_side_length = Cell::side_length;
|
int old_side_length = Cell::side_length;
|
||||||
Cell::side_length = static_cast<int>(static_cast<float>(Cell::side_length) * scaling);
|
Cell::side_length = static_cast<int>(static_cast<float>(Cell::side_length) * scaling);
|
||||||
int shift = Cell::side_length - old_side_length;
|
int shift = Cell::side_length - old_side_length;
|
||||||
float move_x = 0.f;
|
float move_x, move_y;
|
||||||
float move_y = 0.f;
|
// Moving all scaled tiles up and left, to remove spacing
|
||||||
for (Cells::size_type i = 0; i < vec_field.size(); ++i)
|
for (Cells::size_type i = 0; i < vec_field.size(); ++i)
|
||||||
{
|
{
|
||||||
move_x = 0.f;
|
move_x = 0.f;
|
||||||
move_y = 0.f;
|
move_y = 0.f;
|
||||||
if (!(((i % cells_on_width == 0) && (i >= cells_on_width)) || i == 0))
|
// 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);
|
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)
|
if (i >= cells_on_width)
|
||||||
move_y = static_cast<float>(shift) * static_cast<float>(i / cells_on_width);
|
move_y = static_cast<float>(shift) * static_cast<float>(i / cells_on_width);
|
||||||
|
|
||||||
|
|
5
board.h
5
board.h
|
@ -8,9 +8,6 @@
|
||||||
|
|
||||||
using pos = std::pair<int, int>;
|
using pos = std::pair<int, int>;
|
||||||
|
|
||||||
constexpr int SCREEN_WIDTH = 1600;
|
|
||||||
constexpr int SCREEN_HEIGHT = 900;
|
|
||||||
|
|
||||||
enum class DIRECTION
|
enum class DIRECTION
|
||||||
{
|
{
|
||||||
UP,
|
UP,
|
||||||
|
@ -42,7 +39,7 @@ public:
|
||||||
bool isWinCondition() const;
|
bool isWinCondition() const;
|
||||||
|
|
||||||
// Set play image
|
// Set play image
|
||||||
bool init(const std::string& path, int splitting);
|
bool init(const std::string& path, int splitting, const sf::RenderWindow& window);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,13 @@
|
||||||
|
|
||||||
namespace filepath
|
namespace filepath
|
||||||
{
|
{
|
||||||
static std::tuple<std::filesystem::path, std::filesystem::file_status> getFileInfo(const std::filesystem::directory_entry& entry)
|
std::tuple<std::filesystem::path, std::filesystem::file_status> getFileInfo(const std::filesystem::directory_entry& entry)
|
||||||
{
|
{
|
||||||
const auto file_status (std::filesystem::status(entry));
|
const auto file_status (std::filesystem::status(entry));
|
||||||
return {entry.path(), file_status};
|
return {entry.path(), file_status};
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool endsWith(const std::string& string, const std::string& ending)
|
bool endsWith(const std::string& string, const std::string& ending)
|
||||||
{
|
{
|
||||||
if (ending.size() > string.size())
|
if (ending.size() > string.size())
|
||||||
return false;
|
return false;
|
||||||
|
@ -25,7 +25,7 @@ namespace filepath
|
||||||
return std::equal(ending.rbegin(), ending.rend(), string.rbegin());
|
return std::equal(ending.rbegin(), ending.rend(), string.rbegin());
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::tuple<int, std::string> parsePath(const std::string &argv)
|
std::tuple<int, std::string> parsePath(const std::string &argv)
|
||||||
{
|
{
|
||||||
std::filesystem::path path(argv);
|
std::filesystem::path path(argv);
|
||||||
if (!std::filesystem::exists(path))
|
if (!std::filesystem::exists(path))
|
||||||
|
@ -67,4 +67,16 @@ namespace filepath
|
||||||
srand(static_cast<unsigned int>(time(nullptr)));
|
srand(static_cast<unsigned int>(time(nullptr)));
|
||||||
return {EXIT_SUCCESS, dir_image_items[rand() & (dir_image_items.size() - 1)]};
|
return {EXIT_SUCCESS, dir_image_items[rand() & (dir_image_items.size() - 1)]};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> split(const std::string &s, char delim)
|
||||||
|
{
|
||||||
|
std::vector<std::string> result;
|
||||||
|
std::stringstream ss (s);
|
||||||
|
std::string item;
|
||||||
|
|
||||||
|
while (getline(ss, item, delim))
|
||||||
|
result.push_back(item);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
109
main.cpp
109
main.cpp
|
@ -6,96 +6,103 @@
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static constexpr int NO_ARGC = 1;
|
static constexpr int DEFAULT_SCREEN_WIDTH = 1280;
|
||||||
static constexpr int MIN_ARGC = 2;
|
static constexpr int DEFAULT_SCREEN_HEIGHT = 720;
|
||||||
static constexpr int MAX_ARGC = 4;
|
static constexpr int DEFAULT_SPLITTING = 4;
|
||||||
static constexpr int DEFAULT_SPLITTING = 5;
|
|
||||||
static const std::string DEFAULT_PATH = "."; // current folder, I guess
|
static const std::string DEFAULT_PATH = "."; // current folder, I guess
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static std::tuple<int, int, std::string> error(const char* msg)
|
std::tuple<int, int, sf::Vector2i, std::string> error(const char* msg)
|
||||||
{
|
{
|
||||||
std::cout << msg;
|
std::cout << msg;
|
||||||
return {EXIT_FAILURE, -1, {}};
|
return {EXIT_FAILURE, -1, {}, {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::tuple<int, int, std::string> parseInput(int argc, char **argv)
|
std::tuple<int, int, sf::Vector2i, std::string> parseInput(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int splitting = DEFAULT_SPLITTING;
|
int splitting = DEFAULT_SPLITTING;
|
||||||
|
sf::Vector2i resolution(DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT);
|
||||||
std::string path = DEFAULT_PATH;
|
std::string path = DEFAULT_PATH;
|
||||||
|
|
||||||
switch (argc)
|
for (int current_arg = 1; current_arg < argc; ++current_arg) // current_arg = 0 is executable name
|
||||||
{
|
{
|
||||||
default:
|
if (strcmp(argv[current_arg], output::HELP_FLAG) == 0) // --help
|
||||||
return error(output::NO_ARG_MSG);
|
|
||||||
|
|
||||||
case NO_ARGC:
|
|
||||||
{
|
|
||||||
// Just launch the application with default parameters
|
|
||||||
std::cout << "No arguments given. Launching at \"" << DEFAULT_PATH << "\" with splitting " << std::to_string(DEFAULT_SPLITTING) << "\n"
|
|
||||||
<< "--help for more information.\n";
|
|
||||||
const auto &[ret_code, ret_path] = filepath::parsePath(DEFAULT_PATH);
|
|
||||||
|
|
||||||
if (ret_code)
|
|
||||||
return error(output::IMG_FAIL_MSG);
|
|
||||||
|
|
||||||
path = ret_path;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MIN_ARGC:
|
|
||||||
{
|
|
||||||
// maybe --help
|
|
||||||
if (strcmp(argv[1], output::HELP_FLAG) == 0)
|
|
||||||
return error(output::HELP_MSG);
|
return error(output::HELP_MSG);
|
||||||
|
|
||||||
const auto &[ret_code, ret_path] = filepath::parsePath(argv[1]);
|
if (strcmp(argv[current_arg], output::SPLITTING_FLAG) == 0) // -s num
|
||||||
|
|
||||||
if (ret_code)
|
|
||||||
return error(output::IMG_FAIL_MSG);
|
|
||||||
|
|
||||||
path = ret_path;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (MAX_ARGC - 1):
|
|
||||||
case MAX_ARGC:
|
|
||||||
{
|
|
||||||
// full stack
|
|
||||||
if (strcmp(argv[1], output::SPLITTING_FLAG) == 0)
|
|
||||||
{
|
{
|
||||||
|
const int value_rg = current_arg + 1;
|
||||||
|
if (value_rg == argc) // is '-s' is the last argument
|
||||||
|
return error(output::SPLITTING_MSG);
|
||||||
|
|
||||||
splitting = -1; // here assuming user is providing it on their own
|
splitting = -1; // here assuming user is providing it on their own
|
||||||
if (std::isdigit(*argv[2]))
|
if (std::isdigit(*argv[value_rg]))
|
||||||
splitting = std::stoi(argv[2]);
|
splitting = std::stoi(argv[value_rg]);
|
||||||
|
|
||||||
if (splitting < 2)
|
if (splitting < 2)
|
||||||
return error(output::SPLITTING_MSG);
|
return error(output::SPLITTING_MSG);
|
||||||
|
|
||||||
const auto &[ret_code, ret_path] = filepath::parsePath(argc == MAX_ARGC ? argv[3] : DEFAULT_PATH);
|
++current_arg; // skipping value after flag to not check it once again
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[current_arg], output::RESOLUTION_FLAG) == 0) // -r numxnum
|
||||||
|
{
|
||||||
|
const int value_rg = current_arg + 1;
|
||||||
|
if (value_rg == argc) // is '-s' is the last argument
|
||||||
|
return error(output::RESOLUTION_MSG);
|
||||||
|
|
||||||
|
std::vector<std::string> res = filepath::split(argv[value_rg], 'x'); // splitting argument by 'x' as in 600x900
|
||||||
|
|
||||||
|
if (res.size() < 2)
|
||||||
|
return error(output::RESOLUTION_MSG);
|
||||||
|
|
||||||
|
resolution = {-1, -1};
|
||||||
|
|
||||||
|
if (std::isdigit(*res[0].c_str()) && std::isdigit(*res[1].c_str()))
|
||||||
|
resolution = {std::stoi(res[0].c_str()), std::stoi(res[1].c_str())};
|
||||||
|
|
||||||
|
if (resolution.x < 1 || resolution.y < 1)
|
||||||
|
return error(output::RESOLUTION_MSG);
|
||||||
|
|
||||||
|
++current_arg; // skipping value after flag to not check it once again
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing else, then assuming it's filepath or folderpath
|
||||||
|
const auto &[ret_code, ret_path] = filepath::parsePath(argv[current_arg]);
|
||||||
|
|
||||||
if (ret_code)
|
if (ret_code)
|
||||||
return error(output::IMG_FAIL_MSG);
|
return error(output::IMG_FAIL_MSG);
|
||||||
|
|
||||||
path = ret_path;
|
path = ret_path;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
if (path == DEFAULT_PATH)
|
||||||
|
{
|
||||||
|
// no path was give, loading random image from '.'
|
||||||
|
const auto &[ret_code, ret_path] = filepath::parsePath(path);
|
||||||
|
|
||||||
|
if (ret_code)
|
||||||
|
return error(output::IMG_FAIL_MSG);
|
||||||
|
|
||||||
|
path = ret_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {EXIT_SUCCESS, splitting, path};
|
return {EXIT_SUCCESS, splitting, resolution, path};
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const auto&[ret_code, splitting, 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) // Error code is EXIT_FAILURE
|
||||||
return ret_code;
|
return ret_code;
|
||||||
|
|
||||||
Application app;
|
Application app(resolution.x, resolution.y);
|
||||||
if (app.init(path, splitting))
|
if (app.init(path, splitting))
|
||||||
{
|
{
|
||||||
app.run();
|
app.run();
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace output
|
||||||
{
|
{
|
||||||
const char* HELP_FLAG = "--help";
|
const char* HELP_FLAG = "--help";
|
||||||
const char* SPLITTING_FLAG = "-s";
|
const char* SPLITTING_FLAG = "-s";
|
||||||
|
const char* RESOLUTION_FLAG = "-r";
|
||||||
|
|
||||||
const char* NO_ARG_MSG = "Please at least provide a path to a target image. --help for more information.\n";
|
const char* NO_ARG_MSG = "Please at least provide a path to a target image. --help for more information.\n";
|
||||||
const char* HELP_MSG = "usage: sliding-puzzle [-OPTIONS...] FILE-OR-DIRECTORY\n\n"
|
const char* HELP_MSG = "usage: sliding-puzzle [-OPTIONS...] FILE-OR-DIRECTORY\n\n"
|
||||||
|
@ -18,4 +19,6 @@ namespace output
|
||||||
" will be num * num.\n";
|
" will be num * num.\n";
|
||||||
const char* SPLITTING_MSG = "-s should be given with a positive num >= 2 as in [-s num].\n";
|
const char* SPLITTING_MSG = "-s should be given with a positive num >= 2 as in [-s num].\n";
|
||||||
const char* IMG_FAIL_MSG = "Couldn't load image from given path.\n";
|
const char* IMG_FAIL_MSG = "Couldn't load image from given path.\n";
|
||||||
|
const char* RESOLUTION_MSG = "Couldn't recognize given screen resolution.\n"
|
||||||
|
"Please it provide as in [NUMxNUM], 1280x720, 1600x900, etc.\n";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue