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 | |
| parent | 6f0a34bfb761d965bd961dc1f880b84e35f9959f (diff) | |
| download | witness-tutorializer-d5bce3bba23a5ba4c296f1783ba277bcc206736c.tar.gz witness-tutorializer-d5bce3bba23a5ba4c296f1783ba277bcc206736c.tar.bz2 witness-tutorializer-d5bce3bba23a5ba4c296f1783ba277bcc206736c.zip | |
Some progress on symmetry.
| -rw-r--r-- | App/Main.cpp | 2 | ||||
| -rw-r--r-- | Source/Puzzle.cpp | 19 | ||||
| -rw-r--r-- | Source/Puzzle.h | 11 | ||||
| -rw-r--r-- | Source/PuzzleSerializer.cpp | 58 |
4 files changed, 66 insertions, 24 deletions
| diff --git a/App/Main.cpp b/App/Main.cpp index 55074ed..8df3e6e 100644 --- a/App/Main.cpp +++ b/App/Main.cpp | |||
| @@ -268,7 +268,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance | |||
| 268 | // WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT, | 268 | // WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT, |
| 269 | // 200, 80, 200, 200, g_hwnd, NULL, g_hInstance, NULL); | 269 | // 200, 80, 200, 200, g_hwnd, NULL, g_hInstance, NULL); |
| 270 | 270 | ||
| 271 | g_panelId = CreateText(200, 100, 100, L"86"); | 271 | g_panelId = CreateText(200, 100, 100, L"59"); |
| 272 | CreateButton(200, 130, 100, L"Read", TMP1); | 272 | CreateButton(200, 130, 100, L"Read", TMP1); |
| 273 | CreateButton(200, 160, 100, L"Write", TMP2); | 273 | CreateButton(200, 160, 100, L"Write", TMP2); |
| 274 | CreateButton(200, 190, 100, L"Solve", TMP3); | 274 | CreateButton(200, 190, 100, L"Solve", TMP3); |
| diff --git a/Source/Puzzle.cpp b/Source/Puzzle.cpp index d0ede27..2f399a7 100644 --- a/Source/Puzzle.cpp +++ b/Source/Puzzle.cpp | |||
| @@ -27,6 +27,25 @@ void Puzzle::NewGrid(int newWidth, int newHeight) { | |||
| 27 | for (int x=0; x<width; x++) grid[x].resize(height); | 27 | for (int x=0; x<width; x++) grid[x].resize(height); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | Pos Puzzle::GetSymmetricalPos(int x, int y) const { | ||
| 31 | if (symmetry != Symmetry::NONE) { | ||
| 32 | if (pillar) { | ||
| 33 | x += width/2; | ||
| 34 | if (symmetry & Symmetry::X) { | ||
| 35 | x = width - x; | ||
| 36 | } | ||
| 37 | } else { | ||
| 38 | if (symmetry & Symmetry::X) { | ||
| 39 | x = (width-1) - x; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | if (symmetry & Symmetry::Y) { | ||
| 43 | y = (height-1) - y; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | return Pos{x, y}; | ||
| 47 | } | ||
| 48 | |||
| 30 | int Puzzle::Mod(int x) const { | 49 | int Puzzle::Mod(int x) const { |
| 31 | if (!pillar) return x; | 50 | if (!pillar) return x; |
| 32 | return (x + width * height * 2) % width; | 51 | return (x + width * height * 2) % width; |
| diff --git a/Source/Puzzle.h b/Source/Puzzle.h index ac604f1..8afb9ca 100644 --- a/Source/Puzzle.h +++ b/Source/Puzzle.h | |||
| @@ -74,7 +74,12 @@ public: | |||
| 74 | int width = 0; | 74 | int width = 0; |
| 75 | bool hasDecorations = false; | 75 | bool hasDecorations = false; |
| 76 | 76 | ||
| 77 | enum class Symmetry {NONE, X, Y, XY}; | 77 | enum Symmetry { |
| 78 | NONE = 0, | ||
| 79 | X = 1, | ||
| 80 | Y = 2, | ||
| 81 | XY = 3 | ||
| 82 | }; | ||
| 78 | Symmetry symmetry = Symmetry::NONE; | 83 | Symmetry symmetry = Symmetry::NONE; |
| 79 | bool pillar = false; | 84 | bool pillar = false; |
| 80 | 85 | ||
| @@ -87,9 +92,7 @@ public: | |||
| 87 | Cell GetCell(int x, int y) const; | 92 | Cell GetCell(int x, int y) const; |
| 88 | Cell::Color GetLine(int x, int y) const; | 93 | Cell::Color GetLine(int x, int y) const; |
| 89 | void NewGrid(int newWidth, int newHeight); | 94 | void NewGrid(int newWidth, int newHeight); |
| 90 | 95 | Pos GetSymmetricalPos(int x, int y) const; | |
| 91 | // @TODO: | ||
| 92 | Pos GetSymmetricalPos(int x, int y); | ||
| 93 | 96 | ||
| 94 | // private: | 97 | // private: |
| 95 | std::vector<std::vector<Cell>> grid; | 98 | std::vector<std::vector<Cell>> grid; |
| 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 | ||
