diff options
author | jbzdarkid <jbzdarkid@gmail.com> | 2019-11-20 20:30:25 -0800 |
---|---|---|
committer | jbzdarkid <jbzdarkid@gmail.com> | 2019-11-20 20:30:25 -0800 |
commit | d5bce3bba23a5ba4c296f1783ba277bcc206736c (patch) | |
tree | 64835daf9aeb54fa779e06426a777861d68195e4 /Source/PuzzleSerializer.cpp | |
parent | 6f0a34bfb761d965bd961dc1f880b84e35f9959f (diff) | |
download | witness-tutorializer-d5bce3bba23a5ba4c296f1783ba277bcc206736c.tar.gz witness-tutorializer-d5bce3bba23a5ba4c296f1783ba277bcc206736c.tar.bz2 witness-tutorializer-d5bce3bba23a5ba4c296f1783ba277bcc206736c.zip |
Some progress on symmetry.
Diffstat (limited to 'Source/PuzzleSerializer.cpp')
-rw-r--r-- | Source/PuzzleSerializer.cpp | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/Source/PuzzleSerializer.cpp b/Source/PuzzleSerializer.cpp index 132ebb7..e7381d8 100644 --- a/Source/PuzzleSerializer.cpp +++ b/Source/PuzzleSerializer.cpp | |||
@@ -8,8 +8,8 @@ | |||
8 | PuzzleSerializer::PuzzleSerializer(const std::shared_ptr<Memory>& memory) : _memory(memory) {} | 8 | PuzzleSerializer::PuzzleSerializer(const std::shared_ptr<Memory>& memory) : _memory(memory) {} |
9 | 9 | ||
10 | Puzzle PuzzleSerializer::ReadPuzzle(int id) { | 10 | Puzzle PuzzleSerializer::ReadPuzzle(int id) { |
11 | int width = 2 * _memory->ReadEntityData<int>(id, GRID_SIZE_X, 1)[0] - 1; | 11 | int width = _memory->ReadEntityData<int>(id, GRID_SIZE_X, 1)[0] - 1; |
12 | int height = 2 * _memory->ReadEntityData<int>(id, GRID_SIZE_Y, 1)[0] - 1; | 12 | int height = _memory->ReadEntityData<int>(id, GRID_SIZE_Y, 1)[0] - 1; |
13 | if (width == 0) width = height; | 13 | if (width == 0) width = height; |
14 | if (height == 0) height = width; | 14 | if (height == 0) height = width; |
15 | if (width < 0 || height < 0) return Puzzle(); // @Error: Grid size should be always positive? Looks like the starting panels break this rule, though. | 15 | if (width < 0 || height < 0) return Puzzle(); // @Error: Grid size should be always positive? Looks like the starting panels break this rule, though. |
@@ -45,11 +45,12 @@ void PuzzleSerializer::WritePuzzle(const Puzzle& p, int id) { | |||
45 | VERTI_GAP_SIZE = HEIGHT_INTERVAL / 2; | 45 | VERTI_GAP_SIZE = HEIGHT_INTERVAL / 2; |
46 | 46 | ||
47 | WriteIntersections(p); | 47 | WriteIntersections(p); |
48 | WriteEndpoints(p); | ||
48 | WriteDots(p); | 49 | WriteDots(p); |
49 | WriteGaps(p); | 50 | WriteGaps(p); |
50 | WriteEndpoints(p); | ||
51 | WriteDecorations(p, id); | 51 | WriteDecorations(p, id); |
52 | WriteSequence(p, id); | 52 | WriteSequence(p, id); |
53 | WriteSymmetry(p, id); | ||
53 | 54 | ||
54 | #ifndef NDEBUG | 55 | #ifndef NDEBUG |
55 | int maxDots = _memory->ReadEntityData<int>(id, NUM_DOTS, 1)[0]; | 56 | int maxDots = _memory->ReadEntityData<int>(id, NUM_DOTS, 1)[0]; |
@@ -190,9 +191,9 @@ void PuzzleSerializer::ReadSymmetry(Puzzle& p, int id) { | |||
190 | Pos p1 = loc_to_xy(p, reflectionData[0]); | 191 | Pos p1 = loc_to_xy(p, reflectionData[0]); |
191 | Pos p2 = loc_to_xy(p, reflectionData[reflectionData[0]]); | 192 | Pos p2 = loc_to_xy(p, reflectionData[reflectionData[0]]); |
192 | if (p1.x != p2.x) { | 193 | if (p1.x != p2.x) { |
193 | p.symmetry = Puzzle::Symmetry::Y; | ||
194 | } else if (p1.y != p2.y) { | ||
195 | p.symmetry = Puzzle::Symmetry::X; | 194 | p.symmetry = Puzzle::Symmetry::X; |
195 | } else if (p1.y != p2.y) { | ||
196 | p.symmetry = Puzzle::Symmetry::Y; | ||
196 | } else { | 197 | } else { |
197 | p.symmetry = Puzzle::Symmetry::XY; | 198 | p.symmetry = Puzzle::Symmetry::XY; |
198 | } | 199 | } |
@@ -260,6 +261,12 @@ void PuzzleSerializer::WriteIntersections(const Puzzle& p) { | |||
260 | } | 261 | } |
261 | 262 | ||
262 | void PuzzleSerializer::WriteEndpoints(const Puzzle& p) { | 263 | void PuzzleSerializer::WriteEndpoints(const Puzzle& p) { |
264 | // int xMin, xMax, yMin, yMax; | ||
265 | // | ||
266 | // if (p.symmetry == Puzzle::Symmetry::NONE) { | ||
267 | // xMin = | ||
268 | // } | ||
269 | |||
263 | for (int x=0; x<p.width; x++) { | 270 | for (int x=0; x<p.width; x++) { |
264 | for (int y=0; y<p.height; y++) { | 271 | for (int y=0; y<p.height; y++) { |
265 | if (p.grid[x][y].end == Cell::Dir::NONE) continue; | 272 | if (p.grid[x][y].end == Cell::Dir::NONE) continue; |
@@ -352,6 +359,7 @@ void PuzzleSerializer::WriteGaps(const Puzzle& p) { | |||
352 | if (connectionLocation == -1) continue; // @Error | 359 | if (connectionLocation == -1) continue; // @Error |
353 | 360 | ||
354 | auto [xPos, yPos] = xy_to_pos(p, x, y); | 361 | auto [xPos, yPos] = xy_to_pos(p, x, y); |
362 | // TODO: Use AddIntersection here? | ||
355 | // Reminder: Y goes from 0.0 (bottom) to 1.0 (top) | 363 | // Reminder: Y goes from 0.0 (bottom) to 1.0 (top) |
356 | if (x%2 == 0) { // Vertical gap | 364 | if (x%2 == 0) { // Vertical gap |
357 | _connectionsA[connectionLocation] = xy_to_loc(p, x, y-1); | 365 | _connectionsA[connectionLocation] = xy_to_loc(p, x, y-1); |
@@ -429,22 +437,32 @@ void PuzzleSerializer::WriteSymmetry(const Puzzle& p, int id) { | |||
429 | return; | 437 | return; |
430 | } | 438 | } |
431 | 439 | ||
432 | // TODO: This. Probably 3 different sections for the different types? | 440 | std::vector<int> reflectionData; |
433 | // The idea is simple, though, just write symmetry data for all endpoints. | 441 | reflectionData.resize(_intersectionFlags.size()); |
434 | // Handle the default grid... then just separate iterators for dots/gaps/endpoints? Gross, but might work. | 442 | |
435 | // I think this might put constraints on how I build the dots/gaps, actually. Let me see. | 443 | // Wow, what a horrible solution. But hey, whatever, if it works. |
436 | /* | 444 | for (int x=0; x<p.width; x+=2) { |
437 | Pos p1 = loc_to_xy(p, reflectionData[0]); | 445 | for (int y=0; y<p.height; y+=2) { |
438 | Pos p2 = loc_to_xy(p, reflectionData[reflectionData[0]]); | 446 | Pos sym = p.GetSymmetricalPos(x, y); |
439 | if (p1.x != p2.x) { | 447 | int location = xy_to_loc(p, x, y); |
440 | p.symmetry = Puzzle::Symmetry::Y; | 448 | int symLocation = xy_to_loc(p, sym.x, sym.y); |
441 | } else if (p1.y != p2.y) { | 449 | reflectionData[location] = symLocation; |
442 | p.symmetry = Puzzle::Symmetry::X; | 450 | reflectionData[symLocation] = location; |
443 | } else { | 451 | if (p.grid[x][y].end != Cell::Dir::NONE) { |
444 | p.symmetry = Puzzle::Symmetry::XY; | 452 | location = extra_xy_to_loc(Pos{x, y}); |
453 | symLocation = extra_xy_to_loc(p.GetSymmetricalPos(x, y)); | ||
454 | reflectionData[location] = symLocation; | ||
455 | reflectionData[symLocation] = location; | ||
456 | } | ||
457 | } | ||
445 | } | 458 | } |
446 | 459 | ||
447 | */ | 460 | auto [x, y] = loc_to_xy(p, 0); |
461 | Pos sym = p.GetSymmetricalPos(x, y); | ||
462 | int i = xy_to_loc(p, sym.x, sym.y); | ||
463 | |||
464 | int k = 1; | ||
465 | // TODO: Done? No, still need gaps (if they're reflected). No idea how to do this, though. Maybe I can safely assume that they're at consecutive locations? | ||
448 | } | 466 | } |
449 | 467 | ||
450 | std::tuple<int, int> PuzzleSerializer::loc_to_xy(const Puzzle& p, int location) const { | 468 | std::tuple<int, int> PuzzleSerializer::loc_to_xy(const Puzzle& p, int location) const { |
@@ -457,6 +475,8 @@ std::tuple<int, int> PuzzleSerializer::loc_to_xy(const Puzzle& p, int location) | |||
457 | } | 475 | } |
458 | 476 | ||
459 | int PuzzleSerializer::xy_to_loc(const Puzzle& p, int x, int y) const { | 477 | int PuzzleSerializer::xy_to_loc(const Puzzle& p, int x, int y) const { |
478 | assert(x%2 == 0); | ||
479 | assert(y%2 == 0); | ||
460 | int height2 = (p.height - 1) / 2; | 480 | int height2 = (p.height - 1) / 2; |
461 | int width2 = (p.width + 1) / 2; | 481 | int width2 = (p.width + 1) / 2; |
462 | 482 | ||