summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorjbzdarkid <jbzdarkid@gmail.com>2019-11-20 20:30:25 -0800
committerjbzdarkid <jbzdarkid@gmail.com>2019-11-20 20:30:25 -0800
commitd5bce3bba23a5ba4c296f1783ba277bcc206736c (patch)
tree64835daf9aeb54fa779e06426a777861d68195e4
parent6f0a34bfb761d965bd961dc1f880b84e35f9959f (diff)
downloadwitness-tutorializer-d5bce3bba23a5ba4c296f1783ba277bcc206736c.tar.gz
witness-tutorializer-d5bce3bba23a5ba4c296f1783ba277bcc206736c.tar.bz2
witness-tutorializer-d5bce3bba23a5ba4c296f1783ba277bcc206736c.zip
Some progress on symmetry.
-rw-r--r--App/Main.cpp2
-rw-r--r--Source/Puzzle.cpp19
-rw-r--r--Source/Puzzle.h11
-rw-r--r--Source/PuzzleSerializer.cpp58
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
30Pos 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
30int Puzzle::Mod(int x) const { 49int 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 @@
8PuzzleSerializer::PuzzleSerializer(const std::shared_ptr<Memory>& memory) : _memory(memory) {} 8PuzzleSerializer::PuzzleSerializer(const std::shared_ptr<Memory>& memory) : _memory(memory) {}
9 9
10Puzzle PuzzleSerializer::ReadPuzzle(int id) { 10Puzzle 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
262void PuzzleSerializer::WriteEndpoints(const Puzzle& p) { 263void 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
450std::tuple<int, int> PuzzleSerializer::loc_to_xy(const Puzzle& p, int location) const { 468std::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
459int PuzzleSerializer::xy_to_loc(const Puzzle& p, int x, int y) const { 477int 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