summary refs log tree commit diff stats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/Puzzle.cpp12
-rw-r--r--Source/Puzzle.h28
-rw-r--r--Source/Randomizer2.cpp104
-rw-r--r--Source/Randomizer2.h12
-rw-r--r--Source/Solver.h2
-rw-r--r--Source/Source.vcxproj2
-rw-r--r--Source/Validator.h2
7 files changed, 147 insertions, 15 deletions
diff --git a/Source/Puzzle.cpp b/Source/Puzzle.cpp index ee4c2e8..cc552d3 100644 --- a/Source/Puzzle.cpp +++ b/Source/Puzzle.cpp
@@ -7,16 +7,14 @@
7PuzzleSerializer::PuzzleSerializer(const std::shared_ptr<Memory>& memory) : _memory(memory) {} 7PuzzleSerializer::PuzzleSerializer(const std::shared_ptr<Memory>& memory) : _memory(memory) {}
8 8
9Puzzle PuzzleSerializer::ReadPuzzle(int id) { 9Puzzle PuzzleSerializer::ReadPuzzle(int id) {
10 Puzzle p; 10 int width = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_X, 1)[0] - 1;
11 p.width = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_X, 1)[0] - 1; 11 int height = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_Y, 1)[0] - 1;
12 p.height = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_Y, 1)[0] - 1; 12 if (width < 0 || height < 0) return Puzzle(); // @Error: Grid size should be always positive? Looks like the starting panels break this rule, though.
13 if (p.width < 0 || p.height < 0) return p; // @Error: Grid size should be always positive? Looks like the starting panels break this rule, though.
14 p.grid.resize(p.width);
15 for (auto& row : p.grid) row.resize(p.height);
16 13
14 Puzzle p;
15 p.NewGrid(width, height);
17 ReadIntersections(p, id); 16 ReadIntersections(p, id);
18 ReadDecorations(p, id); 17 ReadDecorations(p, id);
19
20 return p; 18 return p;
21} 19}
22 20
diff --git a/Source/Puzzle.h b/Source/Puzzle.h index 7a98a78..94cb4b0 100644 --- a/Source/Puzzle.h +++ b/Source/Puzzle.h
@@ -37,7 +37,6 @@ struct Decoration {
37 int count = 0; 37 int count = 0;
38}; 38};
39 39
40
41struct Cell { 40struct Cell {
42 inline static Cell Undefined() { 41 inline static Cell Undefined() {
43 Cell c; 42 Cell c;
@@ -63,7 +62,9 @@ struct Cell {
63struct Negation {}; 62struct Negation {};
64struct Pos {int x; int y;}; 63struct Pos {int x; int y;};
65 64
66struct Puzzle { 65#include <cassert> // TODO: Move this + impl to cpp
66class Puzzle {
67public:
67 int16_t height; 68 int16_t height;
68 int16_t width; 69 int16_t width;
69 bool hasDecorations = false; 70 bool hasDecorations = false;
@@ -72,6 +73,10 @@ struct Puzzle {
72 Symmetry sym = Symmetry::NONE; 73 Symmetry sym = Symmetry::NONE;
73 bool pillar = false; 74 bool pillar = false;
74 75
76 bool valid;
77 std::vector<Negation> negations;
78 std::vector<Pos> invalidElements;
79
75 inline Cell GetCell(int x, int y) const { 80 inline Cell GetCell(int x, int y) const {
76 x = Mod(x); 81 x = Mod(x);
77 if (!SafeCell(x, y)) return Cell::Undefined(); 82 if (!SafeCell(x, y)) return Cell::Undefined();
@@ -80,13 +85,24 @@ struct Puzzle {
80 inline Cell::Color GetLine(int x, int y) const { 85 inline Cell::Color GetLine(int x, int y) const {
81 return grid[x][y].color; 86 return grid[x][y].color;
82 } 87 }
88 inline void NewGrid(int newWidth, int newHeight) {
89 if (newWidth == 0) {
90 assert(false);
91 newWidth = width;
92 newHeight = height;
93 } else {
94 // @Cleanup! This should be in the ctor...
95 width = 2*newWidth + 1;
96 height = 2*newHeight + 1;
97 }
98 grid.clear();
99 grid.resize(width);
100 for (int x=0; x<width; x++) grid[x].resize(height);
101 }
102
83 // @TODO: 103 // @TODO:
84 Pos GetSymmetricalPos(int x, int y); 104 Pos GetSymmetricalPos(int x, int y);
85 105
86 bool valid;
87 std::vector<Negation> negations;
88 std::vector<Pos> invalidElements;
89
90// private: 106// private:
91 std::vector<std::vector<Cell>> grid; 107 std::vector<std::vector<Cell>> grid;
92 108
diff --git a/Source/Randomizer2.cpp b/Source/Randomizer2.cpp new file mode 100644 index 0000000..fcfec9a --- /dev/null +++ b/Source/Randomizer2.cpp
@@ -0,0 +1,104 @@
1#include "Randomizer2.h"
2#include "Puzzle.h"
3#include "Random.h"
4#include "Solver.h"
5
6Randomizer2::Randomizer2(const std::shared_ptr<Memory>& memory) : _memory(memory) {}
7
8void Randomizer2::Randomize() {
9 // 4x4
10 // 14 gaps
11 // start (x=0, y=8)
12 // end (x=8, y=0) Up
13 // 1 solution
14 Puzzle p;
15 int attemptCount = 0;
16 while (true) {
17 attemptCount++;
18 p.NewGrid(4, 4);
19
20 std::vector<Pos> corners;
21 std::vector<Pos> cells;
22 std::vector<Pos> edges;
23 for (int x=0; x<p.width; x++) {
24 for (int y=0; y<p.height; y++) {
25 if (x%2 == 0 && y%2 == 0) corners.emplace_back(Pos{x, y});
26 else if (x%2 == 1 && y%2 == 1) cells.emplace_back(Pos{x, y});
27 else edges.emplace_back(Pos{x, y});
28 }
29 }
30
31 for (int i=0; i<14; i++) {
32 int edge = Random::RandInt(0, static_cast<int>(edges.size() - 1));
33 Pos pos = edges[edge];
34 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
35 edges.erase(edges.begin() + edge);
36 }
37
38 p.grid[0][8].start = true;
39 p.grid[8][0].end = Cell::Dir::UP;
40
41 auto solutions = Solver::Solve(p);
42 if (solutions.size() == 1) {
43 auto solution = solutions[0];
44 int solutionLength = 0;
45 for (int x=0; x<solution.width; x++) {
46 for (int y=0; y<solution.height; y++) {
47 if (solution.grid[x][y].color == Cell::Color::BLACK) solutionLength++;
48 }
49 }
50 if (solutionLength == 25) break;
51 }
52 }
53 PuzzleSerializer(_memory).WritePuzzle(p, 0x293);
54
55
56
57
58 // 7x7
59 // 35 gaps
60 // start (x=8, y=8)
61 // end (x=4, y=0) Up
62 // 2 solutions, 37 & 39
63 attemptCount = 0;
64 while (true) {
65 attemptCount++;
66 p.NewGrid(7, 7);
67
68 std::vector<Pos> corners;
69 std::vector<Pos> cells;
70 std::vector<Pos> edges;
71 for (int x=0; x<p.width; x++) {
72 for (int y=0; y<p.height; y++) {
73 if (x%2 == 0 && y%2 == 0) corners.emplace_back(Pos{x, y});
74 else if (x%2 == 1 && y%2 == 1) cells.emplace_back(Pos{x, y});
75 else edges.emplace_back(Pos{x, y});
76 }
77 }
78
79 for (int i=0; i<35; i++) {
80 int edge = Random::RandInt(0, static_cast<int>(edges.size() - 1));
81 Pos pos = edges[edge];
82 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
83 edges.erase(edges.begin() + edge);
84 }
85
86 p.grid[8][8].start = true;
87 p.grid[4][0].end = Cell::Dir::UP;
88
89 auto solutions = Solver::Solve(p);
90 if (solutions.size() > 0) break;
91 if (solutions.size() > 0 && solutions.size() < 5) {
92 auto solution = solutions[0];
93 int solutionLength = 0;
94 for (int x=0; x<solution.width; x++) {
95 for (int y=0; y<solution.height; y++) {
96 if (solution.grid[x][y].color == Cell::Color::BLACK) solutionLength++;
97 }
98 }
99 if (solutionLength > 30 && solutionLength < 40) break;
100 }
101 }
102 PuzzleSerializer(_memory).WritePuzzle(p, 0x295);
103
104}
diff --git a/Source/Randomizer2.h b/Source/Randomizer2.h new file mode 100644 index 0000000..1aeae11 --- /dev/null +++ b/Source/Randomizer2.h
@@ -0,0 +1,12 @@
1#pragma once
2#include <memory>
3
4class Memory;
5class Randomizer2 {
6public:
7 Randomizer2(const std::shared_ptr<Memory>& memory);
8 void Randomize();
9
10private:
11 std::shared_ptr<Memory> _memory;
12};
diff --git a/Source/Solver.h b/Source/Solver.h index 8a021ac..09108c7 100644 --- a/Source/Solver.h +++ b/Source/Solver.h
@@ -5,7 +5,7 @@
5#define MAX_SOLUTIONS 10000 5#define MAX_SOLUTIONS 10000
6#endif 6#endif
7 7
8struct Puzzle; 8class Puzzle;
9class Solver { 9class Solver {
10public: 10public:
11 static std::vector<Puzzle> Solve(Puzzle& p); 11 static std::vector<Puzzle> Solve(Puzzle& p);
diff --git a/Source/Source.vcxproj b/Source/Source.vcxproj index 92aa9d7..aebeaeb 100644 --- a/Source/Source.vcxproj +++ b/Source/Source.vcxproj
@@ -163,6 +163,7 @@
163 <ClInclude Include="Panels.h" /> 163 <ClInclude Include="Panels.h" />
164 <ClInclude Include="Random.h" /> 164 <ClInclude Include="Random.h" />
165 <ClInclude Include="Randomizer.h" /> 165 <ClInclude Include="Randomizer.h" />
166 <ClInclude Include="Randomizer2.h" />
166 <ClInclude Include="Solver.h" /> 167 <ClInclude Include="Solver.h" />
167 <ClInclude Include="Validator.h" /> 168 <ClInclude Include="Validator.h" />
168 </ItemGroup> 169 </ItemGroup>
@@ -172,6 +173,7 @@
172 <ClCompile Include="Puzzle.cpp" /> 173 <ClCompile Include="Puzzle.cpp" />
173 <ClCompile Include="Random.cpp" /> 174 <ClCompile Include="Random.cpp" />
174 <ClCompile Include="Randomizer.cpp" /> 175 <ClCompile Include="Randomizer.cpp" />
176 <ClCompile Include="Randomizer2.cpp" />
175 <ClCompile Include="Solver.cpp" /> 177 <ClCompile Include="Solver.cpp" />
176 <ClCompile Include="Validator.cpp" /> 178 <ClCompile Include="Validator.cpp" />
177 </ItemGroup> 179 </ItemGroup>
diff --git a/Source/Validator.h b/Source/Validator.h index cddc293..2a102dd 100644 --- a/Source/Validator.h +++ b/Source/Validator.h
@@ -15,7 +15,7 @@
15#endif 15#endif
16 16
17struct Region{}; 17struct Region{};
18struct Puzzle; 18class Puzzle;
19struct Pos; 19struct Pos;
20class Validator { 20class Validator {
21public: 21public: