diff --git a/.gitmodules b/.gitmodules index 70a5151..fb678ab 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "lib/blt-with-graphics"] path = lib/blt-with-graphics url = https://git.tpgc.me/tri11paragon/BLT-With-Graphics-Template +[submodule "tools/skyscraper_parser"] + path = tools/skyscraper_parser + url = https://github.com/Tri11Paragon/skyscraper_parser diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0b76fe5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..ecadcfb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/skyscrapers-ga.iml b/.idea/skyscrapers-ga.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/skyscrapers-ga.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..3739d1a --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 563278b..1828e9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,7 @@ macro(blt_add_project name source type) project(skyscrapers-ga) endmacro() -project(skyscrapers-ga VERSION 0.0.2) +project(skyscrapers-ga VERSION 0.0.3) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..5895532 --- /dev/null +++ b/default.nix @@ -0,0 +1,66 @@ +{ pkgs ? (import { + config.allowUnfree = true; + config.segger-jlink.acceptLicense = true; +}), customPkgs ? (import /home/brett/my-nixpkgs { + config.allowUnfree = true; + config.segger-jlink.acceptLicense = true; +}), ... }: +pkgs.mkShell +{ + nativeBuildInputs = with pkgs; [ + playwright-driver.browsers + ]; + buildInputs = with pkgs; [ + cmake + gcc + clang + emscripten + ninja + customPkgs.jetbrains.clion + #clion = import ~/my-nixpkgs/pkgs/applications/editors/jetbrains {}; + renderdoc + valgrind + (python3.withPackages (python-pkgs: [ + python-pkgs.beautifulsoup4 + python-pkgs.playwright + python-pkgs.requests + ])) + ]; + propagatedBuildInputs = with pkgs; [ + xorg.libX11 + xorg.libX11.dev + xorg.libXcursor + xorg.libXcursor.dev + xorg.libXext + xorg.libXext.dev + xorg.libXinerama + xorg.libXinerama.dev + xorg.libXrandr + xorg.libXrandr.dev + xorg.libXrender + xorg.libXrender.dev + xorg.libxcb + xorg.libxcb.dev + xorg.libXi + xorg.libXi.dev + harfbuzz + harfbuzz.dev + zlib + zlib.dev + bzip2 + bzip2.dev + pngpp + brotli + brotli.dev + pulseaudio.dev + git + libGL + libGL.dev + glfw + ]; + LD_LIBRARY_PATH="/run/opengl-driver/lib:/run/opengl-driver-32/lib"; + shellHook = '' + export PLAYWRIGHT_BROWSERS_PATH=${pkgs.playwright-driver.browsers} + export PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=true + ''; +} diff --git a/include/skyscrapers.h b/include/skyscrapers.h new file mode 100644 index 0000000..a81fd03 --- /dev/null +++ b/include/skyscrapers.h @@ -0,0 +1,66 @@ +#pragma once +/* + * Copyright (C) 2024 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SKYSCRAPERS_H +#define SKYSCRAPERS_H + +#include +#include +#include +#include +#include + +namespace sky +{ + struct problem_t + { + enum class error_t + { + MISSING_BOARD_SIZE, + MISSING_BOARD_DATA, + INCORRECT_BOARD_DATA_FOR_SIZE + }; + + blt::i32 board_size; + std::vector top, bottom, left, right; + + explicit problem_t(const blt::i32 board_size): board_size(board_size) + { + top.reserve(board_size); + bottom.reserve(board_size); + left.reserve(board_size); + right.reserve(board_size); + } + + void print(); + + [[nodiscard]] blt::i32 min() const // NOLINT + { + return 1; + } + + [[nodiscard]] blt::i32 max() const + { + return board_size + 1; + } + }; + + blt::expected problem_from_file(std::string_view path); +} + +#endif //SKYSCRAPERS_H diff --git a/rules.txt b/rules.txt new file mode 100644 index 0000000..e4f0fa6 --- /dev/null +++ b/rules.txt @@ -0,0 +1,5 @@ +Each of the boxes contains a skyscraper. +Put numbers 1 to 4 into the boxes which give the height of the building. The higher the number, the taller the skyscraper. +Each row and each column contains each number exactly once. +The number in an arrow shows you how many skyscrapers can be seen when looking in the direction of the arrow. +You cannot see a shorter skyscraper behind a taller one. \ No newline at end of file diff --git a/skyscraper_problem.txt b/skyscraper_problem.txt new file mode 100644 index 0000000..64f3abf --- /dev/null +++ b/skyscraper_problem.txt @@ -0,0 +1,10 @@ +BOARD_SIZE: 6 + +1 4 2 3 3 3 +1 3 +2 3 +4 2 +3 3 +2 4 +2 1 +2 2 3 3 4 1 diff --git a/src/main.cpp b/src/main.cpp index 6f2b004..aabf5d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,71 @@ -#include +#include +#include "blt/gfx/renderer/resource_manager.h" +#include "blt/gfx/renderer/batch_2d_renderer.h" +#include "blt/gfx/renderer/camera.h" +#include +#include +#include -int main() +blt::gfx::matrix_state_manager global_matrices; +blt::gfx::resource_manager resources; +blt::gfx::batch_renderer_2d renderer_2d(resources, global_matrices); +blt::gfx::first_person_camera camera; + +void init(const blt::gfx::window_data&) { - std::cout << "Hello World!" << std::endl; + using namespace blt::gfx; + + + global_matrices.create_internals(); + resources.load_resources(); + renderer_2d.create(); } + +void update(const blt::gfx::window_data& data) +{ + global_matrices.update_perspectives(data.width, data.height, 90, 0.1, 2000); + + camera.update(); + camera.update_view(global_matrices); + global_matrices.update(); + + renderer_2d.render(data.width, data.height); +} + +void destroy(const blt::gfx::window_data&) +{ + global_matrices.cleanup(); + resources.cleanup(); + renderer_2d.cleanup(); + blt::gfx::cleanup(); +} + +int main(int argc, const char** argv) +{ + blt::arg_parse parser; + + parser.addArgument(blt::arg_builder("file").build()); + + auto args = parser.parse_args(argc, argv); + + if (!args.contains("file")) + { + BLT_WARN("Please provide a skyscraper formatted file!"); + return EXIT_FAILURE; + } + + const auto file = args.get("file"); + + auto problem = sky::problem_from_file(file); + + if (!problem) + { + BLT_WARN("Unable to parse skyscraper file!"); + return EXIT_FAILURE; + } + + auto& problem_d = problem.value(); + problem_d.print(); + + blt::gfx::init(blt::gfx::window_data{"My Sexy Window", init, update, destroy}.setSyncInterval(1)); +} \ No newline at end of file diff --git a/src/skyscrapers.h.cpp b/src/skyscrapers.h.cpp new file mode 100644 index 0000000..2262eb0 --- /dev/null +++ b/src/skyscrapers.h.cpp @@ -0,0 +1,110 @@ +/* + * + * Copyright (C) 2025 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +#include +#include + +namespace sky +{ + void problem_t::print() + { + BLT_TRACE("Board Size: %d", board_size); + BLT_TRACE_STREAM << "\t"; + for (int i = 0; i < board_size; i++) + BLT_TRACE_STREAM << top[i] << '\t'; + BLT_TRACE_STREAM << "\n"; + for (int i = 0; i < board_size; i++) + { + BLT_TRACE_STREAM << left[i]; + for (int j = 0; j < board_size + 1; j++) + BLT_TRACE_STREAM << '\t'; + BLT_TRACE_STREAM << right[i] << "\n"; + } + BLT_TRACE_STREAM << "\t"; + for (int i = 0; i < board_size; i++) + BLT_TRACE_STREAM << bottom[i] << '\t'; + BLT_TRACE_STREAM << "\n"; + } + + blt::expected problem_from_file(const std::string_view path) + { + const auto lines = blt::fs::getLinesFromFile(path); + + const auto size_line = blt::string::split(lines.front(), '\t'); + + if (size_line.size() != 2) + { + BLT_WARN("File is incorrectly formatted. First line is expected to describe board size like 'BOARD_SIZE: #`"); + return blt::unexpected(problem_t::error_t::MISSING_BOARD_SIZE); + } + + problem_t problem{std::stoi(size_line[1])}; + + if (lines.size() != static_cast(problem.board_size) + 3) + { + BLT_TRACE(lines.size()); + BLT_TRACE(problem.board_size + 1); + BLT_WARN("File is incorrectly formatted. Expected problem to be defined as a series of lines, describing the structure of the board"); + return blt::unexpected(problem_t::error_t::MISSING_BOARD_DATA); + } + + auto top_problems = blt::string::split(lines[1], '\t'); + + if (top_problems.size() != static_cast(problem.board_size)) + { + BLT_WARN("File is incorrectly formatted. Expected BOARD_SIZE '%d' number of elements got %lu", problem.board_size, top_problems.size()); + return blt::unexpected(problem_t::error_t::INCORRECT_BOARD_DATA_FOR_SIZE); + } + + for (const auto& arrow : top_problems) + problem.top.push_back(std::stoi(arrow)); + + for (blt::size_t i = 0; i < static_cast(problem.board_size); i++) + { + const auto index = i + 2; + if (index >= lines.size()) + { + BLT_WARN("File is incorrectly formatted. Expected BOARD_SIZE '%d' number of rows describing the sizes of the board but got %lu", + problem.board_size, lines.size()); + return blt::unexpected(problem_t::error_t::INCORRECT_BOARD_DATA_FOR_SIZE); + } + auto data = blt::string::split(lines[index], '\t'); + if (data.size() != 2) + { + BLT_WARN("File is incorrectly formatted. Expected 2 points for the side data descriptors, got %lu", data.size()); + return blt::unexpected(problem_t::error_t::INCORRECT_BOARD_DATA_FOR_SIZE); + } + problem.left.push_back(std::stoi(data[0])); + problem.right.push_back(std::stoi(data[1])); + } + + auto bottom_problems = blt::string::split(lines[8], '\t'); + + if (bottom_problems.size() != static_cast(problem.board_size)) + { + BLT_WARN("File is incorrectly formatted. Expected BOARD_SIZE '%d' number of elements got %lu", problem.board_size, top_problems.size()); + return blt::unexpected(problem_t::error_t::INCORRECT_BOARD_DATA_FOR_SIZE); + } + + for (const auto& arrow : bottom_problems) + problem.bottom.push_back(std::stoi(arrow)); + + return problem; + } +} diff --git a/tools/skyscraper_parser b/tools/skyscraper_parser new file mode 160000 index 0000000..529553b --- /dev/null +++ b/tools/skyscraper_parser @@ -0,0 +1 @@ +Subproject commit 529553b9a4f432c7f9e742c80308c6edd369c07e