diff options
author | jbzdarkid <jbzdarkid@gmail.com> | 2021-09-11 10:40:27 -0700 |
---|---|---|
committer | Joseph Blackman <joblac@microsoft.com> | 2021-09-11 10:46:37 -0700 |
commit | 810a2745b407f8b3fe3cbe7bb344847b7a5a1cad (patch) | |
tree | 8896a842da6db0fdcb20a092f3cff3c2f1512730 | |
parent | b8d472ff024ad5b13dfe0c33ae10d5fdf8a2c4cc (diff) | |
download | witness-tutorializer-810a2745b407f8b3fe3cbe7bb344847b7a5a1cad.tar.gz witness-tutorializer-810a2745b407f8b3fe3cbe7bb344847b7a5a1cad.tar.bz2 witness-tutorializer-810a2745b407f8b3fe3cbe7bb344847b7a5a1cad.zip |
Fix a bug where re-randomization could cause inconsistency
Closes #8. Co-authored-by: Star Rauchenberger <fefferburbia@gmail.com> # Conflicts: # App/Version.h # Source/Randomizer.h
-rw-r--r-- | App/Version.h | 2 | ||||
-rw-r--r-- | Source/Randomizer.cpp | 39 | ||||
-rw-r--r-- | 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 @@ | |||
5 | 5 | ||
6 | #define MAJOR 6 | 6 | #define MAJOR 6 |
7 | #define MINOR 0 | 7 | #define MINOR 0 |
8 | #define PATCH 0 | 8 | #define PATCH 1 |
9 | 9 | ||
10 | #define VERSION_STR TO_STRING(MAJOR) L"." TO_STRING(MINOR) L"." TO_STRING(PATCH) | 10 | #define VERSION_STR TO_STRING(MAJOR) L"." TO_STRING(MINOR) L"." TO_STRING(PATCH) |
11 | #define VERSION MAJOR, MINOR, PATCH | 11 | #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() { | |||
188 | void Randomizer::RandomizeSymmetry() { | 188 | void Randomizer::RandomizeSymmetry() { |
189 | std::vector<int> randomOrder(transparent.size(), 0); | 189 | std::vector<int> randomOrder(transparent.size(), 0); |
190 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | 190 | std::iota(randomOrder.begin(), randomOrder.end(), 0); |
191 | RandomizeRange(randomOrder, SWAP::NONE, 1, 5); | 191 | Shuffle(randomOrder, 1, 5); |
192 | ReassignTargets(transparent, randomOrder); | 192 | ReassignTargets(transparent, randomOrder); |
193 | } | 193 | } |
194 | 194 | ||
@@ -230,9 +230,9 @@ void Randomizer::RandomizeShadows() { | |||
230 | 230 | ||
231 | std::vector<int> randomOrder(shadowsPanels.size(), 0); | 231 | std::vector<int> randomOrder(shadowsPanels.size(), 0); |
232 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | 232 | std::iota(randomOrder.begin(), randomOrder.end(), 0); |
233 | RandomizeRange(randomOrder, SWAP::NONE, 0, 8); // Tutorial | 233 | Shuffle(randomOrder, 0, 8); // Tutorial |
234 | RandomizeRange(randomOrder, SWAP::NONE, 8, 16); // Avoid | 234 | Shuffle(randomOrder, 8, 16); // Avoid |
235 | RandomizeRange(randomOrder, SWAP::NONE, 16, 21); // Follow | 235 | Shuffle(randomOrder, 16, 21); // Follow |
236 | ReassignTargets(shadowsPanels, randomOrder); | 236 | ReassignTargets(shadowsPanels, randomOrder); |
237 | // Turn off original starting panel | 237 | // Turn off original starting panel |
238 | _memory->WriteEntityData<float>(shadowsPanels[0], POWER, {0.0f, 0.0f}); | 238 | _memory->WriteEntityData<float>(shadowsPanels[0], POWER, {0.0f, 0.0f}); |
@@ -244,7 +244,7 @@ void Randomizer::RandomizeTown() { | |||
244 | // @Hack...? To open the gate at the end | 244 | // @Hack...? To open the gate at the end |
245 | std::vector<int> randomOrder(orchard.size() + 1, 0); | 245 | std::vector<int> randomOrder(orchard.size() + 1, 0); |
246 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | 246 | std::iota(randomOrder.begin(), randomOrder.end(), 0); |
247 | RandomizeRange(randomOrder, SWAP::NONE, 1, 5); | 247 | Shuffle(randomOrder, 1, 5); |
248 | // Ensure that we open the gate before the final puzzle (by swapping) | 248 | // Ensure that we open the gate before the final puzzle (by swapping) |
249 | int panel3Index = find(randomOrder, 3); | 249 | int panel3Index = find(randomOrder, 3); |
250 | int panel4Index = find(randomOrder, 4); | 250 | int panel4Index = find(randomOrder, 4); |
@@ -256,7 +256,7 @@ void Randomizer::RandomizeTown() { | |||
256 | void Randomizer::RandomizeMonastery() { | 256 | void Randomizer::RandomizeMonastery() { |
257 | std::vector<int> randomOrder(monasteryPanels.size(), 0); | 257 | std::vector<int> randomOrder(monasteryPanels.size(), 0); |
258 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | 258 | std::iota(randomOrder.begin(), randomOrder.end(), 0); |
259 | RandomizeRange(randomOrder, SWAP::NONE, 3, 9); // Outer 2 & 3, Inner 1-4 | 259 | Shuffle(randomOrder, 3, 9); // Outer 2 & 3, Inner 1-4 |
260 | ReassignTargets(monasteryPanels, randomOrder); | 260 | ReassignTargets(monasteryPanels, randomOrder); |
261 | } | 261 | } |
262 | 262 | ||
@@ -266,10 +266,10 @@ void Randomizer::RandomizeBunker() { | |||
266 | // Randomize Tutorial 2-Advanced Tutorial 4 + Glass 1 | 266 | // Randomize Tutorial 2-Advanced Tutorial 4 + Glass 1 |
267 | // Tutorial 1 cannot be randomized, since no other panel can start on | 267 | // Tutorial 1 cannot be randomized, since no other panel can start on |
268 | // Glass 1 will become door + glass 1, due to the targetting system | 268 | // Glass 1 will become door + glass 1, due to the targetting system |
269 | RandomizeRange(randomOrder, SWAP::NONE, 1, 10); | 269 | Shuffle(randomOrder, 1, 10); |
270 | // Randomize Glass 1-3 into everything after the door/glass 1 | 270 | // Randomize Glass 1-3 into everything after the door/glass 1 |
271 | const size_t glass1Index = find(randomOrder, 9); | 271 | const size_t glass1Index = find(randomOrder, 9); |
272 | RandomizeRange(randomOrder, SWAP::NONE, glass1Index + 1, 12); | 272 | Shuffle(randomOrder, glass1Index + 1, 12); |
273 | ReassignTargets(bunkerPanels, randomOrder); | 273 | ReassignTargets(bunkerPanels, randomOrder); |
274 | } | 274 | } |
275 | 275 | ||
@@ -277,8 +277,8 @@ void Randomizer::RandomizeJungle() { | |||
277 | std::vector<int> randomOrder(junglePanels.size(), 0); | 277 | std::vector<int> randomOrder(junglePanels.size(), 0); |
278 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | 278 | std::iota(randomOrder.begin(), randomOrder.end(), 0); |
279 | // Waves 1 cannot be randomized, since no other panel can start on | 279 | // Waves 1 cannot be randomized, since no other panel can start on |
280 | RandomizeRange(randomOrder, SWAP::NONE, 1, 7); // Waves 2-7 | 280 | Shuffle(randomOrder, 1, 7); // Waves 2-7 |
281 | RandomizeRange(randomOrder, SWAP::NONE, 8, 13); // Pitches 1-6 | 281 | Shuffle(randomOrder, 8, 13); // Pitches 1-6 |
282 | ReassignTargets(junglePanels, randomOrder); | 282 | ReassignTargets(junglePanels, randomOrder); |
283 | 283 | ||
284 | // Fix the wall's target to point back to the cable, and the cable to point to the pitches panel. | 284 | // 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() { | |||
304 | 304 | ||
305 | std::vector<int> randomOrder(pillars.size(), 0); | 305 | std::vector<int> randomOrder(pillars.size(), 0); |
306 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | 306 | std::iota(randomOrder.begin(), randomOrder.end(), 0); |
307 | RandomizeRange(randomOrder, SWAP::NONE, 0, 4); // Left Pillars 1-4 | 307 | Shuffle(randomOrder, 0, 4); // Left Pillars 1-4 |
308 | RandomizeRange(randomOrder, SWAP::NONE, 5, 9); // Right Pillars 1-4 | 308 | Shuffle(randomOrder, 5, 9); // Right Pillars 1-4 |
309 | ReassignTargets(pillars, randomOrder, targets); | 309 | ReassignTargets(pillars, randomOrder, targets); |
310 | // Turn off original starting panels | 310 | // Turn off original starting panels |
311 | _memory->WriteEntityData<float>(pillars[0], POWER, {0.0f, 0.0f}); | 311 | _memory->WriteEntityData<float>(pillars[0], POWER, {0.0f, 0.0f}); |
@@ -325,7 +325,7 @@ void Randomizer::RandomizeChallenge() { | |||
325 | void Randomizer::RandomizeAudioLogs() { | 325 | void Randomizer::RandomizeAudioLogs() { |
326 | std::vector<int> randomOrder(audiologs.size(), 0); | 326 | std::vector<int> randomOrder(audiologs.size(), 0); |
327 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | 327 | std::iota(randomOrder.begin(), randomOrder.end(), 0); |
328 | Randomize(randomOrder, SWAP::NONE); | 328 | Shuffle(randomOrder, 0, randomOrder.size()); |
329 | ReassignNames(audiologs, randomOrder); | 329 | ReassignNames(audiologs, randomOrder); |
330 | } | 330 | } |
331 | 331 | ||
@@ -334,7 +334,18 @@ void Randomizer::Randomize(std::vector<int>& panels, int flags) { | |||
334 | } | 334 | } |
335 | 335 | ||
336 | // Range is [start, end) | 336 | // Range is [start, end) |
337 | void Randomizer::RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex) { | 337 | void Randomizer::Shuffle(std::vector<int> &order, size_t startIndex, size_t endIndex) { |
338 | if (order.size() == 0) return; | ||
339 | if (startIndex >= endIndex) return; | ||
340 | if (endIndex >= order.size()) endIndex = static_cast<int>(order.size()); | ||
341 | for (size_t i = endIndex - 1; i > startIndex; i--) { | ||
342 | const int target = Random::RandInt(static_cast<int>(startIndex), static_cast<int>(i)); | ||
343 | std::swap(order[i], order[target]); | ||
344 | } | ||
345 | } | ||
346 | |||
347 | // Range is [start, end) | ||
348 | void Randomizer::RandomizeRange(std::vector<int> panels, int flags, size_t startIndex, size_t endIndex) { | ||
338 | if (panels.size() == 0) return; | 349 | if (panels.size() == 0) return; |
339 | if (startIndex >= endIndex) return; | 350 | if (startIndex >= endIndex) return; |
340 | if (endIndex >= panels.size()) endIndex = static_cast<int>(panels.size()); | 351 | if (endIndex >= panels.size()) endIndex = static_cast<int>(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: | |||
11 | void PreventSnipes(); | 11 | void PreventSnipes(); |
12 | 12 | ||
13 | enum SWAP { | 13 | enum SWAP { |
14 | NONE = 0, | 14 | // NONE = 0, |
15 | TARGETS = 1, | 15 | TARGETS = 1, |
16 | LINES = 2, | 16 | LINES = 2, |
17 | AUDIO_NAMES = 4, | 17 | AUDIO_NAMES = 4, |
@@ -36,7 +36,8 @@ private: | |||
36 | void RandomizeAudioLogs(); | 36 | void RandomizeAudioLogs(); |
37 | 37 | ||
38 | void Randomize(std::vector<int>& panels, int flags); | 38 | void Randomize(std::vector<int>& panels, int flags); |
39 | void RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex); | 39 | void Shuffle(std::vector<int>&order, size_t startIndex, size_t endIndex); |
40 | void RandomizeRange(std::vector<int> panels, int flags, size_t startIndex, size_t endIndex); | ||
40 | void SwapPanels(int panel1, int panel2, int flags); | 41 | void SwapPanels(int panel1, int panel2, int flags); |
41 | void ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order, std::vector<int> targets = {}); | 42 | void ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order, std::vector<int> targets = {}); |
42 | void ReassignNames(const std::vector<int>& panels, const std::vector<int>& order); | 43 | void ReassignNames(const std::vector<int>& panels, const std::vector<int>& order); |