diff options
Diffstat (limited to 'WitnessRandomizer/WitnessRandomizer.cpp')
-rw-r--r-- | WitnessRandomizer/WitnessRandomizer.cpp | 32 |
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 | ||
21 | template <class T> | 23 | template <class T> |
22 | int find(const std::vector<T> &data, T search, int startIndex = 0) { | 24 | size_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 | ||
29 | int main(int argc, char** argv) | 32 | int 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 | ||
124 | void WitnessRandomizer::Randomize(std::vector<int> &panels, int flags) { | 128 | void 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) |
129 | void WitnessRandomizer::RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex) { | 133 | void 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 | ||
217 | void WitnessRandomizer::ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order) { | 221 | void 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 | } |