summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorjbzdarkid <jbzdarkid@gmail.com>2019-11-16 15:08:14 -0800
committerjbzdarkid <jbzdarkid@gmail.com>2019-11-16 15:08:14 -0800
commitee426c3bde4b4c7fb1ea38a953d849e8893d8311 (patch)
tree35307ccba67f55f628be5df47dedf8a11d516c94
parentfc8649b12fc1280d81e8dd4d35736ed69c0d9909 (diff)
downloadwitness-tutorializer-ee426c3bde4b4c7fb1ea38a953d849e8893d8311.tar.gz
witness-tutorializer-ee426c3bde4b4c7fb1ea38a953d849e8893d8311.tar.bz2
witness-tutorializer-ee426c3bde4b4c7fb1ea38a953d849e8893d8311.zip
Some cleanup + bugfixes
-rw-r--r--Source/Puzzle.h25
-rw-r--r--Source/PuzzlerSerializer.cpp63
-rw-r--r--Source/PuzzlerSerializer.h2
3 files changed, 54 insertions, 36 deletions
diff --git a/Source/Puzzle.h b/Source/Puzzle.h index fdf51be..962874e 100644 --- a/Source/Puzzle.h +++ b/Source/Puzzle.h
@@ -38,25 +38,26 @@ struct Decoration {
38}; 38};
39 39
40struct Cell { 40struct Cell {
41 inline static Cell Undefined() {
42 Cell c;
43 c.undefined = true;
44 return c;
45 }
46 bool undefined = false;
47
48 bool start = false;
49 enum class Dir {NONE, LEFT, RIGHT, UP, DOWN};
50 Dir end = Dir::NONE;
51 std::shared_ptr<Decoration> decoration = nullptr;
52 enum class Dot {NONE, BLACK, BLUE, YELLOW, INVISIBLE}; 41 enum class Dot {NONE, BLACK, BLUE, YELLOW, INVISIBLE};
53 Dot dot = Dot::NONE; 42 Dot dot = Dot::NONE;
54 enum class Gap {NONE, BREAK, FULL}; 43 enum class Gap {NONE, BREAK, FULL};
55 Gap gap = Gap::NONE; 44 Gap gap = Gap::NONE;
56
57 // Line color 45 // Line color
58 enum class Color {NONE, BLACK, BLUE, YELLOW}; 46 enum class Color {NONE, BLACK, BLUE, YELLOW};
59 Color color = Color::NONE; 47 Color color = Color::NONE;
48
49 std::shared_ptr<Decoration> decoration = nullptr;
50
51 bool start = false;
52 enum class Dir {NONE, LEFT, RIGHT, UP, DOWN};
53 Dir end = Dir::NONE;
54
55 inline static Cell Undefined() {
56 Cell c;
57 c.undefined = true;
58 return c;
59 }
60 bool undefined = false;
60}; 61};
61 62
62struct Negation {}; 63struct Negation {};
diff --git a/Source/PuzzlerSerializer.cpp b/Source/PuzzlerSerializer.cpp index 8ab1649..abdfafd 100644 --- a/Source/PuzzlerSerializer.cpp +++ b/Source/PuzzlerSerializer.cpp
@@ -95,7 +95,7 @@ void PuzzleSerializer::ReadExtras(Puzzle& p) {
95 p.grid[x][y].start = true; 95 p.grid[x][y].start = true;
96 } 96 }
97 p.grid[x][y].dot = FlagsToDot(flags); 97 p.grid[x][y].dot = FlagsToDot(flags);
98 if (flags & Flags::IS_FULL_GAP) { 98 if (flags & Flags::HAS_NO_CONN) {
99 p.grid[x][y].gap = Cell::Gap::FULL; 99 p.grid[x][y].gap = Cell::Gap::FULL;
100 } 100 }
101 } 101 }
@@ -175,15 +175,13 @@ void PuzzleSerializer::WriteIntersections(const Puzzle& p) {
175 // Grided intersections 175 // Grided intersections
176 for (int y=p.height-1; y>=0; y-=2) { 176 for (int y=p.height-1; y>=0; y-=2) {
177 for (int x=0; x<p.width; x+=2) { 177 for (int x=0; x<p.width; x+=2) {
178 _intersectionLocations.push_back(MIN + (x/2) * WIDTH_INTERVAL); 178 auto [xPos, yPos] = xy_to_pos(p, x, y);
179 _intersectionLocations.push_back(MAX - (y/2) * HEIGHT_INTERVAL); 179 _intersectionLocations.push_back(xPos);
180 _intersectionLocations.push_back(yPos);
180 int flags = 0; 181 int flags = 0;
181 if (p.grid[x][y].start) { 182 if (p.grid[x][y].start) {
182 flags |= Flags::IS_STARTPOINT; 183 flags |= Flags::IS_STARTPOINT;
183 } 184 }
184 if (p.grid[x][y].gap == Cell::Gap::FULL) {
185 flags |= Flags::IS_FULL_GAP;
186 }
187 switch (p.grid[x][y].dot) { 185 switch (p.grid[x][y].dot) {
188 case Cell::Dot::BLACK: 186 case Cell::Dot::BLACK:
189 flags |= Flags::HAS_DOT; 187 flags |= Flags::HAS_DOT;
@@ -201,15 +199,15 @@ void PuzzleSerializer::WriteIntersections(const Puzzle& p) {
201 199
202 int numConnections = 0; 200 int numConnections = 0;
203 if (p.grid[x][y].end != Cell::Dir::NONE) numConnections++; 201 if (p.grid[x][y].end != Cell::Dir::NONE) numConnections++;
204 // Create connections for this intersection for bottom/left only. 202 // Create connections for this intersection for top/left only.
205 // Bottom connection 203 // Top connection
206 if (y > 0 && p.grid[x][y-1].gap != Cell::Gap::FULL) { 204 if (y > 0 && p.grid[x][y-1].gap != Cell::Gap::FULL) {
207 _connectionsA.push_back(xy_to_loc(p, x, y-2)); 205 _connectionsA.push_back(xy_to_loc(p, x, y-2));
208 _connectionsB.push_back(xy_to_loc(p, x, y)); 206 _connectionsB.push_back(xy_to_loc(p, x, y));
209 flags |= Flags::HAS_VERTI_CONN; 207 flags |= Flags::HAS_VERTI_CONN;
210 numConnections++; 208 numConnections++;
211 } 209 }
212 // Top connection 210 // Bottom connection
213 if (y < p.height - 1 && p.grid[x][y+1].gap != Cell::Gap::FULL) { 211 if (y < p.height - 1 && p.grid[x][y+1].gap != Cell::Gap::FULL) {
214 flags |= Flags::HAS_VERTI_CONN; 212 flags |= Flags::HAS_VERTI_CONN;
215 numConnections++; 213 numConnections++;
@@ -226,7 +224,9 @@ void PuzzleSerializer::WriteIntersections(const Puzzle& p) {
226 flags |= Flags::HAS_HORIZ_CONN; 224 flags |= Flags::HAS_HORIZ_CONN;
227 numConnections++; 225 numConnections++;
228 } 226 }
227 if (numConnections == 0) flags |= HAS_NO_CONN;
229 if (numConnections == 1) flags |= HAS_ONE_CONN; 228 if (numConnections == 1) flags |= HAS_ONE_CONN;
229
230 _intersectionFlags.push_back(flags); 230 _intersectionFlags.push_back(flags);
231 } 231 }
232 } 232 }
@@ -268,21 +268,25 @@ void PuzzleSerializer::WriteDots(const Puzzle& p) {
268 if (x%2 == y%2) continue; // Cells are invalid, intersections are already handled. 268 if (x%2 == y%2) continue; // Cells are invalid, intersections are already handled.
269 if (p.grid[x][y].dot == Cell::Dot::NONE) continue; 269 if (p.grid[x][y].dot == Cell::Dot::NONE) continue;
270 270
271 // We need to introduce a new segment -- 271 // We need to introduce a new segment which contains this dot. Break the existing segment, and add one.
272 // Locate the segment we're breaking 272 int connectionLocation = -1;
273 for (int i=0; i<_connectionsA.size(); i++) { 273 for (int i=0; i<_connectionsA.size(); i++) {
274 auto [x1, y1] = loc_to_xy(p, _connectionsA[i]); 274 auto [x1, y1] = loc_to_xy(p, _connectionsA[i]);
275 auto [x2, y2] = loc_to_xy(p, _connectionsB[i]); 275 auto [x2, y2] = loc_to_xy(p, _connectionsB[i]);
276 if ((x1+1 == x && x2-1 == x && y1 == y && y2 == y) || 276 if ((x1+1 == x && x2-1 == x && y1 == y && y2 == y) ||
277 (y1+1 == y && y2-1 == y && x1 == x && x2 == x)) { 277 (y1+1 == y && y2-1 == y && x1 == x && x2 == x)) {
278 int other_connection = _connectionsB[i]; 278 connectionLocation = i;
279 _connectionsB[i] = static_cast<int>(_intersectionFlags.size()); 279 break;
280
281 _connectionsA.push_back(other_connection);
282 _connectionsB.push_back(static_cast<int>(_intersectionFlags.size()));
283 break;
284 } 280 }
285 } 281 }
282 if (connectionLocation == -1) continue; // @Error
283
284 // @Assume: B > A for connections. To remove, add the horiz/verti check, see gaps.
285 int other_connection = _connectionsB[connectionLocation];
286 _connectionsB[connectionLocation] = static_cast<int>(_intersectionFlags.size());
287 _connectionsA.push_back(other_connection);
288 _connectionsB.push_back(static_cast<int>(_intersectionFlags.size()));
289
286 // Add this dot to the end 290 // Add this dot to the end
287 auto [xPos, yPos] = xy_to_pos(p, x, y); 291 auto [xPos, yPos] = xy_to_pos(p, x, y);
288 _intersectionLocations.push_back(xPos); 292 _intersectionLocations.push_back(xPos);
@@ -313,11 +317,24 @@ void PuzzleSerializer::WriteGaps(const Puzzle& p) {
313 if (x%2 == y%2) continue; // Cells are invalid, intersections are already handled. 317 if (x%2 == y%2) continue; // Cells are invalid, intersections are already handled.
314 if (p.grid[x][y].gap != Cell::Gap::BREAK) continue; 318 if (p.grid[x][y].gap != Cell::Gap::BREAK) continue;
315 319
320 // We need to introduce a new segment which contains this dot. Break the existing segment, and add one.
321 int connectionLocation = -1;
322 for (int i=0; i<_connectionsA.size(); i++) {
323 auto [x1, y1] = loc_to_xy(p, _connectionsA[i]);
324 auto [x2, y2] = loc_to_xy(p, _connectionsB[i]);
325 if ((x1+1 == x && x2-1 == x && y1 == y && y2 == y) ||
326 (y1+1 == y && y2-1 == y && x1 == x && x2 == x)) {
327 connectionLocation = i;
328 break;
329 }
330 }
331 if (connectionLocation == -1) continue; // @Error
332
316 auto [xPos, yPos] = xy_to_pos(p, x, y); 333 auto [xPos, yPos] = xy_to_pos(p, x, y);
317 // Reminder: Y goes from 0.0 (bottom) to 1.0 (top) 334 // Reminder: Y goes from 0.0 (bottom) to 1.0 (top)
318 if (x%2 == 0) { // Vertical gap 335 if (x%2 == 0) { // Vertical gap
319 _connectionsA.push_back(xy_to_loc(p, x, y-1)); 336 _connectionsA[connectionLocation] = xy_to_loc(p, x, y-1);
320 _connectionsB.push_back(static_cast<int>(_intersectionFlags.size())); 337 _connectionsB[connectionLocation] = static_cast<int>(_intersectionFlags.size());
321 _intersectionLocations.push_back(xPos); 338 _intersectionLocations.push_back(xPos);
322 _intersectionLocations.push_back(yPos + VERTI_GAP_SIZE / 2); 339 _intersectionLocations.push_back(yPos + VERTI_GAP_SIZE / 2);
323 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN); 340 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN);
@@ -328,8 +345,8 @@ void PuzzleSerializer::WriteGaps(const Puzzle& p) {
328 _intersectionLocations.push_back(yPos - VERTI_GAP_SIZE / 2); 345 _intersectionLocations.push_back(yPos - VERTI_GAP_SIZE / 2);
329 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN); 346 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN);
330 } else if (y%2 == 0) { // Horizontal gap 347 } else if (y%2 == 0) { // Horizontal gap
331 _connectionsA.push_back(xy_to_loc(p, x-1, y)); 348 _connectionsA[connectionLocation] = xy_to_loc(p, x-1, y);
332 _connectionsB.push_back(static_cast<int>(_intersectionFlags.size())); 349 _connectionsB[connectionLocation] = static_cast<int>(_intersectionFlags.size());
333 _intersectionLocations.push_back(xPos - HORIZ_GAP_SIZE / 2); 350 _intersectionLocations.push_back(xPos - HORIZ_GAP_SIZE / 2);
334 _intersectionLocations.push_back(yPos); 351 _intersectionLocations.push_back(yPos);
335 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_HORIZ_CONN); 352 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_HORIZ_CONN);
@@ -422,8 +439,8 @@ int PuzzleSerializer::xy_to_dloc(const Puzzle& p, int x, int y) const {
422 439
423std::tuple<float, float> PuzzleSerializer::xy_to_pos(const Puzzle& p, int x, int y) const { 440std::tuple<float, float> PuzzleSerializer::xy_to_pos(const Puzzle& p, int x, int y) const {
424 return { 441 return {
425 MIN + (x/2) * WIDTH_INTERVAL, 442 MIN + (x/2.0f) * WIDTH_INTERVAL,
426 MAX - (y/2) * HEIGHT_INTERVAL 443 MAX - (y/2.0f) * HEIGHT_INTERVAL
427 }; 444 };
428} 445}
429 446
diff --git a/Source/PuzzlerSerializer.h b/Source/PuzzlerSerializer.h index a49dd90..a3d821c 100644 --- a/Source/PuzzlerSerializer.h +++ b/Source/PuzzlerSerializer.h
@@ -17,7 +17,7 @@ private:
17 enum Flags { 17 enum Flags {
18 IS_ENDPOINT = 0x1, 18 IS_ENDPOINT = 0x1,
19 IS_STARTPOINT = 0x2, 19 IS_STARTPOINT = 0x2,
20 IS_FULL_GAP = 0x8, 20 HAS_NO_CONN = 0x8,
21 HAS_DOT = 0x20, 21 HAS_DOT = 0x20,
22 DOT_IS_BLUE = 0x100, 22 DOT_IS_BLUE = 0x100,
23 DOT_IS_ORANGE = 0x200, 23 DOT_IS_ORANGE = 0x200,