diff options
-rw-r--r-- | Source/Randomizer2.cpp | 56 | ||||
-rw-r--r-- | Source/Randomizer2Core.cpp | 20 |
2 files changed, 71 insertions, 5 deletions
diff --git a/Source/Randomizer2.cpp b/Source/Randomizer2.cpp index 4968666..b1cdc1f 100644 --- a/Source/Randomizer2.cpp +++ b/Source/Randomizer2.cpp | |||
@@ -270,14 +270,66 @@ void Randomizer2::RandomizeSymmetry() { | |||
270 | p.grid[1][6].gap = Cell::Gap::BREAK; | 270 | p.grid[1][6].gap = Cell::Gap::BREAK; |
271 | 271 | ||
272 | for (Pos pos : Randomizer2Core::CutSymmetricalEdgePairs(p, 1)) { | 272 | for (Pos pos : Randomizer2Core::CutSymmetricalEdgePairs(p, 1)) { |
273 | std::string text = std::to_string(pos.x) + " " + std::to_string(pos.y); | ||
274 | OutputDebugStringA(text.c_str()); | ||
275 | p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK; | 273 | p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK; |
276 | Pos sym = p.GetSymmetricalPos(pos.x, pos.y); | 274 | Pos sym = p.GetSymmetricalPos(pos.x, pos.y); |
277 | p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK; | 275 | p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK; |
278 | } | 276 | } |
279 | _serializer.WritePuzzle(p, 0x8D); | 277 | _serializer.WritePuzzle(p, 0x8D); |
280 | } | 278 | } |
279 | { // Rotational 2 | ||
280 | Puzzle p; | ||
281 | p.NewGrid(3, 3); | ||
282 | p.symmetry = Puzzle::Symmetry::XY; | ||
283 | p.grid[6][0].start = true; | ||
284 | p.grid[0][6].start = true; | ||
285 | p.grid[4][0].end = Cell::Dir::UP; | ||
286 | p.grid[2][6].end = Cell::Dir::DOWN; | ||
287 | |||
288 | p.grid[5][0].gap = Cell::Gap::BREAK; | ||
289 | p.grid[1][6].gap = Cell::Gap::BREAK; | ||
290 | |||
291 | std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 3); | ||
292 | for (int i=0; i<cutEdges.size(); i++) { | ||
293 | Pos pos = cutEdges[i]; | ||
294 | if (i%2 == 0) { | ||
295 | p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK; | ||
296 | } else { | ||
297 | Pos sym = p.GetSymmetricalPos(pos.x, pos.y); | ||
298 | p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK; | ||
299 | } | ||
300 | } | ||
301 | |||
302 | p.grid[1][6].gap = Cell::Gap::NONE; | ||
303 | |||
304 | _serializer.WritePuzzle(p, 0x81); | ||
305 | } | ||
306 | { // Rotational 3 | ||
307 | Puzzle p; | ||
308 | p.NewGrid(4, 4); | ||
309 | p.symmetry = Puzzle::Symmetry::XY; | ||
310 | p.grid[6][0].start = true; | ||
311 | p.grid[0][6].start = true; | ||
312 | p.grid[4][0].end = Cell::Dir::UP; | ||
313 | p.grid[2][6].end = Cell::Dir::DOWN; | ||
314 | |||
315 | p.grid[5][0].gap = Cell::Gap::BREAK; | ||
316 | p.grid[1][6].gap = Cell::Gap::BREAK; | ||
317 | |||
318 | std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 3); | ||
319 | for (int i=0; i<cutEdges.size(); i++) { | ||
320 | Pos pos = cutEdges[i]; | ||
321 | if (i%2 == 0) { | ||
322 | p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK; | ||
323 | } else { | ||
324 | Pos sym = p.GetSymmetricalPos(pos.x, pos.y); | ||
325 | p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK; | ||
326 | } | ||
327 | } | ||
328 | |||
329 | p.grid[1][6].gap = Cell::Gap::NONE; | ||
330 | |||
331 | _serializer.WritePuzzle(p, 0x81); | ||
332 | } | ||
281 | } | 333 | } |
282 | 334 | ||
283 | void Randomizer2::RandomizeKeep() { | 335 | void Randomizer2::RandomizeKeep() { |
diff --git a/Source/Randomizer2Core.cpp b/Source/Randomizer2Core.cpp index 401743f..2a2c6ff 100644 --- a/Source/Randomizer2Core.cpp +++ b/Source/Randomizer2Core.cpp | |||
@@ -17,15 +17,28 @@ std::vector<Pos> Randomizer2Core::CutSymmetricalEdgePairs(const Puzzle& p, size_ | |||
17 | for (int y=0; y<p.height; y++) { | 17 | for (int y=0; y<p.height; y++) { |
18 | copy.grid[p.width/2][y].gap = Cell::Gap::FULL; | 18 | copy.grid[p.width/2][y].gap = Cell::Gap::FULL; |
19 | } | 19 | } |
20 | return CutEdgesInternal(copy, 0, (p.width-1)/2, 0, p.height, numEdges); | ||
20 | } else if (p.symmetry == Puzzle::Symmetry::Y) { | 21 | } else if (p.symmetry == Puzzle::Symmetry::Y) { |
21 | for (int x=0; x<p.width; x++) { | 22 | for (int x=0; x<p.width; x++) { |
22 | copy.grid[x][p.height/2].gap = Cell::Gap::FULL; | 23 | copy.grid[x][p.height/2].gap = Cell::Gap::FULL; |
23 | } | 24 | } |
25 | return CutEdgesInternal(copy, 0, p.width, 0, (p.height-1)/2, numEdges); | ||
24 | } else { | 26 | } else { |
25 | assert(p.symmetry == Puzzle::Symmetry::XY); | 27 | assert(p.symmetry == Puzzle::Symmetry::XY); |
26 | // Pass, I think? Maybe this matters for odd numbers. | 28 | if (p.width%4 == 1) { |
29 | assert(p.width == 9); | ||
30 | copy.grid[2][3]; | ||
31 | copy.grid[3][4]; | ||
32 | copy.grid[3][6]; | ||
33 | copy.grid[4][3]; | ||
34 | // For odd grids, cut the center out. | ||
35 | // for (int x=0; x<p.width; x++) { | ||
36 | // copy.grid[x][p.height/2].gap = Cell::Gap::FULL; | ||
37 | // } | ||
38 | |||
39 | } | ||
40 | return CutEdgesInternal(copy, 0, p.width, 0, p.height, numEdges); | ||
27 | } | 41 | } |
28 | return CutEdgesInternal(copy, 0, (p.width-1)/2, 0, p.height, numEdges); | ||
29 | } | 42 | } |
30 | 43 | ||
31 | std::vector<Pos> Randomizer2Core::CutEdgesInternal(const Puzzle& p, int xMin, int xMax, int yMin, int yMax, size_t numEdges) { | 44 | std::vector<Pos> Randomizer2Core::CutEdgesInternal(const Puzzle& p, int xMin, int xMax, int yMin, int yMax, size_t numEdges) { |
@@ -36,6 +49,7 @@ std::vector<Pos> Randomizer2Core::CutEdgesInternal(const Puzzle& p, int xMin, in | |||
36 | if (p.grid[x][y].gap != Cell::Gap::NONE) continue; | 49 | if (p.grid[x][y].gap != Cell::Gap::NONE) continue; |
37 | if (p.grid[x][y].start) continue; | 50 | if (p.grid[x][y].start) continue; |
38 | if (p.grid[x][y].end != Cell::Dir::NONE) continue; | 51 | if (p.grid[x][y].end != Cell::Dir::NONE) continue; |
52 | if (p.symmetry == Puzzle::Symmetry::XY && x > y) continue; // Only allow cuts bottom-left of the diagonal | ||
39 | 53 | ||
40 | // If the puzzle already has a sequence, don't cut along it. | 54 | // If the puzzle already has a sequence, don't cut along it. |
41 | bool inSequence = false; | 55 | bool inSequence = false; |
@@ -51,7 +65,7 @@ std::vector<Pos> Randomizer2Core::CutEdgesInternal(const Puzzle& p, int xMin, in | |||
51 | 65 | ||
52 | std::vector<Pos> cutEdges; | 66 | std::vector<Pos> cutEdges; |
53 | for (int i=0; i<numEdges; i++) { | 67 | for (int i=0; i<numEdges; i++) { |
54 | for (int j=0; j<edges.size(); j++) { | 68 | while (edges.size() > 0) { |
55 | int edge = Random::RandInt(0, static_cast<int>(edges.size() - 1)); | 69 | int edge = Random::RandInt(0, static_cast<int>(edges.size() - 1)); |
56 | Pos pos = edges[edge]; | 70 | Pos pos = edges[edge]; |
57 | edges.erase(edges.begin() + edge); | 71 | edges.erase(edges.begin() + edge); |