diff options
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 | ||
