From 810a2745b407f8b3fe3cbe7bb344847b7a5a1cad Mon Sep 17 00:00:00 2001 From: jbzdarkid Date: Sat, 11 Sep 2021 10:40:27 -0700 Subject: Fix a bug where re-randomization could cause inconsistency Closes #8. Co-authored-by: Star Rauchenberger # Conflicts: # App/Version.h # Source/Randomizer.h --- App/Version.h | 2 +- Source/Randomizer.cpp | 39 +++++++++++++++++++++++++-------------- Source/Randomizer.h | 5 +++-- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/App/Version.h b/App/Version.h index 1541697..bdb584e 100644 --- a/App/Version.h +++ b/App/Version.h @@ -5,7 +5,7 @@ #define MAJOR 6 #define MINOR 0 -#define PATCH 0 +#define PATCH 1 #define VERSION_STR TO_STRING(MAJOR) L"." TO_STRING(MINOR) L"." TO_STRING(PATCH) #define VERSION MAJOR, MINOR, PATCH diff --git a/Source/Randomizer.cpp b/Source/Randomizer.cpp index 72072a8..c573146 100644 --- a/Source/Randomizer.cpp +++ b/Source/Randomizer.cpp @@ -188,7 +188,7 @@ void Randomizer::RandomizeTutorial() { void Randomizer::RandomizeSymmetry() { std::vector randomOrder(transparent.size(), 0); std::iota(randomOrder.begin(), randomOrder.end(), 0); - RandomizeRange(randomOrder, SWAP::NONE, 1, 5); + Shuffle(randomOrder, 1, 5); ReassignTargets(transparent, randomOrder); } @@ -230,9 +230,9 @@ void Randomizer::RandomizeShadows() { std::vector randomOrder(shadowsPanels.size(), 0); std::iota(randomOrder.begin(), randomOrder.end(), 0); - RandomizeRange(randomOrder, SWAP::NONE, 0, 8); // Tutorial - RandomizeRange(randomOrder, SWAP::NONE, 8, 16); // Avoid - RandomizeRange(randomOrder, SWAP::NONE, 16, 21); // Follow + Shuffle(randomOrder, 0, 8); // Tutorial + Shuffle(randomOrder, 8, 16); // Avoid + Shuffle(randomOrder, 16, 21); // Follow ReassignTargets(shadowsPanels, randomOrder); // Turn off original starting panel _memory->WriteEntityData(shadowsPanels[0], POWER, {0.0f, 0.0f}); @@ -244,7 +244,7 @@ void Randomizer::RandomizeTown() { // @Hack...? To open the gate at the end std::vector randomOrder(orchard.size() + 1, 0); std::iota(randomOrder.begin(), randomOrder.end(), 0); - RandomizeRange(randomOrder, SWAP::NONE, 1, 5); + Shuffle(randomOrder, 1, 5); // Ensure that we open the gate before the final puzzle (by swapping) int panel3Index = find(randomOrder, 3); int panel4Index = find(randomOrder, 4); @@ -256,7 +256,7 @@ void Randomizer::RandomizeTown() { void Randomizer::RandomizeMonastery() { std::vector randomOrder(monasteryPanels.size(), 0); std::iota(randomOrder.begin(), randomOrder.end(), 0); - RandomizeRange(randomOrder, SWAP::NONE, 3, 9); // Outer 2 & 3, Inner 1-4 + Shuffle(randomOrder, 3, 9); // Outer 2 & 3, Inner 1-4 ReassignTargets(monasteryPanels, randomOrder); } @@ -266,10 +266,10 @@ void Randomizer::RandomizeBunker() { // Randomize Tutorial 2-Advanced Tutorial 4 + Glass 1 // Tutorial 1 cannot be randomized, since no other panel can start on // Glass 1 will become door + glass 1, due to the targetting system - RandomizeRange(randomOrder, SWAP::NONE, 1, 10); + Shuffle(randomOrder, 1, 10); // Randomize Glass 1-3 into everything after the door/glass 1 const size_t glass1Index = find(randomOrder, 9); - RandomizeRange(randomOrder, SWAP::NONE, glass1Index + 1, 12); + Shuffle(randomOrder, glass1Index + 1, 12); ReassignTargets(bunkerPanels, randomOrder); } @@ -277,8 +277,8 @@ void Randomizer::RandomizeJungle() { std::vector randomOrder(junglePanels.size(), 0); std::iota(randomOrder.begin(), randomOrder.end(), 0); // Waves 1 cannot be randomized, since no other panel can start on - RandomizeRange(randomOrder, SWAP::NONE, 1, 7); // Waves 2-7 - RandomizeRange(randomOrder, SWAP::NONE, 8, 13); // Pitches 1-6 + Shuffle(randomOrder, 1, 7); // Waves 2-7 + Shuffle(randomOrder, 8, 13); // Pitches 1-6 ReassignTargets(junglePanels, randomOrder); // Fix the wall's target to point back to the cable, and the cable to point to the pitches panel. @@ -304,8 +304,8 @@ void Randomizer::RandomizeMountain() { std::vector randomOrder(pillars.size(), 0); std::iota(randomOrder.begin(), randomOrder.end(), 0); - RandomizeRange(randomOrder, SWAP::NONE, 0, 4); // Left Pillars 1-4 - RandomizeRange(randomOrder, SWAP::NONE, 5, 9); // Right Pillars 1-4 + Shuffle(randomOrder, 0, 4); // Left Pillars 1-4 + Shuffle(randomOrder, 5, 9); // Right Pillars 1-4 ReassignTargets(pillars, randomOrder, targets); // Turn off original starting panels _memory->WriteEntityData(pillars[0], POWER, {0.0f, 0.0f}); @@ -325,7 +325,7 @@ void Randomizer::RandomizeChallenge() { void Randomizer::RandomizeAudioLogs() { std::vector randomOrder(audiologs.size(), 0); std::iota(randomOrder.begin(), randomOrder.end(), 0); - Randomize(randomOrder, SWAP::NONE); + Shuffle(randomOrder, 0, randomOrder.size()); ReassignNames(audiologs, randomOrder); } @@ -334,7 +334,18 @@ void Randomizer::Randomize(std::vector& panels, int flags) { } // Range is [start, end) -void Randomizer::RandomizeRange(std::vector &panels, int flags, size_t startIndex, size_t endIndex) { +void Randomizer::Shuffle(std::vector &order, size_t startIndex, size_t endIndex) { + if (order.size() == 0) return; + if (startIndex >= endIndex) return; + if (endIndex >= order.size()) endIndex = static_cast(order.size()); + for (size_t i = endIndex - 1; i > startIndex; i--) { + const int target = Random::RandInt(static_cast(startIndex), static_cast(i)); + std::swap(order[i], order[target]); + } +} + +// Range is [start, end) +void Randomizer::RandomizeRange(std::vector panels, int flags, size_t startIndex, size_t endIndex) { if (panels.size() == 0) return; if (startIndex >= endIndex) return; if (endIndex >= panels.size()) endIndex = static_cast(panels.size()); diff --git a/Source/Randomizer.h b/Source/Randomizer.h index bd8895b..a416c98 100644 --- a/Source/Randomizer.h +++ b/Source/Randomizer.h @@ -11,7 +11,7 @@ public: void PreventSnipes(); enum SWAP { - NONE = 0, + // NONE = 0, TARGETS = 1, LINES = 2, AUDIO_NAMES = 4, @@ -36,7 +36,8 @@ private: void RandomizeAudioLogs(); void Randomize(std::vector& panels, int flags); - void RandomizeRange(std::vector &panels, int flags, size_t startIndex, size_t endIndex); + void Shuffle(std::vector&order, size_t startIndex, size_t endIndex); + void RandomizeRange(std::vector panels, int flags, size_t startIndex, size_t endIndex); void SwapPanels(int panel1, int panel2, int flags); void ReassignTargets(const std::vector& panels, const std::vector& order, std::vector targets = {}); void ReassignNames(const std::vector& panels, const std::vector& order); -- cgit 1.4.1