diff --git a/DeadZone/source/Entity/Player/Player.cpp b/DeadZone/source/Entity/Player/Player.cpp index 7675e10..1b63406 100644 --- a/DeadZone/source/Entity/Player/Player.cpp +++ b/DeadZone/source/Entity/Player/Player.cpp @@ -116,13 +116,12 @@ Player::Player(double x, double y, double drawWidth, double drawHeight, double r // Load player save.json load(); - // TODO: repara - //if (Map::get().getHasBeenLoaded()) - //{ - // const std::pair pos = Map::getRandomAccesiblePosition(); - // this->y = pos.first + 0.5f; - // this->x = pos.second + 0.5f; - //} + if (Map::get().getHasBeenLoaded()) + { + const std::pair pos = Map::getRandomAccesiblePosition(); + this->y = pos.first + 0.5f; + this->x = pos.second + 0.5f; + } } Player& Player::get() diff --git a/DeadZone/source/Map/Map.cpp b/DeadZone/source/Map/Map.cpp index 53639c8..ac248b4 100644 --- a/DeadZone/source/Map/Map.cpp +++ b/DeadZone/source/Map/Map.cpp @@ -40,6 +40,12 @@ void Map::deleteInstance() void Map::readMapFromFile(const std::string& path) { + this->mapString.clear(); + this->map.clear(); + this->doors.clear(); + this->shops.clear(); + this->enclosed.clear(); + std::ios_base::sync_with_stdio(false); std::ifstream in(path); @@ -52,6 +58,7 @@ void Map::readMapFromFile(const std::string& path) while (!in.eof()) { this->map.emplace_back(); + this->mapString.emplace_back(); std::string line; std::getline(in, line); @@ -83,19 +90,33 @@ void Map::readMapFromFile(const std::string& path) this->map.back().emplace_back(std::make_shared((double)this->map.back().size() + 0.5, (double)this->map.size() - 0.5, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, code, 10.0, 10.0)); this->shops.emplace_back(std::dynamic_pointer_cast(this->map.back().back())); } + this->mapString.back().emplace_back(code); } } in.close(); + this->createEnclosedAreas(); + this->mapLoaded = true; } void Map::readMapFromBuffer(const std::vector>& buffer) { + + this->mapString.clear(); + this->map.clear(); + this->doors.clear(); + this->shops.clear(); + this->enclosed.clear(); + + height = buffer.size(); + width = buffer[0].size(); + for (const std::vector &line : buffer) { this->map.emplace_back(); + this->mapString.emplace_back(); for (const std::string& code : line) { @@ -129,12 +150,95 @@ void Map::readMapFromBuffer(const std::vector>& buffer) this->map.back().emplace_back(std::make_shared((double)this->map.back().size() + 0.5, (double)this->map.size() - 0.5, 1.0, 1.0, 0.0, 0.0, ".0")); this->shops.emplace_back(std::make_shared((double)this->map.back().size() - 0.5, (double)this->map.size() - 0.5, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, code, 10.0, 10.0)); } + this->mapString.back().emplace_back(code); + } + } + + this->createEnclosedAreas(); + + for (int i = 0; i < mapString.size(); i++) + { + for (int j = 0; j < mapString[i].size(); j++) + { + std::cout << mapString[i][j] << " "; } + std::cout << std::endl; } this->mapLoaded = true; } +void Map::createEnclosedAreas() { + std::vector> visited(height, std::vector(width, 0)); + std::vector> visited2(height, std::vector(width, 0)); + const int di[8] = { -1, 0, 1, 0, 1, 1, -1, -1 }; + const int dj[8] = { 0, 1, 0, -1, 1, -1, 1, -1 }; + + auto inside = [&](std::pair cell) { + if (cell.first < height && cell.first >= 0 && cell.second < width && cell.second >= 0) + return 1; + return 0; + }; + + auto inside2 = [&](std::pair cell) { + if (cell.first < height - 1 && cell.first >= 1 && cell.second < width - 1 && cell.second >= 1) + return 1; + return 0; + }; + + std::queue> cellsInQueue; + std::vector> visitedCells; + enclosed.assign(height, std::vector(width, 0)); + for (int i = 0; i < height; i++) + for (int j = 0; j < width; j++) + if (mapString[i][j][0] == '.' && !visited[i][j]) { + visitedCells.clear(); + int cnt = 0; + cellsInQueue.push({ i, j }); + visited[i][j] = 1; + visitedCells.push_back({ i, j }); + while (cellsInQueue.size() > 0) { + cnt++; + std::pair cell = cellsInQueue.front(); + cellsInQueue.pop(); + for (int k = 0; k < 4; k++) { + std::pair new_cell = { cell.first + di[k], cell.second + dj[k] }; + if (inside(new_cell) && !visited[new_cell.first][new_cell.second]) { + if (mapString[new_cell.first][new_cell.second][0] == '.') { + cellsInQueue.push({ new_cell.first, new_cell.second }); + visited[new_cell.first][new_cell.second] = 1; + visitedCells.push_back({ new_cell.first, new_cell.second }); + } + else if (mapString[new_cell.first][new_cell.second][0] == 'M') { + std::queue> queueForDoor; + queueForDoor.push(new_cell); + visited2[new_cell.first][new_cell.second] = 1; + while (queueForDoor.size() > 0) { + std::pair cell_for_door = queueForDoor.front(); + queueForDoor.pop(); + for (int k2 = 0; k2 < 8; k2++) { + std::pair new_cell_for_door = cell_for_door; + new_cell_for_door.first += di[k2]; + new_cell_for_door.second += dj[k2]; + if (inside2(new_cell_for_door) && !visited2[new_cell_for_door.first][new_cell_for_door.second] && mapString[new_cell_for_door.first][new_cell_for_door.second] == mapString[new_cell.first][new_cell.second]) { + visited2[new_cell_for_door.first][new_cell_for_door.second] = 1; + queueForDoor.push(new_cell_for_door); + } + } + } + } + } + } + } + if (cnt < 100) { + for (int k = 0; k < visitedCells.size(); k++) { + std::pair cell = visitedCells[k]; + enclosed[cell.first][cell.second] = 1; + } + } + } +} + void Map::draw() { for (int i = 0; i < this->map.size(); ++i) diff --git a/DeadZone/source/Map/Map.h b/DeadZone/source/Map/Map.h index d1eb779..d28d37c 100644 --- a/DeadZone/source/Map/Map.h +++ b/DeadZone/source/Map/Map.h @@ -61,6 +61,7 @@ class Map static void putShopInGoodArea(); static std::string generateProceduralMap(const int& width, const int& height); static void clearSpawnArea(); + static void createEnclosedAreas(); // Getters std::vector>>& getMap() { return this->map; }