From ade93c528bca7321393a767a4a379a0ebae3d215 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Mon, 18 Sep 2023 18:35:13 +0200 Subject: feat: added adjacency to provinces --- src/openvic-simulation/map/Province.cpp | 25 +++++++++++++++++++++++++ src/openvic-simulation/map/Province.hpp | 19 +++++++++++++++++++ 2 files changed, 44 insertions(+) (limited to 'src/openvic-simulation/map') diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp index 775c0a4..8dcaa42 100644 --- a/src/openvic-simulation/map/Province.cpp +++ b/src/openvic-simulation/map/Province.cpp @@ -137,3 +137,28 @@ void Province::tick(Date const& today) { for (Building& building : buildings.get_items()) building.tick(today); } + +Province::adjacency_t::adjacency_t(index_t new_provice_id, distance_t new_distance, flags_t new_flags) { + assert(new_provice_id != Province::NULL_INDEX); + province_id = new_provice_id; + distance = new_distance; + flags = new_flags; +} + +bool Province::is_adjacent_to(index_t province_index) { + for (adjacency_t adj : adjacencies) + if (adj.province_id == province_index) + return true; + return false; +} + +bool Province::add_adjacency(index_t province_index, distance_t distance, flags_t flags) { + if (is_adjacent_to(province_index)) + return false; + adjacencies.push_back({ province_index, distance, flags }); + return true; +} + +std::vector 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..4c89db4 100644 --- a/src/openvic-simulation/map/Province.hpp +++ b/src/openvic-simulation/map/Province.hpp @@ -17,6 +17,19 @@ 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: + index_t province_id; + distance_t distance; + flags_t flags; + + adjacency_t(index_t provice_id, distance_t distance, flags_t flags); + }; static constexpr index_t NULL_INDEX = 0, MAX_INDEX = (1 << (8 * sizeof(index_t))) - 1; @@ -33,6 +46,8 @@ namespace OpenVic { Pop::pop_size_t total_population; distribution_t pop_types, cultures, religions; + std::vector adjacencies; + Province(const std::string_view new_identifier, colour_t new_colour, index_t new_index); public: @@ -65,5 +80,9 @@ namespace OpenVic { void update_state(Date const& today); void tick(Date const& today); + + bool is_adjacent_to(index_t province_index); + bool add_adjacency(index_t province_index, distance_t distance, flags_t flags); + std::vector const& get_adjacencies() const; }; } -- cgit v1.2.3-56-ga3b1 From a5ed46fd6770d7a72b4fd2d6aea9711520fecdf2 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Mon, 18 Sep 2023 23:25:33 +0200 Subject: feat: implemented dumb basic algorithm for Map::_generate_province_adjacencies() --- src/openvic-simulation/map/Map.cpp | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'src/openvic-simulation/map') diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 0173ab6..5d160b7 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -1,6 +1,7 @@ #include "Map.hpp" #include +#include #include #include "openvic-simulation/economy/Good.hpp" @@ -501,11 +502,34 @@ 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 - */ + auto generate_adjacency = [&] (shape_pixel_t cur, int32_t x, int32_t y) { + int32_t idx = x + y * width; + if (idx >= 0 && idx < province_shape_image.size()) { + shape_pixel_t neighbour_pixel = province_shape_image[idx]; + if (cur.index != neighbour_pixel.index) { + Province* cur_province = get_province_by_index(cur.index); + Province* neighbour = get_province_by_index(neighbour_pixel.index); + if (cur_province == nullptr) + Logger::error("No known province with index ", cur.index, ": cannot create adjacency for it!"); + else if (neighbour == nullptr) + Logger::error("No known province with index ", neighbour_pixel.index, ": cannot create adjacency for it!"); + else { //TODO: distance logic and flags + cur_province->add_adjacency(neighbour->index, 0, 0); + neighbour->add_adjacency(cur_province->index, 0, 0); + } + } + } + }; + + for (int32_t y = 0; y < height; ++y) { + for (int32_t x = 0; x < width; ++x) { + shape_pixel_t cur = province_shape_image[x + y * width]; + generate_adjacency(cur, x + 1, y); + generate_adjacency(cur, x, y - 1); + generate_adjacency(cur, x - 1, y); + generate_adjacency(cur, x, y + 1); + } + } + return true; } -- cgit v1.2.3-56-ga3b1 From 5ece48b0bf738a14a4464d09f29468b9dffdbe05 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Mon, 18 Sep 2023 23:30:45 +0200 Subject: feat: make adjacency generator returns false if nothing changed --- src/openvic-simulation/map/Map.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/openvic-simulation/map') diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 5d160b7..6ccaee0 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -502,7 +502,9 @@ bool Map::load_region_file(ast::NodeCPtr root) { } bool Map::_generate_province_adjacencies() { - auto generate_adjacency = [&] (shape_pixel_t cur, int32_t x, int32_t y) { + bool changed = false; + + auto generate_adjacency = [&] (shape_pixel_t cur, int32_t x, int32_t y) -> bool { int32_t idx = x + y * width; if (idx >= 0 && idx < province_shape_image.size()) { shape_pixel_t neighbour_pixel = province_shape_image[idx]; @@ -516,20 +518,22 @@ bool Map::_generate_province_adjacencies() { else { //TODO: distance logic and flags cur_province->add_adjacency(neighbour->index, 0, 0); neighbour->add_adjacency(cur_province->index, 0, 0); + return true; } } } + return false; }; for (int32_t y = 0; y < height; ++y) { for (int32_t x = 0; x < width; ++x) { shape_pixel_t cur = province_shape_image[x + y * width]; - generate_adjacency(cur, x + 1, y); - generate_adjacency(cur, x, y - 1); - generate_adjacency(cur, x - 1, y); - generate_adjacency(cur, x, y + 1); + changed |= generate_adjacency(cur, x + 1, y); + changed |= generate_adjacency(cur, x, y - 1); + changed |= generate_adjacency(cur, x - 1, y); + changed |= generate_adjacency(cur, x, y + 1); } } - return true; + return changed; } -- cgit v1.2.3-56-ga3b1 From 3017b6338ca67c0c18f404cf8e162918e36e94e7 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 19 Sep 2023 14:09:19 +0200 Subject: fix: adjacency algorithm optimisiations and fixes --- src/openvic-simulation/map/Map.cpp | 16 +++++++--------- src/openvic-simulation/map/Province.cpp | 18 ++++++++---------- src/openvic-simulation/map/Province.hpp | 8 ++++---- 3 files changed, 19 insertions(+), 23 deletions(-) (limited to 'src/openvic-simulation/map') diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 6ccaee0..e2ad1de 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -504,9 +504,9 @@ bool Map::load_region_file(ast::NodeCPtr root) { bool Map::_generate_province_adjacencies() { bool changed = false; - auto generate_adjacency = [&] (shape_pixel_t cur, int32_t x, int32_t y) -> bool { - int32_t idx = x + y * width; - if (idx >= 0 && idx < province_shape_image.size()) { + auto generate_adjacency = [&] (shape_pixel_t cur, size_t x, size_t y) -> bool { + if (x < width && y < height) { + size_t idx = x + y * width; shape_pixel_t neighbour_pixel = province_shape_image[idx]; if (cur.index != neighbour_pixel.index) { Province* cur_province = get_province_by_index(cur.index); @@ -516,8 +516,8 @@ bool Map::_generate_province_adjacencies() { else if (neighbour == nullptr) Logger::error("No known province with index ", neighbour_pixel.index, ": cannot create adjacency for it!"); else { //TODO: distance logic and flags - cur_province->add_adjacency(neighbour->index, 0, 0); - neighbour->add_adjacency(cur_province->index, 0, 0); + cur_province->add_adjacency(neighbour, 0, 0); + neighbour->add_adjacency(cur_province, 0, 0); return true; } } @@ -525,12 +525,10 @@ bool Map::_generate_province_adjacencies() { return false; }; - for (int32_t y = 0; y < height; ++y) { - for (int32_t x = 0; x < width; ++x) { + 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]; changed |= generate_adjacency(cur, x + 1, y); - changed |= generate_adjacency(cur, x, y - 1); - changed |= generate_adjacency(cur, x - 1, y); changed |= generate_adjacency(cur, x, y + 1); } } diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp index 8dcaa42..19dd873 100644 --- a/src/openvic-simulation/map/Province.cpp +++ b/src/openvic-simulation/map/Province.cpp @@ -138,24 +138,22 @@ void Province::tick(Date const& today) { building.tick(today); } -Province::adjacency_t::adjacency_t(index_t new_provice_id, distance_t new_distance, flags_t new_flags) { - assert(new_provice_id != Province::NULL_INDEX); - province_id = new_provice_id; - distance = new_distance; - flags = new_flags; +Province::adjacency_t::adjacency_t(Province const* province, distance_t distance, flags_t flags) + : province { province }, distance { distance }, flags { flags } { + assert(province != nullptr); } -bool Province::is_adjacent_to(index_t province_index) { +bool Province::is_adjacent_to(Province const* province) { for (adjacency_t adj : adjacencies) - if (adj.province_id == province_index) + if (adj.province->index == province->index) return true; return false; } -bool Province::add_adjacency(index_t province_index, distance_t distance, flags_t flags) { - if (is_adjacent_to(province_index)) +bool Province::add_adjacency(Province const* province, distance_t distance, flags_t flags) { + if (is_adjacent_to(province)) return false; - adjacencies.push_back({ province_index, distance, flags }); + adjacencies.push_back({ province, distance, flags }); return true; } diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp index 4c89db4..3f75a99 100644 --- a/src/openvic-simulation/map/Province.hpp +++ b/src/openvic-simulation/map/Province.hpp @@ -24,11 +24,11 @@ namespace OpenVic { friend struct Province; private: - index_t province_id; + Province const* province; distance_t distance; flags_t flags; - adjacency_t(index_t provice_id, distance_t distance, flags_t flags); + adjacency_t(Province const* province, distance_t distance, flags_t flags); }; static constexpr index_t NULL_INDEX = 0, MAX_INDEX = (1 << (8 * sizeof(index_t))) - 1; @@ -81,8 +81,8 @@ namespace OpenVic { void update_state(Date const& today); void tick(Date const& today); - bool is_adjacent_to(index_t province_index); - bool add_adjacency(index_t province_index, distance_t distance, flags_t flags); + bool is_adjacent_to(Province const* province); + bool add_adjacency(Province const* province, distance_t distance, flags_t flags); std::vector const& get_adjacencies() const; }; } -- cgit v1.2.3-56-ga3b1 From 88948eb11127c6d3442fbd476f7b456643b58728 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 19 Sep 2023 18:07:11 +0200 Subject: fix: various tweaks during review --- src/openvic-simulation/map/Map.cpp | 38 ++++++++++++++++----------------- src/openvic-simulation/map/Province.cpp | 17 ++++++++++++++- src/openvic-simulation/map/Province.hpp | 8 +++++-- 3 files changed, 40 insertions(+), 23 deletions(-) (limited to 'src/openvic-simulation/map') diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index e2ad1de..3b06c66 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -1,7 +1,6 @@ #include "Map.hpp" #include -#include #include #include "openvic-simulation/economy/Good.hpp" @@ -504,23 +503,20 @@ bool Map::load_region_file(ast::NodeCPtr root) { bool Map::_generate_province_adjacencies() { bool changed = false; - auto generate_adjacency = [&] (shape_pixel_t cur, size_t x, size_t y) -> bool { - if (x < width && y < height) { - size_t idx = x + y * width; - shape_pixel_t neighbour_pixel = province_shape_image[idx]; - if (cur.index != neighbour_pixel.index) { - Province* cur_province = get_province_by_index(cur.index); - Province* neighbour = get_province_by_index(neighbour_pixel.index); - if (cur_province == nullptr) - Logger::error("No known province with index ", cur.index, ": cannot create adjacency for it!"); - else if (neighbour == nullptr) - Logger::error("No known province with index ", neighbour_pixel.index, ": cannot create adjacency for it!"); - else { //TODO: distance logic and flags - cur_province->add_adjacency(neighbour, 0, 0); - neighbour->add_adjacency(cur_province, 0, 0); - return true; - } - } + 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; }; @@ -528,8 +524,10 @@ bool Map::_generate_province_adjacencies() { 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]; - changed |= generate_adjacency(cur, x + 1, y); - changed |= generate_adjacency(cur, x, y + 1); + if(x + 1 < width) + changed |= generate_adjacency(cur, x + 1, y); + if(y + 1 < height) + changed |= generate_adjacency(cur, x, y + 1); } } diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp index 19dd873..db7e784 100644 --- a/src/openvic-simulation/map/Province.cpp +++ b/src/openvic-simulation/map/Province.cpp @@ -1,7 +1,9 @@ #include "Province.hpp" #include +#include #include +#include #include using namespace OpenVic; @@ -143,14 +145,27 @@ Province::adjacency_t::adjacency_t(Province const* province, distance_t distance 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->index == province->index) + 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 }); diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp index 3f75a99..370d05c 100644 --- a/src/openvic-simulation/map/Province.hpp +++ b/src/openvic-simulation/map/Province.hpp @@ -24,11 +24,15 @@ namespace OpenVic { friend struct Province; private: - Province const* province; - distance_t distance; + 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; -- cgit v1.2.3-56-ga3b1