diff options
Diffstat (limited to 'Source/PuzzleSerializer.cpp')
| -rw-r--r-- | Source/PuzzleSerializer.cpp | 120 |
1 files changed, 64 insertions, 56 deletions
| diff --git a/Source/PuzzleSerializer.cpp b/Source/PuzzleSerializer.cpp index fb4166b..3dffde1 100644 --- a/Source/PuzzleSerializer.cpp +++ b/Source/PuzzleSerializer.cpp | |||
| @@ -8,73 +8,81 @@ | |||
| 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 = _memory->ReadEntityData<int>(id, GRID_SIZE_X, 1)[0]; | ||
| 12 | int height = _memory->ReadEntityData<int>(id, GRID_SIZE_Y, 1)[0]; | ||
| 13 | if (width == 0) width = height; | ||
| 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. | ||
| 16 | |||
| 17 | _numGridLocations = width * height; // Highest location which represents a gridded intersection | ||
| 18 | _numIntersections = _memory->ReadEntityData<int>(id, NUM_DOTS, 1)[0]; | ||
| 19 | _intersectionFlags = _memory->ReadArray<int>(id, DOT_FLAGS, _numIntersections); | ||
| 20 | int numConnections = _memory->ReadEntityData<int>(id, NUM_CONNECTIONS, 1)[0]; | ||
| 21 | _connectionsA = _memory->ReadArray<int>(id, DOT_CONNECTION_A, numConnections); | ||
| 22 | _connectionsB = _memory->ReadArray<int>(id, DOT_CONNECTION_B, numConnections); | ||
| 23 | _intersectionLocations = _memory->ReadArray<float>(id, DOT_POSITIONS, _numIntersections*2); | ||
| 24 | |||
| 25 | Puzzle p; | 11 | Puzzle p; |
| 26 | p.NewGrid(width - 1, height - 1); | 12 | try { |
| 27 | ReadIntersections(p); | 13 | int width = _memory->ReadEntityData<int>(id, GRID_SIZE_X, 1)[0]; |
| 28 | ReadExtras(p); | 14 | int height = _memory->ReadEntityData<int>(id, GRID_SIZE_Y, 1)[0]; |
| 29 | ReadDecorations(p, id); | 15 | if (width == 0) width = height; |
| 30 | ReadSequence(p, id); | 16 | if (height == 0) height = width; |
| 31 | ReadSymmetry(p, id); | 17 | if (width < 0 || height < 0) return Puzzle(); // @Error: Grid size should be always positive? Looks like the starting panels break this rule, though. |
| 18 | |||
| 19 | _numGridLocations = width * height; // Highest location which represents a gridded intersection | ||
| 20 | _numIntersections = _memory->ReadEntityData<int>(id, NUM_DOTS, 1)[0]; | ||
| 21 | _intersectionFlags = _memory->ReadArray<int>(id, DOT_FLAGS, _numIntersections); | ||
| 22 | int numConnections = _memory->ReadEntityData<int>(id, NUM_CONNECTIONS, 1)[0]; | ||
| 23 | _connectionsA = _memory->ReadArray<int>(id, DOT_CONNECTION_A, numConnections); | ||
| 24 | _connectionsB = _memory->ReadArray<int>(id, DOT_CONNECTION_B, numConnections); | ||
| 25 | _intersectionLocations = _memory->ReadArray<float>(id, DOT_POSITIONS, _numIntersections*2); | ||
| 26 | |||
| 27 | p.NewGrid(width - 1, height - 1); | ||
| 28 | ReadIntersections(p); | ||
| 29 | ReadExtras(p); | ||
| 30 | ReadDecorations(p, id); | ||
| 31 | ReadSequence(p, id); | ||
| 32 | ReadSymmetry(p, id); | ||
| 33 | } catch (MemoryException exc) { | ||
| 34 | MemoryException::HandleException(exc); | ||
| 35 | } | ||
| 32 | return p; | 36 | return p; |
| 33 | } | 37 | } |
| 34 | 38 | ||
| 35 | void PuzzleSerializer::WritePuzzle(const Puzzle& p, int id) { | 39 | void PuzzleSerializer::WritePuzzle(const Puzzle& p, int id) { |
| 36 | _intersectionFlags.clear(); | 40 | try { |
| 37 | _connectionsA.clear(); | 41 | _intersectionFlags.clear(); |
| 38 | _connectionsB.clear(); | 42 | _connectionsA.clear(); |
| 39 | _intersectionLocations.clear(); | 43 | _connectionsB.clear(); |
| 40 | _extraLocations.clear(); | 44 | _intersectionLocations.clear(); |
| 41 | 45 | _extraLocations.clear(); | |
| 42 | MIN = 0.1f; | 46 | |
| 43 | MAX = 0.9f; | 47 | MIN = 0.1f; |
| 44 | WIDTH_INTERVAL = (MAX - MIN) / (p.width/2); | 48 | MAX = 0.9f; |
| 45 | HEIGHT_INTERVAL = (MAX - MIN) / (p.height/2); | 49 | WIDTH_INTERVAL = (MAX - MIN) / (p.width/2); |
| 46 | GAP_SIZE = min(WIDTH_INTERVAL, HEIGHT_INTERVAL) / 2; | 50 | HEIGHT_INTERVAL = (MAX - MIN) / (p.height/2); |
| 47 | // @Improvement: This will make grid cells square... but how do I keep the puzzle centered? Maybe save extra metadata? | 51 | GAP_SIZE = min(WIDTH_INTERVAL, HEIGHT_INTERVAL) / 2; |
| 48 | // INTERVAL = (MAX - MIN) / (max(p.width, p.height) / 2); | 52 | // @Improvement: This will make grid cells square... but how do I keep the puzzle centered? Maybe save extra metadata? |
| 49 | // GAP_SIZE = INTERVAL / 2; | 53 | // INTERVAL = (MAX - MIN) / (max(p.width, p.height) / 2); |
| 54 | // GAP_SIZE = INTERVAL / 2; | ||
| 50 | 55 | ||
| 51 | WriteIntersections(p); | 56 | WriteIntersections(p); |
| 52 | WriteEndpoints(p); | 57 | WriteEndpoints(p); |
| 53 | WriteDots(p); | 58 | WriteDots(p); |
| 54 | WriteGaps(p); | 59 | WriteGaps(p); |
| 55 | WriteDecorations(p, id); | 60 | WriteDecorations(p, id); |
| 56 | WriteSequence(p, id); | 61 | WriteSequence(p, id); |
| 57 | WriteSymmetry(p, id); | 62 | WriteSymmetry(p, id); |
| 58 | 63 | ||
| 59 | #ifndef NDEBUG | 64 | #ifndef NDEBUG |
| 60 | int maxDots = _memory->ReadEntityData<int>(id, NUM_DOTS, 1)[0]; | 65 | int maxDots = _memory->ReadEntityData<int>(id, NUM_DOTS, 1)[0]; |
| 61 | assert(_intersectionFlags.size() <= maxDots); | 66 | assert(_intersectionFlags.size() <= maxDots); |
| 62 | assert(_intersectionLocations.size() <= maxDots*2); | 67 | assert(_intersectionLocations.size() <= maxDots*2); |
| 63 | 68 | ||
| 64 | int maxConnections = _memory->ReadEntityData<int>(id, NUM_CONNECTIONS, 1)[0]; | 69 | int maxConnections = _memory->ReadEntityData<int>(id, NUM_CONNECTIONS, 1)[0]; |
| 65 | assert(_connectionsA.size() <= maxConnections); | 70 | assert(_connectionsA.size() <= maxConnections); |
| 66 | assert(_connectionsB.size() <= maxConnections); | 71 | assert(_connectionsB.size() <= maxConnections); |
| 67 | #endif | 72 | #endif |
| 68 | 73 | ||
| 69 | _memory->WriteEntityData<int>(id, GRID_SIZE_X, {(p.width + 1)/2}); | 74 | _memory->WriteEntityData<int>(id, GRID_SIZE_X, {(p.width + 1)/2}); |
| 70 | _memory->WriteEntityData<int>(id, GRID_SIZE_Y, {(p.height + 1)/2}); | 75 | _memory->WriteEntityData<int>(id, GRID_SIZE_Y, {(p.height + 1)/2}); |
| 71 | _memory->WriteEntityData<int>(id, NUM_DOTS, {static_cast<int>(_intersectionFlags.size())}); | 76 | _memory->WriteEntityData<int>(id, NUM_DOTS, {static_cast<int>(_intersectionFlags.size())}); |
| 72 | _memory->WriteArray<float>(id, DOT_POSITIONS, _intersectionLocations); | 77 | _memory->WriteArray<float>(id, DOT_POSITIONS, _intersectionLocations); |
| 73 | _memory->WriteArray<int>(id, DOT_FLAGS, _intersectionFlags); | 78 | _memory->WriteArray<int>(id, DOT_FLAGS, _intersectionFlags); |
| 74 | _memory->WriteEntityData<int>(id, NUM_CONNECTIONS, {static_cast<int>(_connectionsA.size())}); | 79 | _memory->WriteEntityData<int>(id, NUM_CONNECTIONS, {static_cast<int>(_connectionsA.size())}); |
| 75 | _memory->WriteArray<int>(id, DOT_CONNECTION_A, _connectionsA); | 80 | _memory->WriteArray<int>(id, DOT_CONNECTION_A, _connectionsA); |
| 76 | _memory->WriteArray<int>(id, DOT_CONNECTION_B, _connectionsB); | 81 | _memory->WriteArray<int>(id, DOT_CONNECTION_B, _connectionsB); |
| 77 | _memory->WriteEntityData<int>(id, NEEDS_REDRAW, {1}); | 82 | _memory->WriteEntityData<int>(id, NEEDS_REDRAW, {1}); |
| 83 | } catch (MemoryException exc) { | ||
| 84 | MemoryException::HandleException(exc); | ||
| 85 | } | ||
| 78 | } | 86 | } |
| 79 | 87 | ||
| 80 | void PuzzleSerializer::ReadIntersections(Puzzle& p) { | 88 | void PuzzleSerializer::ReadIntersections(Puzzle& p) { |
