diff options
| -rw-r--r-- | Source/PuzzleSerializer.cpp | 116 | ||||
| -rw-r--r-- | Source/PuzzleSerializer.h | 11 |
2 files changed, 65 insertions, 62 deletions
| diff --git a/Source/PuzzleSerializer.cpp b/Source/PuzzleSerializer.cpp index e7381d8..f0ddf0b 100644 --- a/Source/PuzzleSerializer.cpp +++ b/Source/PuzzleSerializer.cpp | |||
| @@ -8,12 +8,13 @@ | |||
| 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] - 1; | 11 | int width = _memory->ReadEntityData<int>(id, GRID_SIZE_X, 1)[0]; |
| 12 | int height = _memory->ReadEntityData<int>(id, GRID_SIZE_Y, 1)[0] - 1; | 12 | int height = _memory->ReadEntityData<int>(id, GRID_SIZE_Y, 1)[0]; |
| 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. |
| 16 | 16 | ||
| 17 | _numGridLocations = width * height; // Highest location which represents a gridded intersection | ||
| 17 | _numIntersections = _memory->ReadEntityData<int>(id, NUM_DOTS, 1)[0]; | 18 | _numIntersections = _memory->ReadEntityData<int>(id, NUM_DOTS, 1)[0]; |
| 18 | _intersectionFlags = _memory->ReadArray<int>(id, DOT_FLAGS, _numIntersections); | 19 | _intersectionFlags = _memory->ReadArray<int>(id, DOT_FLAGS, _numIntersections); |
| 19 | int numConnections = _memory->ReadEntityData<int>(id, NUM_CONNECTIONS, 1)[0]; | 20 | int numConnections = _memory->ReadEntityData<int>(id, NUM_CONNECTIONS, 1)[0]; |
| @@ -22,7 +23,7 @@ Puzzle PuzzleSerializer::ReadPuzzle(int id) { | |||
| 22 | _intersectionLocations = _memory->ReadArray<float>(id, DOT_POSITIONS, _numIntersections*2); | 23 | _intersectionLocations = _memory->ReadArray<float>(id, DOT_POSITIONS, _numIntersections*2); |
| 23 | 24 | ||
| 24 | Puzzle p; | 25 | Puzzle p; |
| 25 | p.NewGrid(width, height); | 26 | p.NewGrid(width - 1, height - 1); |
| 26 | ReadIntersections(p); | 27 | ReadIntersections(p); |
| 27 | ReadExtras(p); | 28 | ReadExtras(p); |
| 28 | ReadDecorations(p, id); | 29 | ReadDecorations(p, id); |
| @@ -36,14 +37,17 @@ void PuzzleSerializer::WritePuzzle(const Puzzle& p, int id) { | |||
| 36 | _connectionsA.clear(); | 37 | _connectionsA.clear(); |
| 37 | _connectionsB.clear(); | 38 | _connectionsB.clear(); |
| 38 | _intersectionLocations.clear(); | 39 | _intersectionLocations.clear(); |
| 40 | _extraLocations.clear(); | ||
| 39 | 41 | ||
| 40 | MIN = 0.1f; | 42 | MIN = 0.1f; |
| 41 | MAX = 0.9f; | 43 | MAX = 0.9f; |
| 42 | WIDTH_INTERVAL = (MAX - MIN) / (p.width/2); | 44 | WIDTH_INTERVAL = (MAX - MIN) / (p.width/2); |
| 43 | HEIGHT_INTERVAL = (MAX - MIN) / (p.height/2); | 45 | HEIGHT_INTERVAL = (MAX - MIN) / (p.height/2); |
| 44 | HORIZ_GAP_SIZE = WIDTH_INTERVAL / 2; | 46 | GAP_SIZE = min(WIDTH_INTERVAL, HEIGHT_INTERVAL) / 2; |
| 45 | VERTI_GAP_SIZE = HEIGHT_INTERVAL / 2; | 47 | // @Improvement: This will make grid cells square... but how do I keep the puzzle centered? |
| 46 | 48 | // INTERVAL = (MAX - MIN) / (max(p.width, p.height) / 2); | |
| 49 | // GAP_SIZE = INTERVAL / 2; | ||
| 50 | |||
| 47 | WriteIntersections(p); | 51 | WriteIntersections(p); |
| 48 | WriteEndpoints(p); | 52 | WriteEndpoints(p); |
| 49 | WriteDots(p); | 53 | WriteDots(p); |
| @@ -82,14 +86,17 @@ void PuzzleSerializer::ReadIntersections(Puzzle& p) { | |||
| 82 | } | 86 | } |
| 83 | } | 87 | } |
| 84 | 88 | ||
| 85 | for (int j=0; j<_numIntersections; j++) { | 89 | for (int i=0; i<_numIntersections; i++) { |
| 86 | if (_intersectionFlags[_connectionsA[j]] & Flags::IS_ENDPOINT) break; | 90 | int locationA = _connectionsA[i]; |
| 87 | if (_intersectionFlags[_connectionsB[j]] & Flags::IS_ENDPOINT) break; | 91 | int locationB = _connectionsB[i]; |
| 88 | float x1 = _intersectionLocations[2*_connectionsA[j]]; | 92 | if (locationA > locationB) std::swap(locationA, locationB); // A < B |
| 89 | float y1 = _intersectionLocations[2*_connectionsA[j]+1]; | 93 | if (locationB >= _numGridLocations) continue; // Connection goes to a non-grid location |
| 90 | float x2 = _intersectionLocations[2*_connectionsB[j]]; | 94 | |
| 91 | float y2 = _intersectionLocations[2*_connectionsB[j]+1]; | 95 | float x1 = _intersectionLocations[2*locationA]; |
| 92 | auto [x, y] = loc_to_xy(p, _connectionsA[j]); | 96 | float y1 = _intersectionLocations[2*locationA+1]; |
| 97 | float x2 = _intersectionLocations[2*locationB]; | ||
| 98 | float y2 = _intersectionLocations[2*locationB+1]; | ||
| 99 | auto [x, y] = loc_to_xy(p, locationA); | ||
| 93 | 100 | ||
| 94 | if (x1 < x2) x++; | 101 | if (x1 < x2) x++; |
| 95 | else if (x1 > x2) x--; | 102 | else if (x1 > x2) x--; |
| @@ -100,12 +107,11 @@ void PuzzleSerializer::ReadIntersections(Puzzle& p) { | |||
| 100 | } | 107 | } |
| 101 | 108 | ||
| 102 | void PuzzleSerializer::ReadExtras(Puzzle& p) { | 109 | void PuzzleSerializer::ReadExtras(Puzzle& p) { |
| 103 | // This iterates bottom-top, left-right | 110 | // This iterates left-right, bottom-top |
| 104 | int i = 0; | 111 | int i = 0; |
| 105 | for (; i < _numIntersections; i++) { | 112 | for (; i < _numGridLocations; i++) { |
| 106 | int flags = _intersectionFlags[i]; | 113 | int flags = _intersectionFlags[i]; |
| 107 | auto [x, y] = loc_to_xy(p, i); | 114 | auto [x, y] = loc_to_xy(p, i); |
| 108 | if (y < 0) break; // This is the expected exit point | ||
| 109 | if (flags & Flags::IS_STARTPOINT) { | 115 | if (flags & Flags::IS_STARTPOINT) { |
| 110 | p.grid[x][y].start = true; | 116 | p.grid[x][y].start = true; |
| 111 | } | 117 | } |
| @@ -201,7 +207,7 @@ void PuzzleSerializer::ReadSymmetry(Puzzle& p, int id) { | |||
| 201 | 207 | ||
| 202 | void PuzzleSerializer::WriteIntersections(const Puzzle& p) { | 208 | void PuzzleSerializer::WriteIntersections(const Puzzle& p) { |
| 203 | // @Cleanup: If I write directly to locations, then I can simplify this gross loop iterator. | 209 | // @Cleanup: If I write directly to locations, then I can simplify this gross loop iterator. |
| 204 | // int numIntersections = (p.width / 2 + 1) * (p.height / 2 + 1); | 210 | // Use _numGridIntersections computation: = (p.width / 2 + 1) * (p.height / 2 + 1); |
| 205 | // Grided intersections | 211 | // Grided intersections |
| 206 | for (int y=p.height-1; y>=0; y-=2) { | 212 | for (int y=p.height-1; y>=0; y-=2) { |
| 207 | for (int x=0; x<p.width; x+=2) { | 213 | for (int x=0; x<p.width; x+=2) { |
| @@ -255,18 +261,12 @@ void PuzzleSerializer::WriteIntersections(const Puzzle& p) { | |||
| 255 | if (numConnections == 1) flags |= HAS_ONE_CONN; | 261 | if (numConnections == 1) flags |= HAS_ONE_CONN; |
| 256 | 262 | ||
| 257 | auto [xPos, yPos] = xy_to_pos(p, x, y); | 263 | auto [xPos, yPos] = xy_to_pos(p, x, y); |
| 258 | AddIntersection(x, y, xPos, yPos, flags); | 264 | AddIntersection(p, x, y, xPos, yPos, flags); |
| 259 | } | 265 | } |
| 260 | } | 266 | } |
| 261 | } | 267 | } |
| 262 | 268 | ||
| 263 | void PuzzleSerializer::WriteEndpoints(const Puzzle& p) { | 269 | void PuzzleSerializer::WriteEndpoints(const Puzzle& p) { |
| 264 | // int xMin, xMax, yMin, yMax; | ||
| 265 | // | ||
| 266 | // if (p.symmetry == Puzzle::Symmetry::NONE) { | ||
| 267 | // xMin = | ||
| 268 | // } | ||
| 269 | |||
| 270 | for (int x=0; x<p.width; x++) { | 270 | for (int x=0; x<p.width; x++) { |
| 271 | for (int y=0; y<p.height; y++) { | 271 | for (int y=0; y<p.height; y++) { |
| 272 | if (p.grid[x][y].end == Cell::Dir::NONE) continue; | 272 | if (p.grid[x][y].end == Cell::Dir::NONE) continue; |
| @@ -288,7 +288,7 @@ void PuzzleSerializer::WriteEndpoints(const Puzzle& p) { | |||
| 288 | yPos -= .05f; | 288 | yPos -= .05f; |
| 289 | break; | 289 | break; |
| 290 | } | 290 | } |
| 291 | AddIntersection(x, y, xPos, yPos, Flags::IS_ENDPOINT); | 291 | AddIntersection(p, x, y, xPos, yPos, Flags::IS_ENDPOINT); |
| 292 | } | 292 | } |
| 293 | } | 293 | } |
| 294 | } | 294 | } |
| @@ -334,7 +334,7 @@ void PuzzleSerializer::WriteDots(const Puzzle& p) { | |||
| 334 | } | 334 | } |
| 335 | 335 | ||
| 336 | auto [xPos, yPos] = xy_to_pos(p, x, y); | 336 | auto [xPos, yPos] = xy_to_pos(p, x, y); |
| 337 | AddIntersection(x, y, xPos, yPos, flags); | 337 | AddIntersection(p, x, y, xPos, yPos, flags); |
| 338 | } | 338 | } |
| 339 | } | 339 | } |
| 340 | } | 340 | } |
| @@ -364,27 +364,19 @@ void PuzzleSerializer::WriteGaps(const Puzzle& p) { | |||
| 364 | if (x%2 == 0) { // Vertical gap | 364 | if (x%2 == 0) { // Vertical gap |
| 365 | _connectionsA[connectionLocation] = xy_to_loc(p, x, y-1); | 365 | _connectionsA[connectionLocation] = xy_to_loc(p, x, y-1); |
| 366 | _connectionsB[connectionLocation] = static_cast<int>(_intersectionFlags.size()); | 366 | _connectionsB[connectionLocation] = static_cast<int>(_intersectionFlags.size()); |
| 367 | _intersectionLocations.push_back(xPos); | 367 | AddIntersection(p, x, y, xPos, yPos + GAP_SIZE / 2, Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN); |
| 368 | _intersectionLocations.push_back(yPos + VERTI_GAP_SIZE / 2); | ||
| 369 | _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN); | ||
| 370 | 368 | ||
| 371 | _connectionsA.push_back(xy_to_loc(p, x, y+1)); | 369 | _connectionsA.push_back(xy_to_loc(p, x, y+1)); |
| 372 | _connectionsB.push_back(static_cast<int>(_intersectionFlags.size())); | 370 | _connectionsB.push_back(static_cast<int>(_intersectionFlags.size())); |
| 373 | _intersectionLocations.push_back(xPos); | 371 | AddIntersection(p, x, y, xPos, yPos - GAP_SIZE / 2, Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN); |
| 374 | _intersectionLocations.push_back(yPos - VERTI_GAP_SIZE / 2); | ||
| 375 | _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN); | ||
| 376 | } else if (y%2 == 0) { // Horizontal gap | 372 | } else if (y%2 == 0) { // Horizontal gap |
| 377 | _connectionsA[connectionLocation] = xy_to_loc(p, x-1, y); | 373 | _connectionsA[connectionLocation] = xy_to_loc(p, x-1, y); |
| 378 | _connectionsB[connectionLocation] = static_cast<int>(_intersectionFlags.size()); | 374 | _connectionsB[connectionLocation] = static_cast<int>(_intersectionFlags.size()); |
| 379 | _intersectionLocations.push_back(xPos - HORIZ_GAP_SIZE / 2); | 375 | AddIntersection(p, x, y, xPos - GAP_SIZE / 2, yPos, Flags::HAS_ONE_CONN | Flags::HAS_HORIZ_CONN); |
| 380 | _intersectionLocations.push_back(yPos); | ||
| 381 | _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_HORIZ_CONN); | ||
| 382 | 376 | ||
| 383 | _connectionsA.push_back(xy_to_loc(p, x+1, y)); | 377 | _connectionsA.push_back(xy_to_loc(p, x+1, y)); |
| 384 | _connectionsB.push_back(static_cast<int>(_intersectionFlags.size())); | 378 | _connectionsB.push_back(static_cast<int>(_intersectionFlags.size())); |
| 385 | _intersectionLocations.push_back(xPos + HORIZ_GAP_SIZE / 2); | 379 | AddIntersection(p, x, y, xPos + GAP_SIZE / 2, yPos, Flags::HAS_ONE_CONN | Flags::HAS_HORIZ_CONN); |
| 386 | _intersectionLocations.push_back(yPos); | ||
| 387 | _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_HORIZ_CONN); | ||
| 388 | } | 380 | } |
| 389 | } | 381 | } |
| 390 | } | 382 | } |
| @@ -424,8 +416,9 @@ void PuzzleSerializer::WriteSequence(const Puzzle& p, int id) { | |||
| 424 | } | 416 | } |
| 425 | } | 417 | } |
| 426 | 418 | ||
| 427 | Pos endpoint = p.sequence[p.sequence.size() - 1]; | 419 | // TODO: Orphaned code? |
| 428 | int location = extra_xy_to_loc(endpoint); | 420 | // Pos endpoint = p.sequence[p.sequence.size() - 1]; |
| 421 | // int location = extra_xy_to_loc(p, endpoint.x, endpoint.y); | ||
| 429 | 422 | ||
| 430 | _memory->WriteEntityData<int>(id, SEQUENCE_LEN, {static_cast<int>(sequence.size())}); | 423 | _memory->WriteEntityData<int>(id, SEQUENCE_LEN, {static_cast<int>(sequence.size())}); |
| 431 | _memory->WriteNewArray<int>(id, SEQUENCE, sequence); | 424 | _memory->WriteNewArray<int>(id, SEQUENCE, sequence); |
| @@ -449,20 +442,31 @@ void PuzzleSerializer::WriteSymmetry(const Puzzle& p, int id) { | |||
| 449 | reflectionData[location] = symLocation; | 442 | reflectionData[location] = symLocation; |
| 450 | reflectionData[symLocation] = location; | 443 | reflectionData[symLocation] = location; |
| 451 | if (p.grid[x][y].end != Cell::Dir::NONE) { | 444 | if (p.grid[x][y].end != Cell::Dir::NONE) { |
| 452 | location = extra_xy_to_loc(Pos{x, y}); | 445 | // Rely on symmetry to set the other pair |
| 453 | symLocation = extra_xy_to_loc(p.GetSymmetricalPos(x, y)); | 446 | location = extra_xy_to_loc(p, x, y); |
| 447 | Pos sym = p.GetSymmetricalPos(x, y); | ||
| 448 | symLocation = extra_xy_to_loc(p, sym.x, sym.y); | ||
| 454 | reflectionData[location] = symLocation; | 449 | reflectionData[location] = symLocation; |
| 455 | reflectionData[symLocation] = location; | ||
| 456 | } | 450 | } |
| 457 | } | 451 | } |
| 458 | } | 452 | } |
| 459 | 453 | ||
| 460 | auto [x, y] = loc_to_xy(p, 0); | 454 | for (int x=0; x<p.width; x++) { |
| 461 | Pos sym = p.GetSymmetricalPos(x, y); | 455 | for (int y=0; y<p.height; y++) { |
| 462 | int i = xy_to_loc(p, sym.x, sym.y); | 456 | if (x%2 == y%2) continue; |
| 457 | if (p.grid[x][y].gap != Cell::Gap::BREAK) continue; | ||
| 463 | 458 | ||
| 464 | int k = 1; | 459 | Pos sym = p.GetSymmetricalPos(x, y); |
| 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? | 460 | int location = extra_xy_to_loc(p, x, y); |
| 461 | int symLocation = extra_xy_to_loc(p, sym.x, sym.y); | ||
| 462 | // Each gap results in two intersections, @Assume they're written consecutively | ||
| 463 | // Rely on symmetry to set the other pairs | ||
| 464 | reflectionData[location] = symLocation; | ||
| 465 | reflectionData[location-1] = symLocation-1; | ||
| 466 | } | ||
| 467 | } | ||
| 468 | |||
| 469 | _memory->WriteArray<int>(id, REFLECTION_DATA, reflectionData); | ||
| 466 | } | 470 | } |
| 467 | 471 | ||
| 468 | std::tuple<int, int> PuzzleSerializer::loc_to_xy(const Puzzle& p, int location) const { | 472 | std::tuple<int, int> PuzzleSerializer::loc_to_xy(const Puzzle& p, int location) const { |
| @@ -484,12 +488,10 @@ int PuzzleSerializer::xy_to_loc(const Puzzle& p, int x, int y) const { | |||
| 484 | return rowsFromBottom * width2 + x/2; | 488 | return rowsFromBottom * width2 + x/2; |
| 485 | } | 489 | } |
| 486 | 490 | ||
| 487 | int PuzzleSerializer::extra_xy_to_loc(Pos pos) const { | 491 | int PuzzleSerializer::extra_xy_to_loc(const Puzzle& p, int x, int y) const { |
| 488 | for (auto [x, y, location] : _extraLocations) { | 492 | auto search = _extraLocations.find(x * p.height + y); |
| 489 | if (pos.x == x && pos.y == y) return location; | 493 | if (search == _extraLocations.end()) return -1; // @Error |
| 490 | } | 494 | return search->second; |
| 491 | |||
| 492 | return -1; // @Error | ||
| 493 | } | 495 | } |
| 494 | 496 | ||
| 495 | std::tuple<int, int> PuzzleSerializer::dloc_to_xy(const Puzzle& p, int location) const { | 497 | std::tuple<int, int> PuzzleSerializer::dloc_to_xy(const Puzzle& p, int location) const { |
| @@ -532,8 +534,8 @@ int PuzzleSerializer::FindConnection(int location) const { | |||
| 532 | return -1; | 534 | return -1; |
| 533 | } | 535 | } |
| 534 | 536 | ||
| 535 | void PuzzleSerializer::AddIntersection(int x, int y, float xPos, float yPos, int flags) { | 537 | void PuzzleSerializer::AddIntersection(const Puzzle& p, int x, int y, float xPos, float yPos, int flags) { |
| 536 | _extraLocations.emplace_back(x, y, static_cast<int>(_intersectionFlags.size())); | 538 | _extraLocations[x * p.height + y] = static_cast<int>(_intersectionFlags.size()); |
| 537 | _intersectionLocations.push_back(xPos); | 539 | _intersectionLocations.push_back(xPos); |
| 538 | _intersectionLocations.push_back(yPos); | 540 | _intersectionLocations.push_back(yPos); |
| 539 | _intersectionFlags.push_back(flags); | 541 | _intersectionFlags.push_back(flags); |
| diff --git a/Source/PuzzleSerializer.h b/Source/PuzzleSerializer.h index 3c8f480..4d254d8 100644 --- a/Source/PuzzleSerializer.h +++ b/Source/PuzzleSerializer.h | |||
| @@ -43,7 +43,7 @@ private: | |||
| 43 | 43 | ||
| 44 | std::tuple<int, int> loc_to_xy(const Puzzle& p, int location) const; | 44 | std::tuple<int, int> loc_to_xy(const Puzzle& p, int location) const; |
| 45 | int xy_to_loc(const Puzzle& p, int x, int y) const; | 45 | int xy_to_loc(const Puzzle& p, int x, int y) const; |
| 46 | int extra_xy_to_loc(Pos pos) const; | 46 | int extra_xy_to_loc(const Puzzle& p, int x, int y) const; |
| 47 | // Decoration location | 47 | // Decoration location |
| 48 | std::tuple<int, int> dloc_to_xy(const Puzzle& p, int location) const; | 48 | std::tuple<int, int> dloc_to_xy(const Puzzle& p, int location) const; |
| 49 | int xy_to_dloc(const Puzzle& p, int x, int y) const; | 49 | int xy_to_dloc(const Puzzle& p, int x, int y) const; |
| @@ -52,17 +52,18 @@ private: | |||
| 52 | Cell::Dot FlagsToDot(int flags) const; | 52 | Cell::Dot FlagsToDot(int flags) const; |
| 53 | // Iterate connection lists for another location which is connected to us; return that other location. | 53 | // Iterate connection lists for another location which is connected to us; return that other location. |
| 54 | int FindConnection(int location) const; | 54 | int FindConnection(int location) const; |
| 55 | void AddIntersection(int x, int y, float xPos, float yPos, int flags); | 55 | void AddIntersection(const Puzzle& p, int x, int y, float xPos, float yPos, int flags); |
| 56 | 56 | ||
| 57 | std::shared_ptr<Memory> _memory; | 57 | std::shared_ptr<Memory> _memory; |
| 58 | 58 | ||
| 59 | std::vector<float> _intersectionLocations; | 59 | int _numGridLocations; |
| 60 | int _numIntersections; | 60 | int _numIntersections; |
| 61 | std::vector<int> _intersectionFlags; | 61 | std::vector<int> _intersectionFlags; |
| 62 | std::vector<int> _connectionsA; | 62 | std::vector<int> _connectionsA; |
| 63 | std::vector<int> _connectionsB; | 63 | std::vector<int> _connectionsB; |
| 64 | std::vector<float> _intersectionLocations; | ||
| 64 | // Locations of non-grid points, i.e. dots, gaps, and endpoints | 65 | // Locations of non-grid points, i.e. dots, gaps, and endpoints |
| 65 | std::vector<std::tuple<int, int, int>> _extraLocations; | 66 | std::unordered_map<int, int> _extraLocations; |
| 66 | 67 | ||
| 67 | float MIN, MAX, WIDTH_INTERVAL, HEIGHT_INTERVAL, HORIZ_GAP_SIZE, VERTI_GAP_SIZE; | 68 | float MIN, MAX, WIDTH_INTERVAL, HEIGHT_INTERVAL, INTERVAL, GAP_SIZE; |
| 68 | }; | 69 | }; |
