Wrap generator in Randomizer class

This commit is contained in:
gymnast86
2026-04-09 15:38:56 -07:00
parent 679044f33d
commit 6c55f42ce2
17 changed files with 225 additions and 245 deletions
-2
View File
@@ -1389,8 +1389,6 @@ set(DUSK_FILES
src/dusk/randomizer/logic/flatten/flatten.hpp
src/dusk/randomizer/logic/flatten/simplify_algebraic.cpp
src/dusk/randomizer/logic/flatten/simplify_algebraic.hpp
src/dusk/randomizer/logic/generate.cpp
src/dusk/randomizer/logic/generate.hpp
src/dusk/randomizer/logic/item.cpp
src/dusk/randomizer/logic/item.hpp
src/dusk/randomizer/logic/item_pool.cpp
+3 -5
View File
@@ -2,6 +2,7 @@
#include "search.hpp"
#include "world.hpp"
#include "../randomizer.hpp"
#include <algorithm>
#include <iostream>
@@ -10,15 +11,12 @@
namespace randomizer::logic::area
{
int LocationAccess::_idCounter = 0;
int Area::_idCounter = 0;
LocationAccess::LocationAccess(randomizer::logic::location::Location* loc,
const randomizer::logic::requirement::Requirement& req,
Area* area):
_loc(loc), _req(std::move(req)), _area(area)
{
this->_id = this->_idCounter++;
this->_id = area->GetWorld()->GetRandomizer()->GetNewLocAccID();
}
randomizer::logic::location::Location* LocationAccess::GetLocation() const
@@ -63,7 +61,7 @@ namespace randomizer::logic::area
Area::Area(const std::string& name, randomizer::logic::world::World* world): _name(name), _world(world)
{
this->_id = this->_idCounter++;
this->_id = world->GetRandomizer()->GetNewAreaID();
}
std::string Area::GetName() const
-4
View File
@@ -36,8 +36,6 @@ namespace randomizer::logic::area
int GetID() const;
private:
static int _idCounter;
int _id = -1;
randomizer::logic::location::Location* _loc = nullptr;
randomizer::logic::requirement::Requirement _req;
@@ -97,8 +95,6 @@ namespace randomizer::logic::area
void AssignHintRegionsAndDungeonLocations();
private:
static int _idCounter;
int _id = -1;
std::string _name = "";
std::string _hardAssignedRegion = "";
-112
View File
@@ -1,112 +0,0 @@
#include "generate.hpp"
#include "entrance_shuffle.hpp"
#include "fill.hpp"
#include "flatten/flatten.hpp"
#include "plandomizer.hpp"
#include "search.hpp"
#include "spoiler_log.hpp"
#include "../seedgen/config.hpp"
#include "../seedgen/settings.hpp"
#include "../utility/log.hpp"
#include "../utility/time.hpp"
#include <iostream>
namespace randomizer::logic::generate
{
randomizer::logic::world::WorldPool GenerateWorlds()
{
randomizer::utility::time::ScopedTimer<"Seed generation took ", std::chrono::milliseconds> timer;
randomizer::seedgen::config::Config config;
config.LoadFromFile(SETTINGS_PATH, PREFERENCES_PATH);
randomizer::utility::platform::Log(std::string("Seed: ") + config.GetSeed());
randomizer::logic::world::WorldPool worlds = {};
GenerateRandomizer(config, worlds);
return std::move(worlds);
}
void GenerateRandomizer(randomizer::seedgen::config::Config& config, randomizer::logic::world::WorldPool& worlds)
{
randomizer::seedgen::config::SeedRNG(config, true, false);
// Set the hash now before anything else random is decided. This allows us to show the hash for a seed
// before generating it later
auto hash = config.GetHash();
randomizer::utility::platform::Log(std::string("Hash: ") + hash);
// Build all worlds
int worldId = 1;
for (const auto& settings : config.GetSettingsList())
{
std::unique_ptr<randomizer::logic::world::World> world = std::make_unique<randomizer::logic::world::World>(worldId++);
world->SetSettings(settings);
world->ResolveRandomSettings();
world->ResolveConflictingSettings();
world->Build();
worlds.emplace_back(std::move(world));
}
// Give each world a pointer to the world pool
for (auto& world : worlds)
{
world->SetWorlds(&worlds);
}
// Process Plando Data for all worlds
if (config.IsUsingPlandomizer())
{
randomizer::logic::plandomizer::LoadPlandomizerData(worlds, config.GetPlandomizerPath());
}
// Pre Entrance Shuffle Tasks
for (auto& world : worlds)
{
world->PerformPreEntranceShuffleTasks();
}
randomizer::utility::platform::Log("Shuffling Entrances...");
for (auto& world : worlds)
{
randomizer::logic::entrance_shuffle::ShuffleWorldEntrances(world.get(), worlds);
}
// Post Entrance Shuffle Tasks
for (auto& world : worlds)
{
world->PerformPostEntranceShuffleTasks();
}
randomizer::logic::fill::CacheExitTimeForms(worlds);
// Flattening isn't used for anything yet, but flattens down the requirements for
// each location and entrance into a single statement. This will be useful for hints and could potentially
// be used to speed up the fill algorithm (but the fill algorithm is already pretty fast, so we'd only gain maybe like
// 0.2 seconds back or something)
randomizer::utility::platform::Log("Flattening...");
FlattenSearch search = FlattenSearch(worlds.at(0).get());
search.doSearch();
randomizer::utility::platform::Log("Filling Worlds...");
randomizer::logic::fill::FillWorlds(worlds);
// Post Fill Tasks
for (auto& world : worlds)
{
world->PerformPostFillTasks();
}
// Generate Playthrough
randomizer::logic::search::GeneratePlaythrough(&worlds);
// TODO: Generate Hints
// Write Logs
if (config.IsGeneratingSpoilerLog())
{
randomizer::logic::spoiler_log::GenerateSpoilerLog(worlds, config);
}
randomizer::logic::spoiler_log::GenerateAntiSpoilerLog(worlds, config);
}
} // namespace randomizer::logic::generate
-24
View File
@@ -1,24 +0,0 @@
#pragma once
#include "world.hpp"
#include "../seedgen/config.hpp"
namespace randomizer::logic::generate
{
/**
* @brief Generates a complete randomizer seed
*
* @param worlds The list of worlds for the generated randomizer seed
* @return the worldpool which was generated
*/
randomizer::logic::world::WorldPool GenerateWorlds();
/**
* @brief Generates a complete randomizer seed with the provided config
*
* @param config The configuration to use for this seed
* @param worlds The list of worlds for the generated randomizer seed
* @return 0 if no errors. 1 if there were errors
*/
void GenerateRandomizer(randomizer::seedgen::config::Config& config, randomizer::logic::world::WorldPool& worlds);
} // namespace randomizer::logic::generate
+10 -8
View File
@@ -1,6 +1,7 @@
#include "search.hpp"
#include "world.hpp"
#include "../randomizer.hpp"
#include "../utility/general.hpp"
#include "../utility/platform.hpp"
@@ -520,11 +521,12 @@ namespace randomizer::logic::search
return std::nullopt;
}
void GeneratePlaythrough(randomizer::logic::world::WorldPool* worlds)
void GeneratePlaythrough(randomizer::Randomizer* randomizer)
{
auto& worlds = randomizer->GetWorlds();
LOG_TO_DEBUG("Generating Playthrough");
// Generate Initial Playthrough
auto playthroughSearch = Search::Playthrough(worlds);
auto playthroughSearch = Search::Playthrough(&worlds);
playthroughSearch.SearchWorlds();
auto& playthroughSpheres = playthroughSearch._playthroughSpheres;
@@ -542,7 +544,7 @@ namespace randomizer::logic::search
}
// Remove all items from locations that are not part of the playthrough set
for (const auto& world : *worlds)
for (const auto& world : worlds)
{
for (const auto& location : world->GetAllLocations())
{
@@ -567,7 +569,7 @@ namespace randomizer::logic::search
// If the game is beatable, temporarily take this item away and erase the location from the playthrough
// locations
if (GameBeatable(worlds))
if (GameBeatable(&worlds))
{
tempEmptyLocations[location] = itemAtLocation;
playthroughLocationsSet.erase(location);
@@ -581,7 +583,7 @@ namespace randomizer::logic::search
// Generate a new playthrough search incase some spheres were flattened by the previous generation having access
// to extra items
auto newSearch = Search::Playthrough(worlds);
auto newSearch = Search::Playthrough(&worlds);
newSearch.SearchWorlds();
// Now do the same process for entrances to pare down the entrance playthrough
@@ -594,7 +596,7 @@ namespace randomizer::logic::search
for (const auto& entrance : sphereCopy)
{
auto connectedArea = entrance->Disconnect();
if (GameBeatable(worlds))
if (GameBeatable(&worlds))
{
// If the game is still beatable then this entrance is not required
sphere.erase(std::remove(sphere.begin(), sphere.end(), entrance), sphere.end());
@@ -636,8 +638,8 @@ namespace randomizer::logic::search
// Remove any empty spheres
newSearch.RemoveEmptySpheres();
worlds->at(0)->SetPlaythroughSpheres(newSearch._playthroughSpheres);
worlds->at(0)->SetEntranceSpheres(newSearch._entranceSpheres);
randomizer->GetPlaythroughSpheres() = newSearch._playthroughSpheres;
randomizer->GetEntranceSpheres() = newSearch._entranceSpheres;
}
bool GameBeatable(randomizer::logic::world::WorldPool* worlds, const randomizer::logic::item_pool::ItemPool& items /* = {} */)
+6 -1
View File
@@ -12,6 +12,11 @@
#include <optional>
// Forward Declarations (we have a lot here)
namespace randomizer
{
class Randomizer;
}
namespace randomizer::logic::world
{
class World;
@@ -156,6 +161,6 @@ namespace randomizer::logic::search
*/
std::optional<std::string> VerifyLogic(randomizer::logic::world::WorldPool* worlds,
const randomizer::logic::item_pool::ItemPool& items = {});
void GeneratePlaythrough(randomizer::logic::world::WorldPool* worlds);
void GeneratePlaythrough(randomizer::Randomizer* randomizer);
bool GameBeatable(randomizer::logic::world::WorldPool* worlds, const randomizer::logic::item_pool::ItemPool& items = {});
} // namespace randomizer::logic::search
+20 -16
View File
@@ -1,6 +1,7 @@
#include "spoiler_log.hpp"
#include "entrance_shuffle.hpp"
#include "../randomizer.hpp"
#include "../utility/file.hpp"
#include "../utility/platform.hpp"
#include "../utility/yaml.hpp"
@@ -28,23 +29,23 @@ namespace randomizer::logic::spoiler_log
return entrance->GetAlias() + ": " + spaces + replacement->GetAliasFrom();
}
void LogBasicInfo(std::ofstream& log, randomizer::seedgen::config::Config& config, randomizer::logic::world::WorldPool& worlds)
void LogBasicInfo(std::ofstream& log, randomizer::Randomizer* randomizer)
{
log << "Dusk Randomizer Version: " << "1.0.0" << std::endl;
log << "Seed: " << config.GetSeed() << std::endl;
log << "Seed: " << randomizer->GetConfig().GetSeed() << std::endl;
// TODO: Setting string
log << "Hash: " << config.GetHash() << std::endl;
log << "Hash: " << randomizer->GetConfig().GetHash() << std::endl;
}
void LogSettings(std::ofstream& log, randomizer::seedgen::config::Config& config, randomizer::logic::world::WorldPool& worlds)
void LogSettings(std::ofstream& log, randomizer::Randomizer* randomizer)
{
log << std::endl << "# Settings" << std::endl;
log << YAML::Dump(config.SettingsToYaml()) << std::endl;
log << YAML::Dump(randomizer->GetConfig().SettingsToYaml()) << std::endl;
}
void GenerateSpoilerLog(randomizer::logic::world::WorldPool& worlds, randomizer::seedgen::config::Config& config)
void GenerateSpoilerLog(randomizer::Randomizer* randomizer)
{
randomizer::utility::platform::Log("Generating Spoiler Log");
@@ -54,11 +55,14 @@ namespace randomizer::logic::spoiler_log
randomizer::utility::file::create_directories(LOGS_PATH);
}
auto& config = randomizer->GetConfig();
auto& worlds = randomizer->GetWorlds();
std::string filepath = std::string(LOGS_PATH) + config.GetHash() + " Spoiler Log.txt";
std::ofstream spoilerLog;
spoilerLog.open(filepath);
LogBasicInfo(spoilerLog, config, worlds);
LogBasicInfo(spoilerLog, randomizer);
// Gather worlds with starting inventories
std::list<randomizer::logic::world::World*> worldswithStartingInventories = {};
@@ -87,7 +91,7 @@ namespace randomizer::logic::spoiler_log
// Get name lengths for pretty formatting
size_t longestNameLength = 0;
for (const auto& sphere : worlds.at(0)->GetPlaythroughSpheres())
for (const auto& sphere : randomizer->GetPlaythroughSpheres())
{
for (const auto& location : sphere)
{
@@ -98,7 +102,7 @@ namespace randomizer::logic::spoiler_log
// Print playthrough
int sphereNum = 0;
spoilerLog << std::endl << "Playthrough:" << std::endl;
for (auto& sphere : worlds.at(0)->GetPlaythroughSpheres())
for (auto& sphere : randomizer->GetPlaythroughSpheres())
{
sphereNum += 1;
spoilerLog << " Sphere " << sphereNum << ":" << std::endl;
@@ -111,7 +115,7 @@ namespace randomizer::logic::spoiler_log
// Get name lengths for pretty formatting
longestNameLength = 0;
for (const auto& sphere : worlds.at(0)->GetEntranceSpheres())
for (const auto& sphere : randomizer->GetEntranceSpheres())
{
for (const auto& entrance : sphere)
{
@@ -125,7 +129,7 @@ namespace randomizer::logic::spoiler_log
{
spoilerLog << std::endl << "Entrance Playthrough:" << std::endl;
}
for (auto& sphere : worlds.at(0)->GetEntranceSpheres())
for (auto& sphere : randomizer->GetEntranceSpheres())
{
sphereNum += 1;
if (sphere.empty())
@@ -220,14 +224,14 @@ namespace randomizer::logic::spoiler_log
// TODO: Hints
// Log Settings
LogSettings(spoilerLog, config, worlds);
LogSettings(spoilerLog, randomizer);
spoilerLog.close();
randomizer::utility::platform::Log("Wrote spoiler log to " + filepath);
}
void GenerateAntiSpoilerLog(randomizer::logic::world::WorldPool& worlds, randomizer::seedgen::config::Config& config)
void GenerateAntiSpoilerLog(randomizer::Randomizer* randomizer)
{
// Create logs folder if it doesn't exist
if (!randomizer::utility::file::dirExists(LOGS_PATH))
@@ -235,11 +239,11 @@ namespace randomizer::logic::spoiler_log
randomizer::utility::file::create_directories(LOGS_PATH);
}
std::string filepath = std::string(LOGS_PATH) + config.GetHash() + " Anti-Spoiler Log.txt";
std::string filepath = std::string(LOGS_PATH) + randomizer->GetConfig().GetHash() + " Anti-Spoiler Log.txt";
std::ofstream antiSpoilerLog;
antiSpoilerLog.open(filepath);
LogBasicInfo(antiSpoilerLog, config, worlds);
LogSettings(antiSpoilerLog, config, worlds);
LogBasicInfo(antiSpoilerLog, randomizer);
LogSettings(antiSpoilerLog, randomizer);
}
} // namespace randomizer::logic::spoiler_log
+7 -4
View File
@@ -1,10 +1,13 @@
#pragma once
#include "world.hpp"
#include "../seedgen/config.hpp"
// Forward Declarations
namespace randomizer
{
class Randomizer;
}
namespace randomizer::logic::spoiler_log
{
void GenerateSpoilerLog(randomizer::logic::world::WorldPool& worlds, randomizer::seedgen::config::Config& config);
void GenerateAntiSpoilerLog(randomizer::logic::world::WorldPool& worlds, randomizer::seedgen::config::Config& config);
void GenerateSpoilerLog(randomizer::Randomizer* randomizer);
void GenerateAntiSpoilerLog(randomizer::Randomizer* randomizer);
} // namespace randomizer::logic::spoiler_log
+13 -31
View File
@@ -2,6 +2,7 @@
#include "search.hpp"
#include "../randomizer.hpp"
#include "../utility/exception.hpp"
#include "../utility/file.hpp"
#include "../utility/general.hpp"
@@ -17,12 +18,9 @@
namespace randomizer::logic::world
{
int World::_eventIdCounter = 0;
World::World(const int& id)
{
this->_id = id;
}
World::World(const int& id, randomizer::Randomizer* randomizer) :
_id(id), _randomizer(randomizer)
{}
int World::GetID() const
{
@@ -36,9 +34,13 @@ namespace randomizer::logic::world
{
return this->_settings;
}
void World::SetWorlds(WorldPool* worlds)
void World::SetRandomizer(Randomizer* randomizer)
{
_worlds = worlds;
this->_randomizer = randomizer;
}
Randomizer* World::GetRandomizer() const
{
return this->_randomizer;
}
void World::ResolveRandomSettings()
@@ -773,8 +775,8 @@ namespace randomizer::logic::world
// Check if the game is beatable, set dungeon as required if so. If the dungeon is not required and barren
// unrequired dungeons is on, then set all the locations in the unrequired dungeon as nonprogress.
auto completeItemPool = randomizer::logic::item_pool::GetCompleteItemPool(*(this->_worlds));
if (!randomizer::logic::search::GameBeatable(this->_worlds, completeItemPool))
auto completeItemPool = randomizer::logic::item_pool::GetCompleteItemPool(this->_randomizer->GetWorlds());
if (!randomizer::logic::search::GameBeatable(&(this->_randomizer->GetWorlds()), completeItemPool))
{
dungeon->SetRequired(true);
}
@@ -1123,7 +1125,7 @@ namespace randomizer::logic::world
// Add the event if it doesn't exist yet
if (!this->_eventIndexes.contains(eventName))
{
auto index = this->_eventIdCounter++;
auto index = this->_randomizer->GetNewEventID();
this->_eventIndexes.emplace(eventName, index);
this->_eventNames.emplace(index, eventName);
LOG_TO_DEBUG("Event \"" + eventName + "\" was assigned eventIndex " + std::to_string(index));
@@ -1151,24 +1153,4 @@ namespace randomizer::logic::world
}
return settings.GetMap().at(settingName);
}
void World::SetPlaythroughSpheres(const std::list<std::list<randomizer::logic::location::Location*>>& playthroughSpheres)
{
this->_playthroughSpheres = playthroughSpheres;
}
std::list<std::list<randomizer::logic::location::Location*>> World::GetPlaythroughSpheres() const
{
return this->_playthroughSpheres;
}
void World::SetEntranceSpheres(const std::list<std::list<randomizer::logic::entrance::Entrance*>>& entranceSpheres)
{
this->_entranceSpheres = entranceSpheres;
}
std::list<std::list<randomizer::logic::entrance::Entrance*>> World::GetEntranceSpheres() const
{
return this->_entranceSpheres;
}
} // namespace randomizer::logic::world
+10 -14
View File
@@ -19,6 +19,11 @@
#include <iostream>
// Forward Declarations
namespace randomizer
{
class Randomizer;
}
namespace randomizer::logic::search
{
class Search;
@@ -32,12 +37,13 @@ namespace randomizer::logic::world
class World
{
public:
World(const int& id);
World(const int& id, randomizer::Randomizer* randomizer);
int GetID() const;
void SetSettings(const randomizer::seedgen::settings::Settings& settings);
const randomizer::seedgen::settings::Settings& GetSettings() const;
void SetWorlds(WorldPool* worlds);
void SetRandomizer(Randomizer* randomizer);
Randomizer* GetRandomizer() const;
/**
* @brief Resolves all remaining random settings within a specific world
@@ -133,16 +139,10 @@ namespace randomizer::logic::world
std::string GetEventName(const int& eventIndex);
randomizer::seedgen::settings::Setting& Setting(const std::string& settingName);
void SetPlaythroughSpheres(const std::list<std::list<randomizer::logic::location::Location*>>& playthroughSpheres);
std::list<std::list<randomizer::logic::location::Location*>> GetPlaythroughSpheres() const;
void SetEntranceSpheres(const std::list<std::list<randomizer::logic::entrance::Entrance*>>& entranceSpheres);
std::list<std::list<randomizer::logic::entrance::Entrance*>> GetEntranceSpheres() const;
private:
int _id = -1;
static int _eventIdCounter; // Needs to be shared for events across all worlds
int _entranceIdCounter = 0; // Specific for this world
int _entranceIdCounter = 0;
randomizer::seedgen::settings::Settings _settings;
std::map<std::string, std::unique_ptr<randomizer::logic::item::Item>> _itemTable = {};
@@ -159,14 +159,10 @@ namespace randomizer::logic::world
randomizer::logic::item_pool::ItemPool _startingItemPool = {};
std::unordered_map<randomizer::logic::entrance::Entrance*, int> _exitTimeFormCache = {};
// Playthroughs will be stored in world 0 for convenience
std::list<std::list<randomizer::logic::location::Location*>> _playthroughSpheres = {};
std::list<std::list<randomizer::logic::entrance::Entrance*>> _entranceSpheres = {};
// Plandomizer Data
std::unordered_map<randomizer::logic::location::Location*, randomizer::logic::item::Item*> _plandomizerLocations = {};
std::unordered_map<randomizer::logic::entrance::Entrance*, randomizer::logic::entrance::Entrance*> _plandomizerEntrances = {};
WorldPool* _worlds = nullptr;
Randomizer* _randomizer = nullptr;
};
} // namespace randomizer::logic::world
+1
View File
@@ -58,5 +58,6 @@ string(LENGTH "${CMAKE_SOURCE_DIR}/" SOURCE_PATH_SIZE)
set(GAME_COMPILE_DEFS ${GAME_COMPILE_DEFS} SOURCE_PATH_SIZE=${SOURCE_PATH_SIZE})
set(GAME_LIBS ${GAME_LIBS} yaml-cpp::yaml-cpp zlib base64pp)
make_directory("${CMAKE_BINARY_DIR}/randomizer")
# Put data files together for easier manipulation
# file(COPY "${CMAKE_SOURCE_DIR}/src/dusk/randomizer/data/" DESTINATION "${CMAKE_BINARY_DIR}/randomizer/data/" REGEX "^.*example.*$" EXCLUDE) # World, macros, and location info
+103 -16
View File
@@ -1,29 +1,116 @@
#include "randomizer.hpp"
#include "logic/generate.hpp"
#include "logic/entrance_shuffle.hpp"
#include "logic/fill.hpp"
#include "logic/flatten/flatten.hpp"
#include "logic/plandomizer.hpp"
#include "logic/search.hpp"
#include "logic/spoiler_log.hpp"
#include "logic/world.hpp"
#include "test/test.hpp"
#include "seedgen/config.hpp"
#include "seedgen/settings.hpp"
#include "utility/log.hpp"
#include "utility/time.hpp"
#include <iostream>
int randomizerMain()
namespace randomizer
{
try
int Randomizer::Generate()
{
#ifdef LOGIC_TESTS
randomizer::test::test::RunTests();
try
{
GenerateWorlds();
}
catch(const std::exception& e)
{
std::cout << "============================================================" << std::endl;
std::cout << "The following exception occured: " << e.what() << std::endl;
return 1;
}
return 0;
#else
auto worlds = randomizer::logic::generate::GenerateWorlds();
#endif
}
catch(const std::exception& e)
{
std::cout << "============================================================" << std::endl;
std::cout << "The following exception occured: " << e.what() << std::endl;
return 1;
}
return 0;
}
void Randomizer::GenerateWorlds()
{
utility::time::ScopedTimer<"Seed generation took ", std::chrono::milliseconds> timer;
this->_worlds.clear();
this->_config.LoadFromFile(SETTINGS_PATH, PREFERENCES_PATH);
utility::platform::Log(std::string("Seed: ") + this->_config.GetSeed());
seedgen::config::SeedRNG(this->_config, true, false);
// Set the hash now before anything else random is decided. This allows us to show the hash for a seed
// before generating it later
auto hash = this->_config.GetHash();
utility::platform::Log(std::string("Hash: ") + hash);
// Build all worlds
int worldId = 1;
for (const auto& settings : this->_config.GetSettingsList())
{
std::unique_ptr<logic::world::World> world = std::make_unique<logic::world::World>(worldId++, this);
world->SetSettings(settings);
world->ResolveRandomSettings();
world->ResolveConflictingSettings();
world->Build();
this->_worlds.emplace_back(std::move(world));
}
// Process Plando Data for all worlds
if (this->_config.IsUsingPlandomizer())
{
logic::plandomizer::LoadPlandomizerData(this->_worlds, this->_config.GetPlandomizerPath());
}
// Pre Entrance Shuffle Tasks
for (auto& world : this->_worlds)
{
world->PerformPreEntranceShuffleTasks();
}
utility::platform::Log("Shuffling Entrances...");
for (auto& world : this->_worlds)
{
logic::entrance_shuffle::ShuffleWorldEntrances(world.get(), this->_worlds);
}
// Post Entrance Shuffle Tasks
for (auto& world : this->_worlds)
{
world->PerformPostEntranceShuffleTasks();
}
logic::fill::CacheExitTimeForms(this->_worlds);
// Flattening isn't used for anything yet, but flattens down the requirements for
// each location and entrance into a single statement. This will be useful for hints and could potentially
// be used to speed up the fill algorithm (but the fill algorithm is already pretty fast, so we'd only gain maybe like
// 0.2 seconds back or something)
utility::platform::Log("Flattening...");
FlattenSearch search = FlattenSearch(this->_worlds.at(0).get());
search.doSearch();
utility::platform::Log("Filling Worlds...");
logic::fill::FillWorlds(this->_worlds);
// Post Fill Tasks
for (auto& world : this->_worlds)
{
world->PerformPostFillTasks();
}
// Generate Playthrough
logic::search::GeneratePlaythrough(this);
// TODO: Generate Hints
// Write Logs
if (this->_config.IsGeneratingSpoilerLog())
{
logic::spoiler_log::GenerateSpoilerLog(this);
}
logic::spoiler_log::GenerateAntiSpoilerLog(this);
}
} // namespace randomizer
+39 -1
View File
@@ -1,3 +1,41 @@
#pragma once
int randomizerMain();
#include "logic/world.hpp"
namespace randomizer
{
class Randomizer
{
public:
explicit Randomizer() = default;
/**
* @brief Generates a complete randomizer seed
*
* @return 0 if no errors. 1 if there were errors
*/
int Generate();
void GenerateWorlds();
auto& GetConfig() { return this->_config; }
auto& GetWorlds() { return this->_worlds; }
int GetNewEventID() { return ++(this->_eventIdCounter); }
int GetNewAreaID() { return ++(this->_areaIdCounter); }
int GetNewLocAccID() { return ++(this->_locAccIdCounter); }
auto& GetPlaythroughSpheres() { return this->_playthroughSpheres; }
auto& GetEntranceSpheres() { return this->_entranceSpheres; }
private:
seedgen::config::Config _config{};
logic::world::WorldPool _worlds{};
int _eventIdCounter{};
int _areaIdCounter{};
int _locAccIdCounter{};
// Playthrough data
std::list<std::list<logic::location::Location*>> _playthroughSpheres{};
std::list<std::list<logic::entrance::Entrance*>> _entranceSpheres{};
};
} // namespace randomizer
+4 -4
View File
@@ -1,7 +1,6 @@
#include "test.hpp"
#include "../logic/generate.hpp"
#include "../logic/world.hpp"
#include "../randomizer.hpp"
#include "../utility/string.hpp"
#include <filesystem>
@@ -23,11 +22,12 @@ namespace randomizer::test::test
std::cout << "Testing " << testName << std::endl;
try {
randomizer::logic::generate::GenerateWorlds();
randomizer::Randomizer r{};
r.GenerateWorlds();
}
catch(const std::exception& e) {
std::cout << "Test \"" << testName << "\" failed! Failed settings saved to " << SETTINGS_PATH << std::endl;
std::cout << "Error Message:" << std::endl;
std::cout << "Error Message: " << std::endl;
throw e;
}
+2 -2
View File
@@ -30,7 +30,7 @@ namespace randomizer::utility::log
#ifdef RANDO_ERROR_LOG
output.open(LOG_PATH);
output << "Program opened " << randomizer::utility::time::ProgramTime::getDateStr(); // time string ends with \n
output << "Twilight Princess HD Randomizer Version " << RANDOMIZER_VERSION << std::endl;
output << "Dusk Randomizer Version " << RANDOMIZER_VERSION << std::endl;
output << std::endl << std::endl;
#endif
}
@@ -77,7 +77,7 @@ namespace randomizer::utility::log
{
output.open(LOG_PATH);
output << "Program opened " << randomizer::utility::time::ProgramTime::getDateStr(); // time string ends with \n
output << "Twilight Princess HD Randomizer Version " << RANDOMIZER_VERSION << std::endl;
output << "Dusk Randomizer Version " << RANDOMIZER_VERSION << std::endl;
output << std::endl << std::endl;
}
+7 -1
View File
@@ -63,6 +63,7 @@
#if RANDOMIZER_ONLY
#include "dusk/randomizer/randomizer.hpp"
#include "dusk/randomizer/test/test.hpp"
#endif
// --- GLOBALS ---
@@ -288,7 +289,12 @@ static const char* CalculateConfigPath() {
int game_main(int argc, char* argv[]) {
#if RANDOMIZER_ONLY
randomizerMain();
#ifdef LOGIC_TESTS
randomizer::test::test::RunTests();
#else
randomizer::Randomizer rando{};
rando.Generate();
#endif
exit(0);
#endif