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