diff options
author | zaaarf <80046572+zaaarf@users.noreply.github.com> | 2023-09-19 18:08:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-19 18:08:07 +0200 |
commit | 7a55877367282749e89ff938ca1d7910f7166fe6 (patch) | |
tree | 46ae571e7dddc83ebc7e87ae83726356d0f71934 | |
parent | 9c89100e0c8854dff3174b078d235148585a8b03 (diff) | |
parent | 88948eb11127c6d3442fbd476f7b456643b58728 (diff) |
Merge pull request #18 from OpenVicProject/province-adjacencies-bis
Basic province adjacencies algorithm/logic
-rw-r--r-- | src/openvic-simulation/map/Map.cpp | 38 | ||||
-rw-r--r-- | src/openvic-simulation/map/Province.cpp | 38 | ||||
-rw-r--r-- | src/openvic-simulation/map/Province.hpp | 23 |
3 files changed, 92 insertions, 7 deletions
diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 0173ab6..3b06c66 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -501,11 +501,35 @@ bool Map::load_region_file(ast::NodeCPtr root) { } bool Map::_generate_province_adjacencies() { - /* TODO - generate default province adjacencies - * variables available for use: - * - width, height - * - province_shape_image, so the index at (x,y) is: - * province_shape_image[x + y * width].index - */ - return true; + bool changed = false; + + auto generate_adjacency = [&] (shape_pixel_t cur_pixel, size_t x, size_t y) -> bool { + size_t idx = x + y * width; + shape_pixel_t neighbour_pixel = province_shape_image[idx]; + if (cur_pixel.index != neighbour_pixel.index) { + Province* cur = get_province_by_index(cur_pixel.index); + Province* neighbour = get_province_by_index(neighbour_pixel.index); + if(cur != nullptr && neighbour != nullptr) { + cur->add_adjacency(neighbour, 0, 0); + neighbour->add_adjacency(cur, 0, 0); + return true; + } else Logger::error( + "Couldn't find province(s): current = ", cur, " (", cur_pixel.index, + "), neighbour = ", neighbour, " (", neighbour_pixel.index, ")" + ); + } + return false; + }; + + for (size_t y = 0; y < height; ++y) { + for (size_t x = 0; x < width; ++x) { + shape_pixel_t cur = province_shape_image[x + y * width]; + if(x + 1 < width) + changed |= generate_adjacency(cur, x + 1, y); + if(y + 1 < height) + changed |= generate_adjacency(cur, x, y + 1); + } + } + + return changed; } diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp index 775c0a4..db7e784 100644 --- a/src/openvic-simulation/map/Province.cpp +++ b/src/openvic-simulation/map/Province.cpp @@ -1,7 +1,9 @@ #include "Province.hpp" #include <cassert> +#include <cstddef> #include <iomanip> +#include <iterator> #include <sstream> using namespace OpenVic; @@ -137,3 +139,39 @@ void Province::tick(Date const& today) { for (Building& building : buildings.get_items()) building.tick(today); } + +Province::adjacency_t::adjacency_t(Province const* province, distance_t distance, flags_t flags) + : province { province }, distance { distance }, flags { flags } { + assert(province != nullptr); +} + +Province::distance_t Province::adjacency_t::get_distance() const { + return distance; +} + +Province::flags_t Province::adjacency_t::get_flags() { + return flags; +} + +bool Province::is_adjacent_to(Province const* province) { + for (adjacency_t adj : adjacencies) + if (adj.province == province) + return true; + return false; +} + +bool Province::add_adjacency(Province const* province, distance_t distance, flags_t flags) { + if (province == nullptr) { + Logger::error("Tried to create null adjacency province for province ", get_identifier(), "!"); + return false; + } + + if (is_adjacent_to(province)) + return false; + adjacencies.push_back({ province, distance, flags }); + return true; +} + +std::vector<Province::adjacency_t> const& Province::get_adjacencies() const { + return adjacencies; +}
\ No newline at end of file diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp index bf407ae..370d05c 100644 --- a/src/openvic-simulation/map/Province.hpp +++ b/src/openvic-simulation/map/Province.hpp @@ -17,6 +17,23 @@ namespace OpenVic { using index_t = uint16_t; using life_rating_t = int8_t; + using distance_t = uint16_t; + using flags_t = uint16_t; + + struct adjacency_t { + friend struct Province; + + private: + Province const* const province; + const distance_t distance; + flags_t flags; + + adjacency_t(Province const* province, distance_t distance, flags_t flags); + + public: + distance_t get_distance() const; + flags_t get_flags(); + }; static constexpr index_t NULL_INDEX = 0, MAX_INDEX = (1 << (8 * sizeof(index_t))) - 1; @@ -33,6 +50,8 @@ namespace OpenVic { Pop::pop_size_t total_population; distribution_t pop_types, cultures, religions; + std::vector<adjacency_t> adjacencies; + Province(const std::string_view new_identifier, colour_t new_colour, index_t new_index); public: @@ -65,5 +84,9 @@ namespace OpenVic { void update_state(Date const& today); void tick(Date const& today); + + bool is_adjacent_to(Province const* province); + bool add_adjacency(Province const* province, distance_t distance, flags_t flags); + std::vector<adjacency_t> const& get_adjacencies() const; }; } |