aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commit7a55877367282749e89ff938ca1d7910f7166fe6 (patch)
tree46ae571e7dddc83ebc7e87ae83726356d0f71934
parent9c89100e0c8854dff3174b078d235148585a8b03 (diff)
parent88948eb11127c6d3442fbd476f7b456643b58728 (diff)
Merge pull request #18 from OpenVicProject/province-adjacencies-bis
Basic province adjacencies algorithm/logic
-rw-r--r--src/openvic-simulation/map/Map.cpp38
-rw-r--r--src/openvic-simulation/map/Province.cpp38
-rw-r--r--src/openvic-simulation/map/Province.hpp23
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;
};
}