summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Source/Memory.h4
-rw-r--r--Source/Randomizer2.cpp41
-rw-r--r--Source/Randomizer2Core.cpp16
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
13enum class ProcStatus { 13enum 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
157void Randomizer2::RandomizeSymmetry() { 151void 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 }