diff options
author | HampusM <hampus@hampusmat.com> | 2022-02-15 20:27:51 +0100 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2022-02-15 20:27:51 +0100 |
commit | 5dae8f8d10d506abc3c75a1f66c1dfe620c84fc1 (patch) | |
tree | 2bfb6efef0535a35bab1da811a5f69cb5203dff9 /src/mazerator.cpp | |
parent | 9147551cd21d565f9503e3ebbcd2121e284d88d5 (diff) |
refactor: improve project design
Diffstat (limited to 'src/mazerator.cpp')
-rw-r--r-- | src/mazerator.cpp | 170 |
1 files changed, 94 insertions, 76 deletions
diff --git a/src/mazerator.cpp b/src/mazerator.cpp index b30124f..81960af 100644 --- a/src/mazerator.cpp +++ b/src/mazerator.cpp @@ -1,35 +1,28 @@ -#include "engine/matrix.hpp" +#include "conversion.hpp" + +#include "app/app.hpp" #include "engine/vector2.hpp" -#include "getopt.h" -#include "maze.hpp" #include "random_generator.hpp" -#include "utils.hpp" + +#include <getopt.h> #include <iostream> #include <memory> #include <string> +#include <string_view> +#include <vector> + +constexpr unsigned int DEFAULT_MAZE_WIDTH = 40U; +constexpr unsigned int DEFAULT_MAZE_HEIGHT = 20U; -void optarg_error(int arg, std::string error) +constexpr std::string_view DEFAULT_MAZE_WALL = "█"; + +void optarg_error(int arg, const std::string &error) { std::cout << "Error: Invalid option argument for -" << arg << ". " << error << std::endl; exit(EXIT_FAILURE); } -void validate_start_coords(unsigned int start_x, unsigned int start_y, unsigned int width, - unsigned int height) -{ - if (start_x >= width) - { - throw "The x start coordinate cannot be higher than or equal to the maze's width"; - } - - if (start_y >= height) - { - throw "The y start coordinate cannot be higher than or equal to the maze's " - "height"; - } -} - /** * Parses a unsigned integer command-line argument. * @@ -54,102 +47,135 @@ void parse_uint_arg(unsigned int *num_dst, int arg, bool check_zero = false) } } -const struct option options[] = {{"width", required_argument, NULL, 'w'}, - {"height", required_argument, NULL, 'h'}, - {"wall", required_argument, NULL, 'W'}, - {"seed", required_argument, NULL, 's'}, - {"start-x", required_argument, NULL, 'x'}, - {"start-y", required_argument, NULL, 'y'}, - {"help", no_argument, NULL, 0}, - {NULL, 0, NULL, 0}}; +const std::array<option, 8> options = { + option({"width", required_argument, nullptr, 'w'}), + option({"height", required_argument, nullptr, 'h'}), + option({"wall", required_argument, nullptr, 'W'}), + option({"seed", required_argument, nullptr, 's'}), + option({"start-x", required_argument, nullptr, 'x'}), + option({"start-y", required_argument, nullptr, 'y'}), + option({"help", no_argument, nullptr, 0}), + option({nullptr, 0, nullptr, 0})}; int main(int argc, char *argv[]) { - unsigned int maze_width = 40U; - unsigned int maze_height = 20U; + auto args = std::vector<std::string>(argv, argv + argc); - std::unique_ptr<unsigned int> start_x = nullptr; - std::unique_ptr<unsigned int> start_y = nullptr; + AppOptions app_options; - std::shared_ptr<RandomNumberGenerator> random_gen = nullptr; + BoundsOpts default_maze_bounds = {DEFAULT_MAZE_WIDTH, DEFAULT_MAZE_HEIGHT}; - std::string wall = "█"; + app_options.maze_bounds(std::make_shared<Bounds>(default_maze_bounds)); - int arg; - while ((arg = getopt_long(argc, argv, "w:h:W:s:x:y:", options, nullptr)) != -1) + app_options.wall(DEFAULT_MAZE_WALL); + + std::unique_ptr<unsigned int> start_x = nullptr; + std::unique_ptr<unsigned int> start_y = nullptr; + + int arg = 0; + while ((arg = getopt_long(argc, argv, "w:h:W:s:x:y:", options.data(), nullptr)) != -1) { switch (arg) { case 'w': - parse_uint_arg(&maze_width, arg, true); + { + app_options.maze_bounds()->width( + static_cast<unsigned int>(std::stoul(optarg, nullptr, NUMBER_BASE))); break; + } case 'h': - parse_uint_arg(&maze_height, arg, true); + { + app_options.maze_bounds()->height( + static_cast<unsigned int>(std::stoul(optarg, nullptr, NUMBER_BASE))); break; + } case 'x': + { start_x = std::make_unique<unsigned int>(); + parse_uint_arg(start_x.get(), arg); break; + } case 'y': + { start_y = std::make_unique<unsigned int>(); + parse_uint_arg(start_y.get(), arg); break; + } case 'W': - wall = optarg; + { + app_options.wall(optarg); break; + } case 's': - unsigned int seed; + { + unsigned int seed = 0; parse_uint_arg(&seed, arg, true); - random_gen = std::make_shared<RandomNumberGenerator>(seed); + app_options.random_gen(std::make_shared<RandomNumberGenerator>(seed)); break; + } case 0: - std::cout - << "Usage: " << argv[0] - << " [OPTION]...\n\n" - "Options:\n" - " -w, --width WIDTH The width of the maze (Default: 40)\n" - " -h, --height HEIGHT The height of the maze (Default: 20)\n" - " -x, --start-x X The x coordinate for the start " - "position " - "(Default: random)\n" - " -y, --start-y Y The y coordinate for the start " - "position " - "(Default: random)\n" - " -W, --wall WALL Single character used as maze walls " - "(Default: '█')\n" - " -s, --seed SEED The randomization seed used for maze " - "generation\n" - " --help Displays usage information" - << std::endl; + { + std::cout << "Usage: " << args[0] + << " [OPTION]...\n\n" + "Options:\n" + " -w, --width WIDTH The width of the maze (Default: " + << DEFAULT_MAZE_WIDTH + << ")\n" + " -h, --height HEIGHT The height of the maze (Default: " + << DEFAULT_MAZE_HEIGHT + << ")\n" + " -x, --start-x X The x coordinate for the start " + "position " + "(Default: random)\n" + " -y, --start-y Y The y coordinate for the start " + "position " + "(Default: random)\n" + " -W, --wall WALL Single character used as maze walls " + "(Default: '" + << DEFAULT_MAZE_WALL + << "')\n" + " -s, --seed SEED The randomization seed used for maze " + "generation\n" + " --help Displays usage information" + << std::endl; return EXIT_SUCCESS; + } case '?': - std::cout << "\nTry '" << argv[0] << " --help' for more information" + { + std::cout << "\nTry '" << args[0] << " --help' for more information" << std::endl; return EXIT_FAILURE; } + } } - if (random_gen == nullptr) + if (app_options.random_gen() == nullptr) { - random_gen = std::make_shared<RandomNumberGenerator>(); + app_options.random_gen(std::make_shared<RandomNumberGenerator>()); } if (start_x == nullptr) { - start_x = - std::make_unique<unsigned int>(random_gen->in_range(0, maze_width - 1U)); + start_x = std::make_unique<unsigned int>(app_options.random_gen()->in_range( + 0, app_options.maze_bounds()->width() - 1U)); } if (start_y == nullptr) { - start_y = - std::make_unique<unsigned int>(random_gen->in_range(0, maze_height - 1U)); + start_y = std::make_unique<unsigned int>(app_options.random_gen()->in_range( + 0, app_options.maze_bounds()->height() - 1U)); } + Vector2Opts start_coords = {.x = *start_x, .y = *start_y}; + + app_options.start_coords(std::make_shared<Vector2>(start_coords)); + try { - validate_start_coords(*start_x, *start_y, maze_width, maze_height); + app_options.maze_bounds()->verify_coords(*app_options.start_coords()); } catch (const char *error) { @@ -157,13 +183,5 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - Matrix<std::string> matrix(maze_height * 2U + 1U, maze_width * 2U + 1U); - - matrix.fill(wall); - - auto start_pos = std::make_shared<Vector2>(*start_x * 2U + 1U, *start_y * 2U + 1U); - - matrix_to_maze<std::string>(&matrix, start_pos, " ", random_gen); - - matrix.print(); + app_start(app_options); } |