summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--App/Main.cpp18
-rw-r--r--Source/Memory.h4
-rw-r--r--Source/Puzzle.h9
-rw-r--r--Source/PuzzleSerializer.cpp98
-rw-r--r--Source/PuzzleSerializer.h8
-rw-r--r--Source/Randomizer2.cpp21
-rw-r--r--Source/Randomizer2.h1
-rw-r--r--Source/Randomizer2Core.cpp2
-rw-r--r--Source/Solver.cpp6
-rw-r--r--Source/Validator.cpp4
10 files changed, 116 insertions, 55 deletions
diff --git a/App/Main.cpp b/App/Main.cpp index f5409ff..55074ed 100644 --- a/App/Main.cpp +++ b/App/Main.cpp
@@ -263,16 +263,16 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
263 CreateCheckbox(10, 340, SPEED_UP_AUTOSCROLLERS); 263 CreateCheckbox(10, 340, SPEED_UP_AUTOSCROLLERS);
264 CreateLabel(30, 340, 205, L"Speed up various autoscrollers"); 264 CreateLabel(30, 340, 205, L"Speed up various autoscrollers");
265 265
266 CreateButton(200, 50, 200, L"Test RNG", TMP5); 266 // CreateButton(200, 50, 200, L"Test RNG", TMP5);
267 g_rngDebug = CreateWindow(L"STATIC", L"", 267 // g_rngDebug = CreateWindow(L"STATIC", L"",
268 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT, 268 // WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
269 200, 80, 200, 200, g_hwnd, NULL, g_hInstance, NULL); 269 // 200, 80, 200, 200, g_hwnd, NULL, g_hInstance, NULL);
270 270
271 // g_panelId = CreateText(200, 100, 100, L"A3B2"); 271 g_panelId = CreateText(200, 100, 100, L"86");
272 // CreateButton(200, 130, 100, L"Read", TMP1); 272 CreateButton(200, 130, 100, L"Read", TMP1);
273 // CreateButton(200, 160, 100, L"Write", TMP2); 273 CreateButton(200, 160, 100, L"Write", TMP2);
274 // CreateButton(200, 190, 100, L"Solve", TMP3); 274 CreateButton(200, 190, 100, L"Solve", TMP3);
275 // CreateButton(200, 220, 100, L"Randomize2", TMP4); 275 CreateButton(200, 220, 100, L"Randomize2", TMP4);
276 276
277 g_witnessProc->StartHeartbeat(g_hwnd); 277 g_witnessProc->StartHeartbeat(g_hwnd);
278 278
diff --git a/Source/Memory.h b/Source/Memory.h index 5332cc3..b7edb28 100644 --- a/Source/Memory.h +++ b/Source/Memory.h
@@ -5,8 +5,8 @@
5#include <vector> 5#include <vector>
6#include <windows.h> 6#include <windows.h>
7 7
8// #define GLOBALS 0x5B28C0 8#define GLOBALS 0x5B28C0
9#define GLOBALS 0x62D0A0 9// #define GLOBALS 0x62D0A0
10 10
11#define HEARTBEAT 0x401 11#define HEARTBEAT 0x401
12enum class ProcStatus { 12enum class ProcStatus {
diff --git a/Source/Puzzle.h b/Source/Puzzle.h index 1e00ef4..ac604f1 100644 --- a/Source/Puzzle.h +++ b/Source/Puzzle.h
@@ -61,7 +61,12 @@ struct Cell {
61}; 61};
62 62
63struct Negation {}; 63struct Negation {};
64struct Pos {int x; int y;}; 64struct Pos {
65 Pos(int x_, int y_) : x(x_), y(y_) {}
66 Pos(const std::tuple<int, int>& xy) : x(std::get<0>(xy)), y(std::get<1>(xy)) {}
67 int x;
68 int y;
69};
65 70
66class Puzzle { 71class Puzzle {
67public: 72public:
@@ -70,7 +75,7 @@ public:
70 bool hasDecorations = false; 75 bool hasDecorations = false;
71 76
72 enum class Symmetry {NONE, X, Y, XY}; 77 enum class Symmetry {NONE, X, Y, XY};
73 Symmetry sym = Symmetry::NONE; 78 Symmetry symmetry = Symmetry::NONE;
74 bool pillar = false; 79 bool pillar = false;
75 80
76 bool valid = false; 81 bool valid = false;
diff --git a/Source/PuzzleSerializer.cpp b/Source/PuzzleSerializer.cpp index 5c91b56..132ebb7 100644 --- a/Source/PuzzleSerializer.cpp +++ b/Source/PuzzleSerializer.cpp
@@ -14,12 +14,12 @@ Puzzle PuzzleSerializer::ReadPuzzle(int id) {
14 if (height == 0) height = width; 14 if (height == 0) height = width;
15 if (width < 0 || height < 0) return Puzzle(); // @Error: Grid size should be always positive? Looks like the starting panels break this rule, though. 15 if (width < 0 || height < 0) return Puzzle(); // @Error: Grid size should be always positive? Looks like the starting panels break this rule, though.
16 16
17 int numIntersections = _memory->ReadEntityData<int>(id, NUM_DOTS, 1)[0]; 17 _numIntersections = _memory->ReadEntityData<int>(id, NUM_DOTS, 1)[0];
18 _intersectionFlags = _memory->ReadArray<int>(id, DOT_FLAGS, numIntersections); 18 _intersectionFlags = _memory->ReadArray<int>(id, DOT_FLAGS, _numIntersections);
19 int numConnections = _memory->ReadEntityData<int>(id, NUM_CONNECTIONS, 1)[0]; 19 int numConnections = _memory->ReadEntityData<int>(id, NUM_CONNECTIONS, 1)[0];
20 _connectionsA = _memory->ReadArray<int>(id, DOT_CONNECTION_A, numConnections); 20 _connectionsA = _memory->ReadArray<int>(id, DOT_CONNECTION_A, numConnections);
21 _connectionsB = _memory->ReadArray<int>(id, DOT_CONNECTION_B, numConnections); 21 _connectionsB = _memory->ReadArray<int>(id, DOT_CONNECTION_B, numConnections);
22 _intersectionLocations = _memory->ReadArray<float>(id, DOT_POSITIONS, numIntersections*2); 22 _intersectionLocations = _memory->ReadArray<float>(id, DOT_POSITIONS, _numIntersections*2);
23 23
24 Puzzle p; 24 Puzzle p;
25 p.NewGrid(width, height); 25 p.NewGrid(width, height);
@@ -27,6 +27,7 @@ Puzzle PuzzleSerializer::ReadPuzzle(int id) {
27 ReadExtras(p); 27 ReadExtras(p);
28 ReadDecorations(p, id); 28 ReadDecorations(p, id);
29 ReadSequence(p, id); 29 ReadSequence(p, id);
30 ReadSymmetry(p, id);
30 return p; 31 return p;
31} 32}
32 33
@@ -80,7 +81,7 @@ void PuzzleSerializer::ReadIntersections(Puzzle& p) {
80 } 81 }
81 } 82 }
82 83
83 for (int j=0; j<_intersectionFlags.size(); j++) { 84 for (int j=0; j<_numIntersections; j++) {
84 if (_intersectionFlags[_connectionsA[j]] & Flags::IS_ENDPOINT) break; 85 if (_intersectionFlags[_connectionsA[j]] & Flags::IS_ENDPOINT) break;
85 if (_intersectionFlags[_connectionsB[j]] & Flags::IS_ENDPOINT) break; 86 if (_intersectionFlags[_connectionsB[j]] & Flags::IS_ENDPOINT) break;
86 float x1 = _intersectionLocations[2*_connectionsA[j]]; 87 float x1 = _intersectionLocations[2*_connectionsA[j]];
@@ -100,7 +101,7 @@ void PuzzleSerializer::ReadIntersections(Puzzle& p) {
100void PuzzleSerializer::ReadExtras(Puzzle& p) { 101void PuzzleSerializer::ReadExtras(Puzzle& p) {
101 // This iterates bottom-top, left-right 102 // This iterates bottom-top, left-right
102 int i = 0; 103 int i = 0;
103 for (; i < _intersectionFlags.size(); i++) { 104 for (; i < _numIntersections; i++) {
104 int flags = _intersectionFlags[i]; 105 int flags = _intersectionFlags[i];
105 auto [x, y] = loc_to_xy(p, i); 106 auto [x, y] = loc_to_xy(p, i);
106 if (y < 0) break; // This is the expected exit point 107 if (y < 0) break; // This is the expected exit point
@@ -114,7 +115,7 @@ void PuzzleSerializer::ReadExtras(Puzzle& p) {
114 } 115 }
115 116
116 // Iterate the remaining intersections (endpoints, dots, gaps) 117 // Iterate the remaining intersections (endpoints, dots, gaps)
117 for (; i < _intersectionFlags.size(); i++) { 118 for (; i < _numIntersections; i++) {
118 int location = FindConnection(i); 119 int location = FindConnection(i);
119 if (location == -1) continue; // @Error: Unable to find connection point 120 if (location == -1) continue; // @Error: Unable to find connection point
120 // (x1, y1) location of this intersection 121 // (x1, y1) location of this intersection
@@ -177,8 +178,23 @@ void PuzzleSerializer::ReadSequence(Puzzle& p, int id) {
177 std::vector<int> sequence = _memory->ReadArray<int>(id, SEQUENCE, sequenceLength); 178 std::vector<int> sequence = _memory->ReadArray<int>(id, SEQUENCE, sequenceLength);
178 179
179 for (int location : sequence) { 180 for (int location : sequence) {
180 auto [x, y] = loc_to_xy(p, location); 181 p.sequence.emplace_back(loc_to_xy(p, location));
181 p.sequence.emplace_back(Pos{x, y}); 182 }
183}
184
185void PuzzleSerializer::ReadSymmetry(Puzzle& p, int id) {
186 int hasSymmetry = _memory->ReadEntityData<int>(id, REFLECTION_DATA, 1)[0];
187 if (hasSymmetry == 0) return; // Array is null, no puzzle symmetry
188
189 std::vector<int> reflectionData = _memory->ReadArray<int>(id, REFLECTION_DATA, _numIntersections);
190 Pos p1 = loc_to_xy(p, reflectionData[0]);
191 Pos p2 = loc_to_xy(p, reflectionData[reflectionData[0]]);
192 if (p1.x != p2.x) {
193 p.symmetry = Puzzle::Symmetry::Y;
194 } else if (p1.y != p2.y) {
195 p.symmetry = Puzzle::Symmetry::X;
196 } else {
197 p.symmetry = Puzzle::Symmetry::XY;
182 } 198 }
183} 199}
184 200
@@ -188,9 +204,6 @@ void PuzzleSerializer::WriteIntersections(const Puzzle& p) {
188 // Grided intersections 204 // Grided intersections
189 for (int y=p.height-1; y>=0; y-=2) { 205 for (int y=p.height-1; y>=0; y-=2) {
190 for (int x=0; x<p.width; x+=2) { 206 for (int x=0; x<p.width; x+=2) {
191 auto [xPos, yPos] = xy_to_pos(p, x, y);
192 _intersectionLocations.push_back(xPos);
193 _intersectionLocations.push_back(yPos);
194 int flags = 0; 207 int flags = 0;
195 if (p.grid[x][y].start) { 208 if (p.grid[x][y].start) {
196 flags |= Flags::IS_STARTPOINT; 209 flags |= Flags::IS_STARTPOINT;
@@ -240,7 +253,8 @@ void PuzzleSerializer::WriteIntersections(const Puzzle& p) {
240 if (numConnections == 0) flags |= HAS_NO_CONN; 253 if (numConnections == 0) flags |= HAS_NO_CONN;
241 if (numConnections == 1) flags |= HAS_ONE_CONN; 254 if (numConnections == 1) flags |= HAS_ONE_CONN;
242 255
243 _intersectionFlags.push_back(flags); 256 auto [xPos, yPos] = xy_to_pos(p, x, y);
257 AddIntersection(x, y, xPos, yPos, flags);
244 } 258 }
245 } 259 }
246} 260}
@@ -267,10 +281,7 @@ void PuzzleSerializer::WriteEndpoints(const Puzzle& p) {
267 yPos -= .05f; 281 yPos -= .05f;
268 break; 282 break;
269 } 283 }
270 _endpointLocations.emplace_back(x, y, static_cast<int>(_intersectionFlags.size())); 284 AddIntersection(x, y, xPos, yPos, Flags::IS_ENDPOINT);
271 _intersectionLocations.push_back(xPos);
272 _intersectionLocations.push_back(yPos);
273 _intersectionFlags.push_back(Flags::IS_ENDPOINT);
274 } 285 }
275 } 286 }
276} 287}
@@ -300,11 +311,6 @@ void PuzzleSerializer::WriteDots(const Puzzle& p) {
300 _connectionsA.push_back(other_connection); 311 _connectionsA.push_back(other_connection);
301 _connectionsB.push_back(static_cast<int>(_intersectionFlags.size())); 312 _connectionsB.push_back(static_cast<int>(_intersectionFlags.size()));
302 313
303 // Add this dot to the end
304 auto [xPos, yPos] = xy_to_pos(p, x, y);
305 _intersectionLocations.push_back(xPos);
306 _intersectionLocations.push_back(yPos);
307
308 int flags = Flags::HAS_DOT; 314 int flags = Flags::HAS_DOT;
309 switch (p.grid[x][y].dot) { 315 switch (p.grid[x][y].dot) {
310 case Cell::Dot::BLACK: 316 case Cell::Dot::BLACK:
@@ -319,7 +325,9 @@ void PuzzleSerializer::WriteDots(const Puzzle& p) {
319 flags |= DOT_IS_INVISIBLE; 325 flags |= DOT_IS_INVISIBLE;
320 break; 326 break;
321 } 327 }
322 _intersectionFlags.push_back(flags); 328
329 auto [xPos, yPos] = xy_to_pos(p, x, y);
330 AddIntersection(x, y, xPos, yPos, flags);
323 } 331 }
324 } 332 }
325} 333}
@@ -409,17 +417,36 @@ void PuzzleSerializer::WriteSequence(const Puzzle& p, int id) {
409 } 417 }
410 418
411 Pos endpoint = p.sequence[p.sequence.size() - 1]; 419 Pos endpoint = p.sequence[p.sequence.size() - 1];
412 for (auto [x, y, location] : _endpointLocations) { 420 int location = extra_xy_to_loc(endpoint);
413 if (x == endpoint.x && y == endpoint.y) {
414 sequence.emplace_back(location);
415 break;
416 }
417 }
418 421
419 _memory->WriteEntityData<int>(id, SEQUENCE_LEN, {static_cast<int>(sequence.size())}); 422 _memory->WriteEntityData<int>(id, SEQUENCE_LEN, {static_cast<int>(sequence.size())});
420 _memory->WriteNewArray<int>(id, SEQUENCE, sequence); 423 _memory->WriteNewArray<int>(id, SEQUENCE, sequence);
421} 424}
422 425
426void PuzzleSerializer::WriteSymmetry(const Puzzle& p, int id) {
427 if (p.symmetry == Puzzle::Symmetry::NONE) {
428 _memory->WriteEntityData<int>(id, REFLECTION_DATA, {0});
429 return;
430 }
431
432 // TODO: This. Probably 3 different sections for the different types?
433 // The idea is simple, though, just write symmetry data for all endpoints.
434 // Handle the default grid... then just separate iterators for dots/gaps/endpoints? Gross, but might work.
435 // I think this might put constraints on how I build the dots/gaps, actually. Let me see.
436 /*
437 Pos p1 = loc_to_xy(p, reflectionData[0]);
438 Pos p2 = loc_to_xy(p, reflectionData[reflectionData[0]]);
439 if (p1.x != p2.x) {
440 p.symmetry = Puzzle::Symmetry::Y;
441 } else if (p1.y != p2.y) {
442 p.symmetry = Puzzle::Symmetry::X;
443 } else {
444 p.symmetry = Puzzle::Symmetry::XY;
445 }
446
447 */
448}
449
423std::tuple<int, int> PuzzleSerializer::loc_to_xy(const Puzzle& p, int location) const { 450std::tuple<int, int> PuzzleSerializer::loc_to_xy(const Puzzle& p, int location) const {
424 int height2 = (p.height - 1) / 2; 451 int height2 = (p.height - 1) / 2;
425 int width2 = (p.width + 1) / 2; 452 int width2 = (p.width + 1) / 2;
@@ -437,6 +464,14 @@ int PuzzleSerializer::xy_to_loc(const Puzzle& p, int x, int y) const {
437 return rowsFromBottom * width2 + x/2; 464 return rowsFromBottom * width2 + x/2;
438} 465}
439 466
467int PuzzleSerializer::extra_xy_to_loc(Pos pos) const {
468 for (auto [x, y, location] : _extraLocations) {
469 if (pos.x == x && pos.y == y) return location;
470 }
471
472 return -1; // @Error
473}
474
440std::tuple<int, int> PuzzleSerializer::dloc_to_xy(const Puzzle& p, int location) const { 475std::tuple<int, int> PuzzleSerializer::dloc_to_xy(const Puzzle& p, int location) const {
441 int height2 = (p.height - 3) / 2; 476 int height2 = (p.height - 3) / 2;
442 int width2 = (p.width - 1) / 2; 477 int width2 = (p.width - 1) / 2;
@@ -476,3 +511,10 @@ int PuzzleSerializer::FindConnection(int location) const {
476 } 511 }
477 return -1; 512 return -1;
478} 513}
514
515void PuzzleSerializer::AddIntersection(int x, int y, float xPos, float yPos, int flags) {
516 _extraLocations.emplace_back(x, y, static_cast<int>(_intersectionFlags.size()));
517 _intersectionLocations.push_back(xPos);
518 _intersectionLocations.push_back(yPos);
519 _intersectionFlags.push_back(flags);
520}
diff --git a/Source/PuzzleSerializer.h b/Source/PuzzleSerializer.h index d9b9edd..3c8f480 100644 --- a/Source/PuzzleSerializer.h +++ b/Source/PuzzleSerializer.h
@@ -31,6 +31,7 @@ private:
31 void ReadExtras(Puzzle& p); 31 void ReadExtras(Puzzle& p);
32 void ReadDecorations(Puzzle& p, int id); 32 void ReadDecorations(Puzzle& p, int id);
33 void ReadSequence(Puzzle& p, int id); 33 void ReadSequence(Puzzle& p, int id);
34 void ReadSymmetry(Puzzle& p, int id);
34 35
35 void WriteIntersections(const Puzzle& p); 36 void WriteIntersections(const Puzzle& p);
36 void WriteDots(const Puzzle& p); 37 void WriteDots(const Puzzle& p);
@@ -38,9 +39,11 @@ private:
38 void WriteEndpoints(const Puzzle& p); 39 void WriteEndpoints(const Puzzle& p);
39 void WriteDecorations(const Puzzle& p, int id); 40 void WriteDecorations(const Puzzle& p, int id);
40 void WriteSequence(const Puzzle& p, int id); 41 void WriteSequence(const Puzzle& p, int id);
42 void WriteSymmetry(const Puzzle& p, int id);
41 43
42 std::tuple<int, int> loc_to_xy(const Puzzle& p, int location) const; 44 std::tuple<int, int> loc_to_xy(const Puzzle& p, int location) const;
43 int xy_to_loc(const Puzzle& p, int x, int y) const; 45 int xy_to_loc(const Puzzle& p, int x, int y) const;
46 int extra_xy_to_loc(Pos pos) const;
44 // Decoration location 47 // Decoration location
45 std::tuple<int, int> dloc_to_xy(const Puzzle& p, int location) const; 48 std::tuple<int, int> dloc_to_xy(const Puzzle& p, int location) const;
46 int xy_to_dloc(const Puzzle& p, int x, int y) const; 49 int xy_to_dloc(const Puzzle& p, int x, int y) const;
@@ -49,14 +52,17 @@ private:
49 Cell::Dot FlagsToDot(int flags) const; 52 Cell::Dot FlagsToDot(int flags) const;
50 // Iterate connection lists for another location which is connected to us; return that other location. 53 // Iterate connection lists for another location which is connected to us; return that other location.
51 int FindConnection(int location) const; 54 int FindConnection(int location) const;
55 void AddIntersection(int x, int y, float xPos, float yPos, int flags);
52 56
53 std::shared_ptr<Memory> _memory; 57 std::shared_ptr<Memory> _memory;
54 58
55 std::vector<float> _intersectionLocations; 59 std::vector<float> _intersectionLocations;
60 int _numIntersections;
56 std::vector<int> _intersectionFlags; 61 std::vector<int> _intersectionFlags;
57 std::vector<int> _connectionsA; 62 std::vector<int> _connectionsA;
58 std::vector<int> _connectionsB; 63 std::vector<int> _connectionsB;
59 std::vector<std::tuple<int, int, int>> _endpointLocations; 64 // Locations of non-grid points, i.e. dots, gaps, and endpoints
65 std::vector<std::tuple<int, int, int>> _extraLocations;
60 66
61 float MIN, MAX, WIDTH_INTERVAL, HEIGHT_INTERVAL, HORIZ_GAP_SIZE, VERTI_GAP_SIZE; 67 float MIN, MAX, WIDTH_INTERVAL, HEIGHT_INTERVAL, HORIZ_GAP_SIZE, VERTI_GAP_SIZE;
62}; 68};
diff --git a/Source/Randomizer2.cpp b/Source/Randomizer2.cpp index 00b584e..e4f2b9f 100644 --- a/Source/Randomizer2.cpp +++ b/Source/Randomizer2.cpp
@@ -14,6 +14,7 @@ Randomizer2::Randomizer2(const std::shared_ptr<Memory>& memory) : _memory(memory
14 14
15void Randomizer2::Randomize() { 15void Randomizer2::Randomize() {
16 RandomizeTutorial(); 16 RandomizeTutorial();
17 RandomizeSymmetry();
17 // RandomizeKeep(); 18 // RandomizeKeep();
18} 19}
19 20
@@ -105,44 +106,44 @@ void Randomizer2::RandomizeTutorial() {
105 x = 1; 106 x = 1;
106 y = 1; 107 y = 1;
107 toTheRight = true; 108 toTheRight = true;
108 cuts.emplace_back(Pos{0, 1}); 109 cuts.emplace_back(0, 1);
109 break; 110 break;
110 case 2: 111 case 2:
111 x = 1; 112 x = 1;
112 y = 1; 113 y = 1;
113 toTheRight = true; 114 toTheRight = true;
114 cuts.emplace_back(Pos{1, 0}); 115 cuts.emplace_back(1, 0);
115 break; 116 break;
116 case 3: 117 case 3:
117 x = 11; 118 x = 11;
118 y = 1; 119 y = 1;
119 toTheRight = false; 120 toTheRight = false;
120 cuts.emplace_back(Pos{12, 1}); 121 cuts.emplace_back(12, 1);
121 break; 122 break;
122 case 4: 123 case 4:
123 x = 11; 124 x = 11;
124 y = 1; 125 y = 1;
125 toTheRight = false; 126 toTheRight = false;
126 cuts.emplace_back(Pos{11, 0}); 127 cuts.emplace_back(11, 0);
127 break; 128 break;
128 } 129 }
129 while (y < p.height) { // The final cut will push y below the bottom of the puzzle, which means we're done. 130 while (y < p.height) { // The final cut will push y below the bottom of the puzzle, which means we're done.
130 switch (Random::RandInt(1, 4)) { 131 switch (Random::RandInt(1, 4)) {
131 case 1: // Go right 132 case 1: // Go right
132 if (x < p.width-2) { 133 if (x < p.width-2) {
133 cuts.emplace_back(Pos{x+1, y}); 134 cuts.emplace_back(x+1, y);
134 x += 2; 135 x += 2;
135 } 136 }
136 break; 137 break;
137 case 2: // Go left 138 case 2: // Go left
138 if (x > 1) { 139 if (x > 1) {
139 cuts.emplace_back(Pos{x-1, y}); 140 cuts.emplace_back(x-1, y);
140 x -= 2; 141 x -= 2;
141 } 142 }
142 break; 143 break;
143 case 3: 144 case 3:
144 case 4: // Go down (biased) 145 case 4: // Go down (biased)
145 cuts.emplace_back(Pos{x, y+1}); 146 cuts.emplace_back(x, y+1);
146 y += 2; 147 y += 2;
147 break; 148 break;
148 } 149 }
@@ -159,6 +160,12 @@ void Randomizer2::RandomizeTutorial() {
159 } 160 }
160} 161}
161 162
163void Randomizer2::RandomizeSymmetry() {
164 { //
165
166 }
167}
168
162void Randomizer2::RandomizeKeep() { 169void Randomizer2::RandomizeKeep() {
163 { // Hedges 1 170 { // Hedges 1
164 Puzzle p; 171 Puzzle p;
diff --git a/Source/Randomizer2.h b/Source/Randomizer2.h index 6e79694..47a9ebd 100644 --- a/Source/Randomizer2.h +++ b/Source/Randomizer2.h
@@ -8,6 +8,7 @@ public:
8 Randomizer2(const std::shared_ptr<Memory>& memory); 8 Randomizer2(const std::shared_ptr<Memory>& memory);
9 void Randomize(); 9 void Randomize();
10 void RandomizeTutorial(); 10 void RandomizeTutorial();
11 void RandomizeSymmetry();
11 void RandomizeKeep(); 12 void RandomizeKeep();
12 13
13private: 14private:
diff --git a/Source/Randomizer2Core.cpp b/Source/Randomizer2Core.cpp index c34fec6..f8d1312 100644 --- a/Source/Randomizer2Core.cpp +++ b/Source/Randomizer2Core.cpp
@@ -24,7 +24,7 @@ std::vector<Pos> Randomizer2Core::CutEdges(const Puzzle& p, size_t numEdges, boo
24 bool inSequence = false; 24 bool inSequence = false;
25 for (Pos pos : p.sequence) inSequence |= (pos.x == x && pos.y == y); 25 for (Pos pos : p.sequence) inSequence |= (pos.x == x && pos.y == y);
26 if (inSequence) continue; 26 if (inSequence) continue;
27 edges.emplace_back(Pos{x, y}); 27 edges.emplace_back(x, y);
28 } 28 }
29 } 29 }
30 return CutEdgesInternal(p, edges, numEdges); 30 return CutEdgesInternal(p, edges, numEdges);
diff --git a/Source/Solver.cpp b/Source/Solver.cpp index a8710a2..c0b35ef 100644 --- a/Source/Solver.cpp +++ b/Source/Solver.cpp
@@ -27,10 +27,10 @@ void Solver::SolveLoop(Puzzle& p, int x, int y, std::vector<Puzzle>& solutions)
27 if (cell.undefined) return; 27 if (cell.undefined) return;
28 if (cell.gap != Cell::Gap::NONE) return; 28 if (cell.gap != Cell::Gap::NONE) return;
29 29
30 if (p.sym == Puzzle::Symmetry::NONE) { 30 if (p.symmetry == Puzzle::Symmetry::NONE) {
31 if (cell.color != Cell::Color::NONE) return; // Collided with ourselves 31 if (cell.color != Cell::Color::NONE) return; // Collided with ourselves
32 p.grid[x][y].color = Cell::Color::BLACK; // Otherwise, mark this cell as visited 32 p.grid[x][y].color = Cell::Color::BLACK; // Otherwise, mark this cell as visited
33 p.sequence.emplace_back(Pos{x, y}); 33 p.sequence.emplace_back(x, y);
34 } else { 34 } else {
35 /* 35 /*
36 // Get the symmetrical position, and try coloring it 36 // Get the symmetrical position, and try coloring it
@@ -71,7 +71,7 @@ void Solver::SolveLoop(Puzzle& p, int x, int y, std::vector<Puzzle>& solutions)
71 // Tail recursion: Back out of this cell 71 // Tail recursion: Back out of this cell
72 p.grid[x][y].color = Cell::Color::NONE; 72 p.grid[x][y].color = Cell::Color::NONE;
73 p.sequence.pop_back(); 73 p.sequence.pop_back();
74 if (p.sym != Puzzle::Symmetry::NONE) { 74 if (p.symmetry != Puzzle::Symmetry::NONE) {
75 /* 75 /*
76 auto sym = p.GetSymmetricalPos(x, y); 76 auto sym = p.GetSymmetricalPos(x, y);
77 p.grid[sym.x][sym.y].color = Cell::Color::NONE; 77 p.grid[sym.x][sym.y].color = Cell::Color::NONE;
diff --git a/Source/Validator.cpp b/Source/Validator.cpp index 82d6779..e71dc34 100644 --- a/Source/Validator.cpp +++ b/Source/Validator.cpp
@@ -32,7 +32,7 @@ void Validator::Validate(Puzzle& p) {
32 if (p.GetLine(x, y + 1) != Cell::Color::NONE) actualCount++; 32 if (p.GetLine(x, y + 1) != Cell::Color::NONE) actualCount++;
33 if (decoration->count != actualCount) { 33 if (decoration->count != actualCount) {
34 // console.log('Triangle at grid['+x+']['+y+'] has', actualCount, 'borders') 34 // console.log('Triangle at grid['+x+']['+y+'] has', actualCount, 'borders')
35 p.invalidElements.emplace_back(Pos{x, y}); 35 p.invalidElements.emplace_back(x, y);
36 } 36 }
37 } 37 }
38 } 38 }
@@ -43,7 +43,7 @@ void Validator::Validate(Puzzle& p) {
43 if (cell.dot != Cell::Dot::NONE) { 43 if (cell.dot != Cell::Dot::NONE) {
44 if (cell.color == Cell::Color::NONE) { 44 if (cell.color == Cell::Color::NONE) {
45 // console.log('Dot at', x, y, 'is not covered') 45 // console.log('Dot at', x, y, 'is not covered')
46 p.invalidElements.emplace_back(Pos{x, y}); 46 p.invalidElements.emplace_back(x, y);
47 } else if (cell.color == Cell::Color::BLUE && cell.dot == Cell::Dot::YELLOW) { 47 } else if (cell.color == Cell::Color::BLUE && cell.dot == Cell::Dot::YELLOW) {
48 // console.log('Yellow dot at', x, y, 'is covered by blue line') 48 // console.log('Yellow dot at', x, y, 'is covered by blue line')
49 p.valid = false; 49 p.valid = false;