summary refs log tree commit diff stats
path: root/Source
diff options
context:
space:
mode:
authorjbzdarkid <jbzdarkid@gmail.com>2019-11-22 10:04:19 -0800
committerjbzdarkid <jbzdarkid@gmail.com>2019-11-22 10:04:19 -0800
commit059e44fa16b649938d79597bcf8f41bf4aa136ab (patch)
tree255c9f256ecae0923e872e62ccaab48221f12743 /Source
parentcbdf87bb8aaebca9c969dfec3c1664b9b6355a0d (diff)
downloadwitness-tutorializer-059e44fa16b649938d79597bcf8f41bf4aa136ab.tar.gz
witness-tutorializer-059e44fa16b649938d79597bcf8f41bf4aa136ab.tar.bz2
witness-tutorializer-059e44fa16b649938d79597bcf8f41bf4aa136ab.zip
fix more asymmetrical gap bugs
Diffstat (limited to 'Source')
-rw-r--r--Source/PuzzleSerializer.cpp20
-rw-r--r--Source/Randomizer2.cpp19
-rw-r--r--Source/Randomizer2Core.cpp23
3 files changed, 46 insertions, 16 deletions
diff --git a/Source/PuzzleSerializer.cpp b/Source/PuzzleSerializer.cpp index a131376..fb4166b 100644 --- a/Source/PuzzleSerializer.cpp +++ b/Source/PuzzleSerializer.cpp
@@ -485,7 +485,6 @@ void PuzzleSerializer::WriteSymmetry(const Puzzle& p, int id) {
485 reflectionData[location] = symLocation; 485 reflectionData[location] = symLocation;
486 reflectionData[symLocation] = location; 486 reflectionData[symLocation] = location;
487 if (p.grid[x][y].end != Cell::Dir::NONE) { 487 if (p.grid[x][y].end != Cell::Dir::NONE) {
488 // Rely on symmetry to set the other pair
489 location = extra_xy_to_loc(p, x, y); 488 location = extra_xy_to_loc(p, x, y);
490 Pos sym = p.GetSymmetricalPos(x, y); 489 Pos sym = p.GetSymmetricalPos(x, y);
491 symLocation = extra_xy_to_loc(p, sym.x, sym.y); 490 symLocation = extra_xy_to_loc(p, sym.x, sym.y);
@@ -503,11 +502,20 @@ void PuzzleSerializer::WriteSymmetry(const Puzzle& p, int id) {
503 int location = extra_xy_to_loc(p, x, y); 502 int location = extra_xy_to_loc(p, x, y);
504 int symLocation = extra_xy_to_loc(p, sym.x, sym.y); 503 int symLocation = extra_xy_to_loc(p, sym.x, sym.y);
505 // Each gap results in two intersections, @Assume they're written consecutively 504 // Each gap results in two intersections, @Assume they're written consecutively
506 // Rely on symmetry to set the other pairs 505
507 reflectionData[location] = symLocation; 506 if ((x%2 != 0 && p.symmetry & Puzzle::Symmetry::X) ||
508 reflectionData[location-1] = symLocation-1; 507 (y%2 != 0 && p.symmetry & Puzzle::Symmetry::Y)) {
509 reflectionData[symLocation] = location; 508 // Write data inverted, because it's being reflected
510 reflectionData[symLocation-1] = location-1; 509 reflectionData[location] = symLocation-1;
510 reflectionData[location-1] = symLocation;
511 reflectionData[symLocation] = location-1;
512 reflectionData[symLocation-1] = location;
513 } else { // Write data normally
514 reflectionData[location] = symLocation;
515 reflectionData[location-1] = symLocation-1;
516 reflectionData[symLocation] = location;
517 reflectionData[symLocation-1] = location-1;
518 }
511 } 519 }
512 } 520 }
513 521
diff --git a/Source/Randomizer2.cpp b/Source/Randomizer2.cpp index cc23c7d..c823567 100644 --- a/Source/Randomizer2.cpp +++ b/Source/Randomizer2.cpp
@@ -177,7 +177,24 @@ void Randomizer2::RandomizeSymmetry() {
177 Puzzle p; 177 Puzzle p;
178 p.NewGrid(4, 4); 178 p.NewGrid(4, 4);
179 p.symmetry = Puzzle::Symmetry::X; 179 p.symmetry = Puzzle::Symmetry::X;
180 180 p.grid[0][8].start = true;
181 p.grid[8][8].start = true;
182 p.grid[2][0].end = Cell::Dir::UP;
183 p.grid[6][0].end = Cell::Dir::UP;
184 // @Bug: This can still make the puzzle unsolvable, if it leaves the centerline free -- even though two lines can't pass through the centerline.
185 // ^ Try seed = 13710
186 std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 4);
187 for (int i=0; i<2; i++) {
188 Pos pos = cutEdges[i];
189 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
190 }
191 for (int i=2; i<4; i++) {
192 Pos pos = cutEdges[i];
193 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
194 p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
195 }
196
197 _serializer.WritePuzzle(p, 0x87);
181 } 198 }
182} 199}
183 200
diff --git a/Source/Randomizer2Core.cpp b/Source/Randomizer2Core.cpp index dcb9fd2..8ef2301 100644 --- a/Source/Randomizer2Core.cpp +++ b/Source/Randomizer2Core.cpp
@@ -15,9 +15,16 @@ std::vector<Pos> Randomizer2Core::CutInsideEdges(const Puzzle& p, size_t numEdge
15} 15}
16 16
17std::vector<Pos> Randomizer2Core::CutSymmetricalEdgePairs(const Puzzle& p, size_t numEdges) { 17std::vector<Pos> Randomizer2Core::CutSymmetricalEdgePairs(const Puzzle& p, size_t numEdges) {
18 Puzzle copy = p;
18 assert(p.symmetry != Puzzle::Symmetry::NONE); 19 assert(p.symmetry != Puzzle::Symmetry::NONE);
19 if (p.symmetry == Puzzle::Symmetry::X) { 20 if (p.symmetry == Puzzle::Symmetry::X) {
20 return CutEdgesInternal(p, 0, (p.width-1)/2, 0, p.height, numEdges); 21 if (p.width%4 == 1) { // Puzzle is even, so we need to prevent cutting the centerline
22 for (int y=0; y<p.height; y++) {
23 copy.grid[p.width/2][y].gap = Cell::Gap::FULL;
24 }
25 }
26
27 return CutEdgesInternal(copy, 0, (p.width-1)/2, 0, p.height, numEdges);
21 } 28 }
22 assert(false); 29 assert(false);
23 return {}; 30 return {};
@@ -93,10 +100,11 @@ std::vector<Pos> Randomizer2Core::CutEdgesInternal(const Puzzle& p, int xMin, in
93 100
94void Randomizer2Core::DebugColorGrid(const std::vector<std::vector<int>>& colorGrid) { 101void Randomizer2Core::DebugColorGrid(const std::vector<std::vector<int>>& colorGrid) {
95#ifndef NDEBUG 102#ifndef NDEBUG
103 static std::string colors = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
96 for (int y=0; y<colorGrid[0].size(); y++) { 104 for (int y=0; y<colorGrid[0].size(); y++) {
97 std::string row; 105 std::string row;
98 for (int x=0; x<colorGrid.size(); x++) { 106 for (int x=0; x<colorGrid.size(); x++) {
99 row += std::to_string(colorGrid[x][y]); 107 row += colors[colorGrid[x][y]];
100 } 108 }
101 row += "\n"; 109 row += "\n";
102 OutputDebugStringA(row.c_str()); 110 OutputDebugStringA(row.c_str());
@@ -128,13 +136,10 @@ void Randomizer2Core::FloodFillOutside(const Puzzle& p, std::vector<std::vector<
128 FloodFillOutside(p, colorGrid, x-1, y); 136 FloodFillOutside(p, colorGrid, x-1, y);
129} 137}
130 138
131/* 139// Color key:
132 undefined -> 1 (color of outside) or * (any colored cell) or -1 (edge/intersection not part of any region) 140// 0 (default): Uncolored
133 141// 1: Outside color and separator color
134 0 -> {} (this is a special edge case, which I don't need right now) 142// 2+: Flood-filled region color
135 1 -> 0 (uncolored / ready to color)
136 2 ->
137*/
138std::tuple<std::vector<std::vector<int>>, int> Randomizer2Core::CreateColorGrid(const Puzzle& p) { 143std::tuple<std::vector<std::vector<int>>, int> Randomizer2Core::CreateColorGrid(const Puzzle& p) {
139 std::vector<std::vector<int>> colorGrid; 144 std::vector<std::vector<int>> colorGrid;
140 colorGrid.resize(p.width); 145 colorGrid.resize(p.width);