First approach of area generation

This commit is contained in:
sebastian 2026-02-14 18:18:58 +01:00
parent dad3a4e0f3
commit 762550fccf
2 changed files with 127 additions and 41 deletions

View File

@ -4,7 +4,12 @@
#include "MapGenerator.h" #include "MapGenerator.h"
#include <queue>
#include <unordered_set> #include <unordered_set>
struct TileInfo {
int q, r;
EntityID id;
};
float MapGenerator::hexRadius = 10.0f; float MapGenerator::hexRadius = 10.0f;
@ -63,8 +68,87 @@ void MapGenerator::generateHexMap(Map &map, int width, int height, EntityManager
entityManager.addComponent(entityID, tileHighlightComponent); entityManager.addComponent(entityID, tileHighlightComponent);
entityManager.addComponent(entityID, tileGameplayComponent); entityManager.addComponent(entityID, tileGameplayComponent);
entityManager.addComponent(entityID, std::make_shared<MapEntityComponent>()); entityManager.addComponent(entityID, std::make_shared<MapEntityComponent>());
//Todo replace with area system }
entityManager.addComponent(entityID, std::make_shared<OwnerComponent>(random.randomInt(0,4))); }
assignOwners(entityManager, 2);
}
void MapGenerator::assignOwners(EntityManager &entityManager, int numPlayers) {
Random random;
std::vector<TileInfo> allTiles;
for (EntityID id: entityManager.getAllEntities()) {
if (auto tileComponent = entityManager.getComponent<TileGameplayComponent>(id)) {
allTiles.push_back({tileComponent->q, tileComponent->r, id});
}
}
int maxTilesPerPlayer = static_cast<int>(allTiles.size() / numPlayers * (1.f / numPlayers)); // z.B. 60% der Map
std::unordered_set<EntityID> assigned;
//1 Seets pro Spieler
std::vector<EntityID> seeds;
for (int player = 0; player < numPlayers; ++player) {
EntityID seed = allTiles[random.randomInt(0, static_cast<int>(allTiles.size()))].id;
seeds.push_back(seed);
entityManager.addComponent(seed, std::make_shared<OwnerComponent>(player-1));
}
// 2. Expansion
bool changed = true;
while (changed) {
changed = false;
for (PlayerID player = 0; player < static_cast<uint32_t>(numPlayers); ++player) {
// Finde alle Tiles des Spielers
int ownedCount = 0;
for (TileInfo& tile : allTiles) {
if (assigned.count(tile.id) == 0) continue;
auto owner = entityManager.getComponent<OwnerComponent>(tile.id);
if (owner && owner->playerID == player) {
++ownedCount;
}
}
std::vector<EntityID> borderTiles;
for (TileInfo& tile : allTiles) {
auto owner = entityManager.getComponent<OwnerComponent>(tile.id);
if (!owner || owner->playerID != player) continue;
for (TileInfo& neighbor : allTiles) {
auto neighborOwner = entityManager.getComponent<OwnerComponent>(neighbor.id);
if (neighborOwner || assigned.count(neighbor.id)) continue;
if (areHexNeighbors(tile.q, tile.r, neighbor.q, neighbor.r)) {
borderTiles.push_back(neighbor.id);
} }
} }
} }
if (ownedCount >= maxTilesPerPlayer) continue;
// Zufällige Auswahl eines Nachbarn zum expandieren
if (!borderTiles.empty()) {
EntityID newTile = borderTiles[random.randomInt(0, static_cast<int>(borderTiles.size()-1))];
entityManager.addComponent(newTile, std::make_shared<OwnerComponent>(player));
assigned.insert(newTile);
changed = true;
}
}
}
}
bool MapGenerator::areHexNeighbors(int q1, int r1, int q2, int r2) {
// Hex axial neighbor differences
static const std::vector<std::pair<int,int>> directions = {
{+1, 0}, {+1, -1}, {0, -1},
{-1, 0}, {-1, +1}, {0, +1}
};
for (auto [dq, dr] : directions) {
if (q1 + dq == q2 && r1 + dr == r2) return true;
}
return false;
}

View File

@ -30,7 +30,9 @@ public:
static void init(Loader& loader, float hexRadius); static void init(Loader& loader, float hexRadius);
static void generateHexMap(Map& map, int width, int height, EntityManager& entityManager); static void generateHexMap(Map& map, int width, int height, EntityManager& entityManager);
std::vector<MapArea> generateAreas(const EntityManager &em); static void assignOwners(EntityManager &entityManager, int numPlayers);
static bool areHexNeighbors(int tile_q, int tile_r, int neighbor_q, int neighbor_r);
private: private: