1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Add option for single-thread generation. Still doesn't guarantee excactly identical maps :?

This commit is contained in:
Tomasz Zieliński 2023-05-24 18:02:11 +02:00
parent edf47f5769
commit cd9bd491e0
3 changed files with 57 additions and 33 deletions

View File

@ -83,6 +83,7 @@ void CMapGenerator::loadConfig()
config.secondaryRoadType = "";
if(!mapGenOptions.isRoadEnabled(config.defaultRoadType))
config.defaultRoadType = config.secondaryRoadType;
config.singleThread = randomMapJson["singleThread"].Bool();
}
const CMapGenerator::Config & CMapGenerator::getConfig() const
@ -299,7 +300,7 @@ void CMapGenerator::fillZones()
//we need info about all town types to evaluate dwellings and pandoras with creatures properly
//place main town in the middle
Load::Progress::setupStepsTill(numZones, 50);
for (const auto& it : map->getZones())
{
@ -310,51 +311,74 @@ void CMapGenerator::fillZones()
std::vector<std::shared_ptr<Zone>> treasureZones;
ThreadPool pool;
std::vector<boost::future<void>> futures;
//At most one Modificator can run for every zone
pool.init(std::min<int>(boost::thread::hardware_concurrency(), numZones));
TModificators allJobs;
for (auto & it : map->getZones())
for (auto& it : map->getZones())
{
allJobs.splice(allJobs.end(), it.second->getModificators());
}
Load::Progress::setupStepsTill(allJobs.size(), 240);
while (!allJobs.empty())
if (config.singleThread) //No thread pool, just queue with deterministic order
{
for (auto it = allJobs.begin(); it != allJobs.end();)
while (!allJobs.empty())
{
if ((*it)->isFinished())
for (auto it = allJobs.begin(); it != allJobs.end();)
{
it = allJobs.erase(it);
Progress::Progress::step();
}
else if ((*it)->isReady())
{
auto jobCopy = *it;
futures.emplace_back(pool.async([this, jobCopy]() -> void
{
jobCopy->run();
Progress::Progress::step(); //Update progress bar
}
));
it = allJobs.erase(it);
}
else
{
++it;
if ((*it)->isReady())
{
auto jobCopy = *it;
jobCopy->run();
Progress::Progress::step(); //Update progress bar
allJobs.erase(it);
break; //Restart from the first job
}
else
{
++it;
}
}
}
}
//Wait for all the tasks
for (auto& fut : futures)
else
{
fut.get();
ThreadPool pool;
std::vector<boost::future<void>> futures;
//At most one Modificator can run for every zone
pool.init(std::min<int>(boost::thread::hardware_concurrency(), numZones));
while (!allJobs.empty())
{
for (auto it = allJobs.begin(); it != allJobs.end();)
{
if ((*it)->isFinished())
{
it = allJobs.erase(it);
Progress::Progress::step();
}
else if ((*it)->isReady())
{
auto jobCopy = *it;
futures.emplace_back(pool.async([this, jobCopy]() -> void
{
jobCopy->run();
Progress::Progress::step(); //Update progress bar
}
));
it = allJobs.erase(it);
}
else
{
++it;
}
}
}
//Wait for all the tasks
for (auto& fut : futures)
{
fut.get();
}
}
for (const auto& it : map->getZones())

View File

@ -47,6 +47,7 @@ public:
int pandoraMultiplierGold, pandoraMultiplierExperience, pandoraMultiplierSpells, pandoraSpellSchool, pandoraSpell60;
std::vector<int> pandoraCreatureValues;
std::vector<int> questValues, questRewardValues;
bool singleThread;
};
explicit CMapGenerator(CMapGenOptions& mapGenOptions, int RandomSeed = std::time(nullptr));

View File

@ -42,7 +42,6 @@ void ObstaclePlacer::process()
blockedArea.subtract(zone.areaUsed());
zone.areaPossible().subtract(blockedArea);
//TODO: Set prohibited area in ObstacleProxy :?
prohibitedArea = zone.freePaths() + zone.areaUsed() + manager->getVisitableArea();
auto objs = createObstacles(zone.getRand());