about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Source/Randomizer2.cpp47
-rw-r--r--Source/Randomizer2Core.cpp38
2 files changed, 63 insertions, 22 deletions
diff --git a/Source/Randomizer2.cpp b/Source/Randomizer2.cpp index b1cdc1f..db90f4c 100644 --- a/Source/Randomizer2.cpp +++ b/Source/Randomizer2.cpp
@@ -307,15 +307,12 @@ void Randomizer2::RandomizeSymmetry() {
307 Puzzle p; 307 Puzzle p;
308 p.NewGrid(4, 4); 308 p.NewGrid(4, 4);
309 p.symmetry = Puzzle::Symmetry::XY; 309 p.symmetry = Puzzle::Symmetry::XY;
310 p.grid[6][0].start = true; 310 p.grid[8][0].start = true;
311 p.grid[0][6].start = true; 311 p.grid[0][8].start = true;
312 p.grid[4][0].end = Cell::Dir::UP; 312 p.grid[0][0].end = Cell::Dir::LEFT;
313 p.grid[2][6].end = Cell::Dir::DOWN; 313 p.grid[8][8].end = Cell::Dir::RIGHT;
314
315 p.grid[5][0].gap = Cell::Gap::BREAK;
316 p.grid[1][6].gap = Cell::Gap::BREAK;
317 314
318 std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 3); 315 std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 7);
319 for (int i=0; i<cutEdges.size(); i++) { 316 for (int i=0; i<cutEdges.size(); i++) {
320 Pos pos = cutEdges[i]; 317 Pos pos = cutEdges[i];
321 if (i%2 == 0) { 318 if (i%2 == 0) {
@@ -326,9 +323,39 @@ void Randomizer2::RandomizeSymmetry() {
326 } 323 }
327 } 324 }
328 325
329 p.grid[1][6].gap = Cell::Gap::NONE; 326 _serializer.WritePuzzle(p, 0x83);
327 }
328 { // Melting
329 Puzzle p;
330 p.NewGrid(6, 6);
331 p.symmetry = Puzzle::Symmetry::XY;
332 p.grid[12][0].start = true;
333 p.grid[0][12].start = true;
334 p.grid[0][0].end = Cell::Dir::LEFT;
335 p.grid[12][12].end = Cell::Dir::RIGHT;
336 Puzzle q = p;
330 337
331 _serializer.WritePuzzle(p, 0x81); 338 std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 15);
339 for (int i=0; i<cutEdges.size(); i++) {
340 Pos pos = cutEdges[i];
341 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
342
343 if (i%2 == 0) {
344 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
345 } else {
346 p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
347 }
348
349 if (pos.x < sym.x) {
350 q.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
351 } else {
352 q.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
353 }
354 }
355
356 _serializer.WritePuzzle(p, 0x84); // Melting 1
357 _serializer.WritePuzzle(q, 0x82); // Melting 2
358 _serializer.WritePuzzle(q, 0x343A); // Melting 3
332 } 359 }
333} 360}
334 361
diff --git a/Source/Randomizer2Core.cpp b/Source/Randomizer2Core.cpp index 2a2c6ff..867fa5a 100644 --- a/Source/Randomizer2Core.cpp +++ b/Source/Randomizer2Core.cpp
@@ -25,17 +25,17 @@ std::vector<Pos> Randomizer2Core::CutSymmetricalEdgePairs(const Puzzle& p, size_
25 return CutEdgesInternal(copy, 0, p.width, 0, (p.height-1)/2, numEdges); 25 return CutEdgesInternal(copy, 0, p.width, 0, (p.height-1)/2, numEdges);
26 } else { 26 } else {
27 assert(p.symmetry == Puzzle::Symmetry::XY); 27 assert(p.symmetry == Puzzle::Symmetry::XY);
28 if (p.width%4 == 1) { 28 int midX = p.width/2;
29 assert(p.width == 9); 29 int midY = p.height/2;
30 copy.grid[2][3]; 30 if (p.width%4 == 1 && p.height%4 == 1) { // For double-even grids, cut around the center
31 copy.grid[3][4]; 31 copy.grid[midX-1][midY].gap = Cell::Gap::FULL;
32 copy.grid[3][6]; 32 copy.grid[midX][midY-1].gap = Cell::Gap::FULL;
33 copy.grid[4][3]; 33 copy.grid[midX][midY+1].gap = Cell::Gap::FULL;
34 // For odd grids, cut the center out. 34 copy.grid[midX+1][midY].gap = Cell::Gap::FULL;
35 // for (int x=0; x<p.width; x++) { 35 } else if (p.width%4 == 1 && p.height%4 == 3) { // For half-even grids, there's only one line to cut
36 // copy.grid[x][p.height/2].gap = Cell::Gap::FULL; 36 copy.grid[midX][midY].gap = Cell::Gap::FULL;
37 // } 37 } else if (p.width%4 == 3 && p.height%4 == 1) { // For half-even grids, there's only one line to cut
38 38 copy.grid[midX][midY].gap = Cell::Gap::FULL;
39 } 39 }
40 return CutEdgesInternal(copy, 0, p.width, 0, p.height, numEdges); 40 return CutEdgesInternal(copy, 0, p.width, 0, p.height, numEdges);
41 } 41 }
@@ -49,7 +49,11 @@ std::vector<Pos> Randomizer2Core::CutEdgesInternal(const Puzzle& p, int xMin, in
49 if (p.grid[x][y].gap != Cell::Gap::NONE) continue; 49 if (p.grid[x][y].gap != Cell::Gap::NONE) continue;
50 if (p.grid[x][y].start) continue; 50 if (p.grid[x][y].start) continue;
51 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 52
53 if (p.symmetry == Puzzle::Symmetry::XY) {
54 assert(p.width == p.height); // TODO: This solution only supports square rotational symmetry.
55 if (x > y) continue; // Only allow cuts bottom-left of the diagonal
56 }
53 57
54 // If the puzzle already has a sequence, don't cut along it. 58 // If the puzzle already has a sequence, don't cut along it.
55 bool inSequence = false; 59 bool inSequence = false;
@@ -63,6 +67,16 @@ std::vector<Pos> Randomizer2Core::CutEdgesInternal(const Puzzle& p, int xMin, in
63 auto [colorGrid, numColors] = CreateColorGrid(p); 67 auto [colorGrid, numColors] = CreateColorGrid(p);
64 assert(numEdges <= numColors); 68 assert(numEdges <= numColors);
65 69
70 // @Hack... sort of. I couldn't think of a better way to do this.
71 if (p.symmetry == Puzzle::Symmetry::XY) {
72 // Recolor the diagonal so that opposite cells share a color. This is because we're only cutting along half their edges,
73 // so they are in fact two sides of the same cell.
74 for (int x=1; x<p.width/2; x+=2) {
75 assert(p.width == p.height); // TODO: This solution only supports square rotational symmetry.
76 colorGrid[x][x] = colorGrid[p.width-x-1][p.width-x-1];
77 }
78 }
79
66 std::vector<Pos> cutEdges; 80 std::vector<Pos> cutEdges;
67 for (int i=0; i<numEdges; i++) { 81 for (int i=0; i<numEdges; i++) {
68 while (edges.size() > 0) { 82 while (edges.size() > 0) {