diff options
| -rw-r--r-- | Source/Memory.h | 4 | ||||
| -rw-r--r-- | Source/Randomizer2.cpp | 41 | ||||
| -rw-r--r-- | Source/Randomizer2Core.cpp | 16 |
3 files changed, 26 insertions, 35 deletions
| diff --git a/Source/Memory.h b/Source/Memory.h index 803a5f1..d497123 100644 --- a/Source/Memory.h +++ b/Source/Memory.h | |||
| @@ -7,8 +7,8 @@ | |||
| 7 | #include <cassert> | 7 | #include <cassert> |
| 8 | #include "MemoryException.h" | 8 | #include "MemoryException.h" |
| 9 | 9 | ||
| 10 | // #define GLOBALS 0x5B28C0 | 10 | #define GLOBALS 0x5B28C0 |
| 11 | #define GLOBALS 0x62D0A0 | 11 | // #define GLOBALS 0x62D0A0 |
| 12 | 12 | ||
| 13 | enum class ProcStatus { | 13 | enum class ProcStatus { |
| 14 | NotRunning, | 14 | NotRunning, |
| diff --git a/Source/Randomizer2.cpp b/Source/Randomizer2.cpp index 782e248..993e7cc 100644 --- a/Source/Randomizer2.cpp +++ b/Source/Randomizer2.cpp | |||
| @@ -35,7 +35,6 @@ void Randomizer2::RandomizeTutorial() { | |||
| 35 | Puzzle p; | 35 | Puzzle p; |
| 36 | p.NewGrid(6, 6); | 36 | p.NewGrid(6, 6); |
| 37 | 37 | ||
| 38 | // @Bug: Mid-segment endpoints are not yet supported. | ||
| 39 | int x = Random::RandInt(0, (p.width-1)/2)*2; | 38 | int x = Random::RandInt(0, (p.width-1)/2)*2; |
| 40 | int y = Random::RandInt(0, (p.height-1)/2)*2; | 39 | int y = Random::RandInt(0, (p.height-1)/2)*2; |
| 41 | int rng = Random::RandInt(1, 4); | 40 | int rng = Random::RandInt(1, 4); |
| @@ -94,29 +93,24 @@ void Randomizer2::RandomizeTutorial() { | |||
| 94 | bool toTheRight; | 93 | bool toTheRight; |
| 95 | // Start by generating a cut line, to ensure one of the two startpoints is inaccessible | 94 | // Start by generating a cut line, to ensure one of the two startpoints is inaccessible |
| 96 | int x, y; | 95 | int x, y; |
| 97 | switch (Random::RandInt(1, 4)) | 96 | switch (Random::RandInt(1, 4)) { |
| 98 | { | ||
| 99 | case 1: | 97 | case 1: |
| 100 | x = 1; | 98 | x = 1; y = 1; |
| 101 | y = 1; | ||
| 102 | toTheRight = true; | 99 | toTheRight = true; |
| 103 | cuts.emplace_back(0, 1); | 100 | cuts.emplace_back(0, 1); |
| 104 | break; | 101 | break; |
| 105 | case 2: | 102 | case 2: |
| 106 | x = 1; | 103 | x = 1; y = 1; |
| 107 | y = 1; | ||
| 108 | toTheRight = true; | 104 | toTheRight = true; |
| 109 | cuts.emplace_back(1, 0); | 105 | cuts.emplace_back(1, 0); |
| 110 | break; | 106 | break; |
| 111 | case 3: | 107 | case 3: |
| 112 | x = 11; | 108 | x = 11; y = 1; |
| 113 | y = 1; | ||
| 114 | toTheRight = false; | 109 | toTheRight = false; |
| 115 | cuts.emplace_back(12, 1); | 110 | cuts.emplace_back(12, 1); |
| 116 | break; | 111 | break; |
| 117 | case 4: | 112 | case 4: |
| 118 | x = 11; | 113 | x = 11; y = 1; |
| 119 | y = 1; | ||
| 120 | toTheRight = false; | 114 | toTheRight = false; |
| 121 | cuts.emplace_back(11, 0); | 115 | cuts.emplace_back(11, 0); |
| 122 | break; | 116 | break; |
| @@ -136,7 +130,7 @@ void Randomizer2::RandomizeTutorial() { | |||
| 136 | } | 130 | } |
| 137 | break; | 131 | break; |
| 138 | case 3: | 132 | case 3: |
| 139 | case 4: // Go down (biased) | 133 | case 4: // Go down (biased x2) |
| 140 | cuts.emplace_back(x, y+1); | 134 | cuts.emplace_back(x, y+1); |
| 141 | y += 2; | 135 | y += 2; |
| 142 | break; | 136 | break; |
| @@ -155,8 +149,7 @@ void Randomizer2::RandomizeTutorial() { | |||
| 155 | } | 149 | } |
| 156 | 150 | ||
| 157 | void Randomizer2::RandomizeSymmetry() { | 151 | void Randomizer2::RandomizeSymmetry() { |
| 158 | // Back wall | 152 | { // Back wall 1 |
| 159 | { | ||
| 160 | Puzzle p; | 153 | Puzzle p; |
| 161 | p.NewGrid(3, 3); | 154 | p.NewGrid(3, 3); |
| 162 | p.symmetry = Puzzle::Symmetry::X; | 155 | p.symmetry = Puzzle::Symmetry::X; |
| @@ -173,7 +166,7 @@ void Randomizer2::RandomizeSymmetry() { | |||
| 173 | } | 166 | } |
| 174 | _serializer.WritePuzzle(p, 0x86); | 167 | _serializer.WritePuzzle(p, 0x86); |
| 175 | } | 168 | } |
| 176 | { | 169 | { // Back wall 2 |
| 177 | Puzzle p; | 170 | Puzzle p; |
| 178 | p.NewGrid(4, 4); | 171 | p.NewGrid(4, 4); |
| 179 | p.symmetry = Puzzle::Symmetry::X; | 172 | p.symmetry = Puzzle::Symmetry::X; |
| @@ -181,17 +174,17 @@ void Randomizer2::RandomizeSymmetry() { | |||
| 181 | p.grid[8][8].start = true; | 174 | p.grid[8][8].start = true; |
| 182 | p.grid[2][0].end = Cell::Dir::UP; | 175 | p.grid[2][0].end = Cell::Dir::UP; |
| 183 | p.grid[6][0].end = Cell::Dir::UP; | 176 | 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); | 177 | std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 4); |
| 187 | for (int i=0; i<2; i++) { | 178 | bool alternate = false; |
| 188 | Pos pos = cutEdges[i]; | 179 | for (int i=0; i<cutEdges.size(); 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]; | 180 | Pos pos = cutEdges[i]; |
| 193 | Pos sym = p.GetSymmetricalPos(pos.x, pos.y); | 181 | if (alternate) { |
| 194 | p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK; | 182 | p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK; |
| 183 | } else { | ||
| 184 | Pos sym = p.GetSymmetricalPos(pos.x, pos.y); | ||
| 185 | p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK; | ||
| 186 | } | ||
| 187 | alternate = !alternate; | ||
| 195 | } | 188 | } |
| 196 | 189 | ||
| 197 | _serializer.WritePuzzle(p, 0x87); | 190 | _serializer.WritePuzzle(p, 0x87); |
| diff --git a/Source/Randomizer2Core.cpp b/Source/Randomizer2Core.cpp index 8ef2301..5cae049 100644 --- a/Source/Randomizer2Core.cpp +++ b/Source/Randomizer2Core.cpp | |||
| @@ -18,7 +18,9 @@ std::vector<Pos> Randomizer2Core::CutSymmetricalEdgePairs(const Puzzle& p, size_ | |||
| 18 | Puzzle copy = p; | 18 | Puzzle copy = p; |
| 19 | assert(p.symmetry != Puzzle::Symmetry::NONE); | 19 | assert(p.symmetry != Puzzle::Symmetry::NONE); |
| 20 | if (p.symmetry == Puzzle::Symmetry::X) { | 20 | if (p.symmetry == Puzzle::Symmetry::X) { |
| 21 | if (p.width%4 == 1) { // Puzzle is even, so we need to prevent cutting the centerline | 21 | if (p.width%4 == 1) { |
| 22 | // The puzle has an even width (e.g. 4x4), so it has a midline for symmetry. | ||
| 23 | // Since this midline is unusable, we cut it pre-emptively. | ||
| 22 | for (int y=0; y<p.height; y++) { | 24 | for (int y=0; y<p.height; y++) { |
| 23 | copy.grid[p.width/2][y].gap = Cell::Gap::FULL; | 25 | copy.grid[p.width/2][y].gap = Cell::Gap::FULL; |
| 24 | } | 26 | } |
| @@ -147,23 +149,19 @@ std::tuple<std::vector<std::vector<int>>, int> Randomizer2Core::CreateColorGrid( | |||
| 147 | for (int x=0; x<p.width; x++) { | 149 | for (int x=0; x<p.width; x++) { |
| 148 | colorGrid[x].resize(p.height); | 150 | colorGrid[x].resize(p.height); |
| 149 | for (int y=0; y<p.height; y++) { | 151 | for (int y=0; y<p.height; y++) { |
| 152 | if (x%2 == 1 && y%2 == 1) continue; | ||
| 150 | // Mark all unbroken edges and intersections as 'do not color' | 153 | // Mark all unbroken edges and intersections as 'do not color' |
| 151 | if (x%2 != y%2) { | 154 | if (p.grid[x][y].gap == Cell::Gap::NONE) colorGrid[x][y] = 1; |
| 152 | if (p.grid[x][y].gap == Cell::Gap::NONE) colorGrid[x][y] = 1; | ||
| 153 | } else if (x%2 == 0 && y%2 == 0) { | ||
| 154 | // @Future: What about empty intersections? | ||
| 155 | colorGrid[x][y] = 1; // do not color intersections | ||
| 156 | } | ||
| 157 | } | 155 | } |
| 158 | } | 156 | } |
| 159 | 157 | ||
| 160 | // @Future: Skip this loop if pillar = true; | 158 | // @Future: Skip this loop if pillar = true; |
| 161 | for (int y=1; y<p.height; y+=2) { | 159 | for (int y=0; y<p.height; y++) { |
| 162 | FloodFillOutside(p, colorGrid, 0, y); | 160 | FloodFillOutside(p, colorGrid, 0, y); |
| 163 | FloodFillOutside(p, colorGrid, p.width - 1, y); | 161 | FloodFillOutside(p, colorGrid, p.width - 1, y); |
| 164 | } | 162 | } |
| 165 | 163 | ||
| 166 | for (int x=1; x<p.width; x+=2) { | 164 | for (int x=0; x<p.width; x++) { |
| 167 | FloodFillOutside(p, colorGrid, x, 0); | 165 | FloodFillOutside(p, colorGrid, x, 0); |
| 168 | FloodFillOutside(p, colorGrid, x, p.height - 1); | 166 | FloodFillOutside(p, colorGrid, x, p.height - 1); |
| 169 | } | 167 | } |
