summary refs log tree commit diff stats
path: root/WitnessRandomizer/WitnessRandomizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WitnessRandomizer/WitnessRandomizer.cpp')
-rw-r--r--WitnessRandomizer/WitnessRandomizer.cpp32
1 files changed, 18 insertions, 14 deletions
diff --git a/WitnessRandomizer/WitnessRandomizer.cpp b/WitnessRandomizer/WitnessRandomizer.cpp index efe18b5..d71cc21 100644 --- a/WitnessRandomizer/WitnessRandomizer.cpp +++ b/WitnessRandomizer/WitnessRandomizer.cpp
@@ -1,5 +1,6 @@
1/* 1/*
2 * BUGS: 2 * BUGS:
3 * Shipwreck vault fails, possibly because of dot_reflection?
3 * Treehouse pivots *should* work, but I need to not copy style_flags. 4 * Treehouse pivots *should* work, but I need to not copy style_flags.
4 This seems to cause crashes when pivots appear elsewhere in the world. 5 This seems to cause crashes when pivots appear elsewhere in the world.
5 * FEATURES: 6 * FEATURES:
@@ -17,23 +18,26 @@
17#include <string> 18#include <string>
18#include <iostream> 19#include <iostream>
19#include <numeric> 20#include <numeric>
21#include <chrono>
20 22
21template <class T> 23template <class T>
22int find(const std::vector<T> &data, T search, int startIndex = 0) { 24size_t find(const std::vector<T> &data, T search, size_t startIndex = 0) {
23 for (int i=startIndex ; i<data.size(); i++) { 25 for (size_t i=startIndex ; i<data.size(); i++) {
24 if (data[i] == search) return i; 26 if (data[i] == search) return i;
25 } 27 }
26 return -1; 28 std::cout << "Couldn't find " << search << " in data!" << std::endl;
29 exit(-1);
27} 30}
28 31
29int main(int argc, char** argv) 32int main(int argc, char** argv)
30{ 33{
34
31 WitnessRandomizer randomizer = WitnessRandomizer(); 35 WitnessRandomizer randomizer = WitnessRandomizer();
32 36
33 if (argc == 2) { 37 if (argc == 2) {
34 srand(atoi(argv[1])); // Seed from the command line 38 srand(atoi(argv[1])); // Seed from the command line
35 } else { 39 } else {
36 int seed = time(0) % (1 << 16); // Seed from the time in milliseconds 40 int seed = time(nullptr) % (1 << 16); // Seed from the time in milliseconds
37 std::cout << "Selected seed: " << seed << std::endl; 41 std::cout << "Selected seed: " << seed << std::endl;
38 srand(seed); 42 srand(seed);
39 } 43 }
@@ -71,7 +75,7 @@ int main(int argc, char** argv)
71 // Glass 1 will become door + glass 1, due to the targetting system 75 // Glass 1 will become door + glass 1, due to the targetting system
72 randomizer.RandomizeRange(randomOrder, SWAP_NONE, 1, 10); 76 randomizer.RandomizeRange(randomOrder, SWAP_NONE, 1, 10);
73 // Randomize Glass 1-3 into everything after the door 77 // Randomize Glass 1-3 into everything after the door
74 int glassDoorIndex = find(randomOrder, 9) + 1; 78 const size_t glassDoorIndex = find(randomOrder, 9) + 1;
75 randomizer.RandomizeRange(randomOrder, SWAP_NONE, glassDoorIndex, 12); 79 randomizer.RandomizeRange(randomOrder, SWAP_NONE, glassDoorIndex, 12);
76 randomizer.ReassignTargets(bunkerPanels, randomOrder); 80 randomizer.ReassignTargets(bunkerPanels, randomOrder);
77 81
@@ -121,17 +125,17 @@ WitnessRandomizer::WitnessRandomizer()
121 WritePanelData<float>(0x002C2, CURSOR_SPEED_SCALE, {1.0}); 125 WritePanelData<float>(0x002C2, CURSOR_SPEED_SCALE, {1.0});
122} 126}
123 127
124void WitnessRandomizer::Randomize(std::vector<int> &panels, int flags) { 128void WitnessRandomizer::Randomize(const std::vector<int>& panels, int flags) {
125 return RandomizeRange(panels, flags, 0, panels.size()); 129 return RandomizeRange(panels, flags, 0, panels.size());
126} 130}
127 131
128// Range is [start, end) 132// Range is [start, end)
129void WitnessRandomizer::RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex) { 133void WitnessRandomizer::RandomizeRange(std::vector<int> panels, int flags, size_t startIndex, size_t endIndex) {
130 if (panels.size() == 0) return; 134 if (panels.size() == 0) return;
131 if (startIndex >= endIndex) return; 135 if (startIndex >= endIndex) return;
132 if (endIndex >= panels.size()) endIndex = panels.size(); 136 if (endIndex >= panels.size()) endIndex = panels.size();
133 for (size_t i = endIndex-1; i > startIndex+1; i--) { 137 for (size_t i = endIndex-1; i > startIndex+1; i--) {
134 size_t target = rand() % (i - startIndex) + startIndex; 138 const size_t target = rand() % (i - startIndex) + startIndex;
135 if (i != target) { 139 if (i != target) {
136 // std::cout << "Swapping panels " << std::hex << panels[i] << " and " << std::hex << panels[target] << std::endl; 140 // std::cout << "Swapping panels " << std::hex << panels[i] << " and " << std::hex << panels[target] << std::endl;
137 SwapPanels(panels[i], panels[target], flags); 141 SwapPanels(panels[i], panels[target], flags);
@@ -215,17 +219,17 @@ void WitnessRandomizer::SwapPanels(int panel1, int panel2, int flags) {
215} 219}
216 220
217void WitnessRandomizer::ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order) { 221void WitnessRandomizer::ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order) {
222 // This list is offset by 1, so the target of the Nth panel is in position N (aka the N+1th element)
223 // The first panel may not have a wire to power it, so we use the panel ID itself.
218 std::vector<int> targetToActivatePanel = {panels[0] + 1}; 224 std::vector<int> targetToActivatePanel = {panels[0] + 1};
219 for (int panel : panels) { 225 for (const int panel : panels) {
220 int target = ReadPanelData<int>(panel, TARGET, 1)[0]; 226 int target = ReadPanelData<int>(panel, TARGET, 1)[0];
221 targetToActivatePanel.push_back(target); 227 targetToActivatePanel.push_back(target);
222 } 228 }
223 229
224 for (int i=0; i<order.size() - 1; i++) { 230 for (size_t i=0; i<order.size() - 1; i++) {
225 // order[i+1] is the target panel 231 // Set the target of order[i] to order[i+1], using the "real" target as determined above.
226 // order[i+1] - 1 is the (real) panel before the target panel 232 const int panelTarget = targetToActivatePanel[order[i+1]];
227 // targets[order[i+1] - 1] is the (real) target which will activate the target panel
228 int panelTarget = targetToActivatePanel[order[i+1]];
229 WritePanelData<int>(panels[order[i]], TARGET, {panelTarget}); 233 WritePanelData<int>(panels[order[i]], TARGET, {panelTarget});
230 } 234 }
231} 235}