summary refs log tree commit diff stats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/PuzzleSerializer.cpp (renamed from Source/PuzzlerSerializer.cpp)2
-rw-r--r--Source/PuzzleSerializer.h (renamed from Source/PuzzlerSerializer.h)0
-rw-r--r--Source/Randomizer2.cpp197
-rw-r--r--Source/Randomizer2.h4
-rw-r--r--Source/Randomizer2Core.cpp29
-rw-r--r--Source/Randomizer2Core.h7
-rw-r--r--Source/Source.vcxproj4
7 files changed, 81 insertions, 162 deletions
diff --git a/Source/PuzzlerSerializer.cpp b/Source/PuzzleSerializer.cpp index 2ba0ce7..c1e93a5 100644 --- a/Source/PuzzlerSerializer.cpp +++ b/Source/PuzzleSerializer.cpp
@@ -1,4 +1,4 @@
1#include "PuzzlerSerializer.h" 1#include "PuzzleSerializer.h"
2#include "Memory.h" 2#include "Memory.h"
3 3
4#pragma warning (disable:26451) 4#pragma warning (disable:26451)
diff --git a/Source/PuzzlerSerializer.h b/Source/PuzzleSerializer.h index d9b9edd..d9b9edd 100644 --- a/Source/PuzzlerSerializer.h +++ b/Source/PuzzleSerializer.h
diff --git a/Source/Randomizer2.cpp b/Source/Randomizer2.cpp index d9c00c0..7a50c7b 100644 --- a/Source/Randomizer2.cpp +++ b/Source/Randomizer2.cpp
@@ -1,128 +1,39 @@
1#include "Memory.h"
1#include "Randomizer2.h" 2#include "Randomizer2.h"
3#include "Randomizer2Core.h"
2#include "Puzzle.h" 4#include "Puzzle.h"
3#include "Random.h" 5#include "Random.h"
4#include "Solver.h" 6#include "Solver.h"
5#include "Memory.h" 7
6#include "Randomizer2Core.h"
7#include "PuzzlerSerializer.h"
8#include <cassert> 8#include <cassert>
9#include <string> 9#include <string>
10 10
11void FloodFillInternal(const Puzzle& p, std::vector<std::vector<bool>>& reached, int x, int y) { 11#pragma warning (disable: 26451)
12 if (x%2 == 1 && y%2 == 1) return;
13 auto cell = p.GetCell(x, y);
14 if (cell.undefined) return;
15 if (cell.gap != Cell::Gap::NONE) return;
16 if (reached[x][y]) return;
17 12
18 reached[x][y] = true; 13Randomizer2::Randomizer2(const std::shared_ptr<Memory>& memory) : _memory(memory), _serializer(PuzzleSerializer(_memory)) {}
19 FloodFillInternal(p, reached, x-1, y);
20 FloodFillInternal(p, reached, x+1, y);
21 FloodFillInternal(p, reached, x, y-1);
22 FloodFillInternal(p, reached, x, y+1);
23}
24 14
25// Returns true: All nodes reachable / false: Some node disconnected 15void Randomizer2::Randomize() {
26bool FloodFill(const Puzzle& p) { 16 RandomizeTutorial();
27 std::vector<std::vector<bool>> reached; 17 RandomizeKeep();
28 reached.resize(p.width);
29 for (int x=0; x<p.width; x++) reached[x].resize(p.height);
30 FloodFillInternal(p, reached, 0, 0);
31
32 for (int x=0; x<p.width; x++) {
33 for (int y=0; y<p.height; y++) {
34 if (x%2 == 0 && y%2 == 0) { // @Specialized
35 if (!reached[x][y]) return false;
36 }
37 }
38 }
39 return true;
40} 18}
41 19
42Randomizer2::Randomizer2(const std::shared_ptr<Memory>& memory) : _memory(memory) {} 20void Randomizer2::RandomizeTutorial() {
43 21 { // Far center
44void Randomizer2::Randomize() { 22 Puzzle p;
45 // 4x4
46 // 14 gaps
47 // start (x=0, y=8)
48 // end (x=8, y=0) Up
49 // 1 solution
50 Puzzle p;
51 while (true) {
52 p.NewGrid(4, 4); 23 p.NewGrid(4, 4);
53
54 std::vector<Pos> corners;
55 std::vector<Pos> cells;
56 std::vector<Pos> edges;
57 for (int x=0; x<p.width; x++) {
58 for (int y=0; y<p.height; y++) {
59 if (x%2 == 0 && y%2 == 0) corners.emplace_back(Pos{x, y});
60 else if (x%2 == 1 && y%2 == 1) cells.emplace_back(Pos{x, y});
61 else edges.emplace_back(Pos{x, y});
62 }
63 }
64
65 for (int i=0; i<14; i++) {
66 for (int j=0; j<edges.size(); j++) {
67 int edge = Random::RandInt(0, static_cast<int>(edges.size() - 1));
68 Pos pos = edges[edge];
69 edges.erase(edges.begin() + edge);
70
71 if (FloodFill(p)) {
72 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
73 break;
74 } else {
75 p.grid[pos.x][pos.y].gap = Cell::Gap::NONE;
76 }
77 }
78 }
79
80 p.grid[0][8].start = true; 24 p.grid[0][8].start = true;
81 p.grid[8][0].end = Cell::Dir::UP; 25 p.grid[8][0].end = Cell::Dir::UP;
82 26
83 auto solutions = Solver::Solve(p); 27 for (Pos pos : Randomizer2Core::CutEdges(p, 14)) {
84 if (solutions.size() > 0) break; 28 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
29 }
30 _serializer.WritePuzzle(p, 0x293);
85 } 31 }
86 PuzzleSerializer(_memory).WritePuzzle(p, 0x293);
87 32
88 // 7x7 33 {
89 // 35 gaps 34 Puzzle p;
90 // start (x=8, y=8)
91 // end (x=4, y=0) Up
92 // 2 solutions, 37 & 39
93 while (true) {
94 p.NewGrid(7, 7); 35 p.NewGrid(7, 7);
95 36
96 std::vector<Pos> corners;
97 std::vector<Pos> cells;
98 std::vector<Pos> edges;
99 for (int x=0; x<p.width; x++) {
100 for (int y=0; y<p.height; y++) {
101 if (x%2 == 0 && y%2 == 0) corners.emplace_back(Pos{x, y});
102 else if (x%2 == 1 && y%2 == 1) cells.emplace_back(Pos{x, y});
103 else edges.emplace_back(Pos{x, y});
104 }
105 }
106
107 for (int i=0; i<35; i++) {
108 for (int j=0; j<edges.size(); j++) {
109 // TODO: Precompute edge weights and make a weighted cut.
110 // This will also preclude the need for flood filling.
111 // https://en.wikipedia.org/wiki/Biconnected_component
112
113 int edge = Random::RandInt(0, static_cast<int>(edges.size() - 1));
114 Pos pos = edges[edge];
115 edges.erase(edges.begin() + edge);
116
117 if (FloodFill(p)) {
118 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
119 break;
120 } else {
121 p.grid[pos.x][pos.y].gap = Cell::Gap::NONE;
122 }
123 }
124 }
125
126 switch (Random::RandInt(1, 4)) { 37 switch (Random::RandInt(1, 4)) {
127 case 1: 38 case 1:
128 p.grid[Random::RandInt(0, p.width-1)][0].end = Cell::Dir::UP; 39 p.grid[Random::RandInt(0, p.width-1)][0].end = Cell::Dir::UP;
@@ -148,17 +59,17 @@ void Randomizer2::Randomize() {
148 p.grid[Random::RandInt(0, 2)*2 + 4][Random::RandInt(0, 2)*2 + 4].start = true; 59 p.grid[Random::RandInt(0, 2)*2 + 4][Random::RandInt(0, 2)*2 + 4].start = true;
149 break; 60 break;
150 } 61 }
62
63 for (Pos pos : Randomizer2Core::CutEdges(p, 35)) {
64 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
65 }
151 66
152 auto solutions = Solver::Solve(p); 67 _serializer.WritePuzzle(p, 0x295);
153 if (solutions.size() > 0) break;
154 } 68 }
155 PuzzleSerializer(_memory).WritePuzzle(p, 0x295);
156
157} 69}
158 70
159void Randomizer2::RandomizeKeep() { 71void Randomizer2::RandomizeKeep() {
160 // *** Hedges 1 *** 72 { // Hedges 1
161 {
162 Puzzle p; 73 Puzzle p;
163 p.NewGrid(4, 4); 74 p.NewGrid(4, 4);
164 75
@@ -177,8 +88,7 @@ void Randomizer2::RandomizeKeep() {
177 p.grid[4][8].start = true; 88 p.grid[4][8].start = true;
178 p.grid[6][0].end = Cell::Dir::UP; 89 p.grid[6][0].end = Cell::Dir::UP;
179 90
180 std::vector<Pos> cutEdges = Randomizer2Core::CutEdgesToBeUnique(p); 91 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges2(p, 5);
181 assert(cutEdges.size() == 5);
182 Puzzle copy = p; 92 Puzzle copy = p;
183 std::vector<int> gates = {0x00344, 0x00488, 0x00489, 0x00495, 0x00496}; 93 std::vector<int> gates = {0x00344, 0x00488, 0x00489, 0x00495, 0x00496};
184 for (int i=0; i<gates.size(); i++) { 94 for (int i=0; i<gates.size(); i++) {
@@ -186,14 +96,12 @@ void Randomizer2::RandomizeKeep() {
186 copy.grid[pos.x][pos.y].gap = Cell::Gap::BREAK; 96 copy.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
187 SetGate(gates[i], pos.x, pos.y); 97 SetGate(gates[i], pos.x, pos.y);
188 } 98 }
189 auto solutions = Solver::Solve(copy); 99 auto solution = GetUniqueSolution(copy);
190 assert(solutions.size() == 1); 100 p.sequence = solution.sequence;
191 p.sequence = solutions[0].sequence; 101 _serializer.WritePuzzle(p, 0x139);
192 PuzzleSerializer(_memory).WritePuzzle(solutions[0], 0x139);
193 } 102 }
194 103
195 // *** Hedges 2 *** 104 { // Hedges 2
196 {
197 Puzzle p; 105 Puzzle p;
198 p.NewGrid(4, 4); 106 p.NewGrid(4, 4);
199 107
@@ -210,29 +118,28 @@ void Randomizer2::RandomizeKeep() {
210 p.grid[0][8].start = true; 118 p.grid[0][8].start = true;
211 p.grid[8][0].end = Cell::Dir::RIGHT; 119 p.grid[8][0].end = Cell::Dir::RIGHT;
212 120
213 std::vector<Pos> cutEdges = Randomizer2Core::CutEdgesToBeUnique(p); 121 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges2(p, 7);
214 assert(cutEdges.size() == 7);
215 for (Pos pos : cutEdges) { 122 for (Pos pos : cutEdges) {
216 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 123 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
217 } 124 }
218 auto solutions = Solver::Solve(p); 125 auto solution = GetUniqueSolution(p);
219 assert(solutions.size() == 1);
220 126
221 Puzzle q; 127 Puzzle q;
222 q.NewGrid(4, 4); 128 q.NewGrid(4, 4);
223 q.grid[0][8].start = true; 129 q.grid[0][8].start = true;
224 q.grid[8][0].end = Cell::Dir::RIGHT; 130 q.grid[8][0].end = Cell::Dir::RIGHT;
225 q.sequence = solutions[0].sequence; 131 q.sequence = solution.sequence;
226 for (Pos pos : cutEdges) { 132 for (Pos pos : cutEdges) {
227 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 133 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
228 } 134 }
229 // Cut to 4 of 9 additional edges (total: 11) 135 // Cut to 6 of 9 additional edges
230 Randomizer2Core::CutEdgesNotOutsideNotBreakingSequence(q, 4); 136 for (Pos pos : Randomizer2Core::CutEdges2(q, 6)) {
231 PuzzleSerializer(_memory).WritePuzzle(q, 0x19DC); 137 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
138 }
139 _serializer.WritePuzzle(q, 0x19DC);
232 } 140 }
233 141
234 // *** Hedges 3 ** 142 { // Hedges 3 [WIP]
235 {
236 Puzzle p; 143 Puzzle p;
237 p.NewGrid(4, 4); 144 p.NewGrid(4, 4);
238 145
@@ -251,17 +158,14 @@ void Randomizer2::RandomizeKeep() {
251 158
252 std::vector<int> pebbleMarkers = {0x034a9, 0x034b1, 0x034be, 0x034c4}; 159 std::vector<int> pebbleMarkers = {0x034a9, 0x034b1, 0x034be, 0x034c4};
253 160
254 161 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges2(p, 7);
255 std::vector<Pos> cutEdges = Randomizer2Core::CutEdgesToBeUnique(p);
256 assert(cutEdges.size() == 7);
257 for (Pos pos : cutEdges) { 162 for (Pos pos : cutEdges) {
258 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK; 163 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
259 } 164 }
260 PuzzleSerializer(_memory).WritePuzzle(p, 0x19E7); 165 // _serializer.WritePuzzle(p, 0x19E7);
261 } 166 }
262 167
263 // *** Hedges 4 *** 168 { // Hedges 4
264 {
265 Puzzle p; 169 Puzzle p;
266 p.NewGrid(4, 4); 170 p.NewGrid(4, 4);
267 171
@@ -283,28 +187,33 @@ void Randomizer2::RandomizeKeep() {
283 p.grid[0][8].start = true; 187 p.grid[0][8].start = true;
284 p.grid[4][0].end = Cell::Dir::UP; 188 p.grid[4][0].end = Cell::Dir::UP;
285 189
286 std::vector<Pos> cutEdges = Randomizer2Core::CutEdgesToBeUnique(p); 190 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges2(p, 2);
287 assert(cutEdges.size() == 2);
288 for (Pos pos : cutEdges) { 191 for (Pos pos : cutEdges) {
289 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 192 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
290 } 193 }
291 auto solutions = Solver::Solve(p); 194 auto solution = GetUniqueSolution(p);
292 assert(solutions.size() == 1);
293 195
294 Puzzle q; 196 Puzzle q;
295 q.NewGrid(4, 4); 197 q.NewGrid(4, 4);
296 q.grid[0][8].start = true; 198 q.grid[0][8].start = true;
297 q.grid[4][0].end = Cell::Dir::UP; 199 q.grid[4][0].end = Cell::Dir::UP;
298 q.sequence = solutions[0].sequence; 200 q.sequence = solution.sequence;
299 for (Pos pos : cutEdges) { 201 for (Pos pos : cutEdges) {
300 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 202 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
301 } 203 }
302 // 9 cuts, -2 from existing cuts 204 for (Pos pos : Randomizer2Core::CutEdges2(q, 7)) {
303 Randomizer2Core::CutEdgesNotOutsideNotBreakingSequence(q, 7); 205 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
304 PuzzleSerializer(_memory).WritePuzzle(q, 0x1A0F); 206 }
207 _serializer.WritePuzzle(q, 0x1A0F);
305 } 208 }
306} 209}
307 210
211Puzzle Randomizer2::GetUniqueSolution(Puzzle& p) {
212 auto solutions = Solver::Solve(p);
213 assert(solutions.size() == 1);
214 return solutions[0];
215}
216
308void Randomizer2::SetGate(int panel, int X, int Y) { 217void Randomizer2::SetGate(int panel, int X, int Y) {
309 float x, y, z, w; 218 float x, y, z, w;
310 if (X%2 == 0 && Y%2 == 1) { // Horizontal 219 if (X%2 == 0 && Y%2 == 1) { // Horizontal
diff --git a/Source/Randomizer2.h b/Source/Randomizer2.h index 359e357..6e79694 100644 --- a/Source/Randomizer2.h +++ b/Source/Randomizer2.h
@@ -1,16 +1,20 @@
1#pragma once 1#pragma once
2#include <memory> 2#include <memory>
3#include "PuzzleSerializer.h"
3 4
4class Memory; 5class Memory;
5class Randomizer2 { 6class Randomizer2 {
6public: 7public:
7 Randomizer2(const std::shared_ptr<Memory>& memory); 8 Randomizer2(const std::shared_ptr<Memory>& memory);
8 void Randomize(); 9 void Randomize();
10 void RandomizeTutorial();
9 void RandomizeKeep(); 11 void RandomizeKeep();
10 12
11private: 13private:
14 Puzzle GetUniqueSolution(Puzzle& p);
12 void SetGate(int panel, int X, int Y); 15 void SetGate(int panel, int X, int Y);
13 void SetPos(int panel, float x, float y, float z); 16 void SetPos(int panel, float x, float y, float z);
14 17
15 std::shared_ptr<Memory> _memory; 18 std::shared_ptr<Memory> _memory;
19 PuzzleSerializer _serializer;
16}; 20};
diff --git a/Source/Randomizer2Core.cpp b/Source/Randomizer2Core.cpp index 2659076..8bd5765 100644 --- a/Source/Randomizer2Core.cpp +++ b/Source/Randomizer2Core.cpp
@@ -6,40 +6,46 @@
6#include <iostream> 6#include <iostream>
7#include <cassert> 7#include <cassert>
8 8
9std::vector<Pos> Randomizer2Core::CutEdgesToBeUnique(const Puzzle& p) { 9// @Cutnpaste
10 auto [colorGrid, numColors] = CreateColorGrid(p); 10std::vector<Pos> Randomizer2Core::CutEdges(const Puzzle& p, size_t numEdges) {
11 std::vector<Pos> edges; 11 std::vector<Pos> edges;
12 for (int x=0; x<p.width; x++) { 12 for (int x=0; x<p.width; x++) {
13 for (int y=0; y<p.height; y++) { 13 for (int y=0; y<p.height; y++) {
14 if (x%2 == y%2) continue; 14 if (x%2 == y%2) continue;
15 if (p.grid[x][y].gap != Cell::Gap::NONE) continue; 15 if (p.grid[x][y].gap != Cell::Gap::NONE) continue;
16
17 // If the puzzle already has a sequence, don't cut along it.
18 bool inSequence = false;
19 for (Pos pos : p.sequence) inSequence |= (pos.x == x && pos.y == y);
20 if (inSequence) continue;
16 edges.emplace_back(Pos{x, y}); 21 edges.emplace_back(Pos{x, y});
17 } 22 }
18 } 23 }
19 return CutEdgesInternal(p, colorGrid, edges, numColors); 24 return CutEdgesInternal(p, edges, numEdges);
20} 25}
21 26
22void Randomizer2Core::CutEdgesNotOutsideNotBreakingSequence(Puzzle& p, size_t numEdges) { 27std::vector<Pos> Randomizer2Core::CutEdges2(const Puzzle& p, size_t numEdges) {
23 auto [colorGrid, numColors] = CreateColorGrid(p);
24 assert(numEdges <= numColors);
25 std::vector<Pos> edges; 28 std::vector<Pos> edges;
29 // Note the iterator bounds; we skip the outer edges.
26 for (int x=1; x<p.width-1; x++) { 30 for (int x=1; x<p.width-1; x++) {
27 for (int y=1; y<p.height-1; y++) { 31 for (int y=1; y<p.height-1; y++) {
28 if (x%2 == y%2) continue; 32 if (x%2 == y%2) continue;
29 if (p.grid[x][y].gap != Cell::Gap::NONE) continue; 33 if (p.grid[x][y].gap != Cell::Gap::NONE) continue;
34
35 // If the puzzle already has a sequence, don't cut along it.
30 bool inSequence = false; 36 bool inSequence = false;
31 for (Pos pos : p.sequence) inSequence |= (pos.x == x && pos.y == y); 37 for (Pos pos : p.sequence) inSequence |= (pos.x == x && pos.y == y);
32 if (inSequence) continue; 38 if (inSequence) continue;
33 edges.emplace_back(Pos{x, y}); 39 edges.emplace_back(Pos{x, y});
34 } 40 }
35 } 41 }
36 std::vector<Pos> cutEdges = CutEdgesInternal(p, colorGrid, edges, numEdges); 42 return CutEdgesInternal(p, edges, numEdges);
37 for (Pos pos : cutEdges) {
38 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
39 }
40} 43}
41 44
42std::vector<Pos> Randomizer2Core::CutEdgesInternal(const Puzzle& p, std::vector<std::vector<int>>& colorGrid, std::vector<Pos>& edges, size_t numEdges) { 45std::vector<Pos> Randomizer2Core::CutEdgesInternal(const Puzzle& p, std::vector<Pos>& edges, size_t numEdges) {
46 auto [colorGrid, numColors] = CreateColorGrid(p);
47 assert(numEdges <= numColors);
48
43 std::vector<Pos> cutEdges; 49 std::vector<Pos> cutEdges;
44 for (int i=0; i<numEdges; i++) { 50 for (int i=0; i<numEdges; i++) {
45 for (int j=0; j<edges.size(); j++) { 51 for (int j=0; j<edges.size(); j++) {
@@ -79,6 +85,7 @@ std::vector<Pos> Randomizer2Core::CutEdgesInternal(const Puzzle& p, std::vector<
79 } 85 }
80 } 86 }
81 } 87 }
88 assert(cutEdges.size() == numEdges);
82 return cutEdges; 89 return cutEdges;
83} 90}
84 91
diff --git a/Source/Randomizer2Core.h b/Source/Randomizer2Core.h index 1b97fba..63ba6a8 100644 --- a/Source/Randomizer2Core.h +++ b/Source/Randomizer2Core.h
@@ -7,12 +7,11 @@ class Puzzle;
7class Randomizer2Core { 7class Randomizer2Core {
8public: 8public:
9 // CAUTION: Does not actually cut edges, just returns a list of suggested cuts. 9 // CAUTION: Does not actually cut edges, just returns a list of suggested cuts.
10 // Cuts a number of edges equal to the number of colors in the color grid. 10 static std::vector<Pos> CutEdges(const Puzzle& p, size_t numEdges);
11 static std::vector<Pos> CutEdgesToBeUnique(const Puzzle& p); 11 static std::vector<Pos> CutEdges2(const Puzzle& p, size_t numEdges);
12 static void CutEdgesNotOutsideNotBreakingSequence(Puzzle& p, size_t numEdges);
13 12
14private: 13private:
15 static std::vector<Pos> CutEdgesInternal(const Puzzle& p, std::vector<std::vector<int>>& colorGrid, std::vector<Pos>& edges, size_t numEdges); 14 static std::vector<Pos> CutEdgesInternal(const Puzzle& p, std::vector<Pos>& edges, size_t numEdges);
16 static void DebugColorGrid(const std::vector<std::vector<int>>& colorGrid); 15 static void DebugColorGrid(const std::vector<std::vector<int>>& colorGrid);
17 static void FloodFill(const Puzzle& p, std::vector<std::vector<int>>& colorGrid, int color, int x, int y); 16 static void FloodFill(const Puzzle& p, std::vector<std::vector<int>>& colorGrid, int color, int x, int y);
18 static void FloodFillOutside(const Puzzle& p, std::vector<std::vector<int>>& colorGrid, int x, int y); 17 static void FloodFillOutside(const Puzzle& p, std::vector<std::vector<int>>& colorGrid, int x, int y);
diff --git a/Source/Source.vcxproj b/Source/Source.vcxproj index 05f9ffa..33e3697 100644 --- a/Source/Source.vcxproj +++ b/Source/Source.vcxproj
@@ -161,7 +161,7 @@
161 <ClInclude Include="Memory.h" /> 161 <ClInclude Include="Memory.h" />
162 <ClInclude Include="Puzzle.h" /> 162 <ClInclude Include="Puzzle.h" />
163 <ClInclude Include="Panels.h" /> 163 <ClInclude Include="Panels.h" />
164 <ClInclude Include="PuzzlerSerializer.h" /> 164 <ClInclude Include="PuzzleSerializer.h" />
165 <ClInclude Include="Random.h" /> 165 <ClInclude Include="Random.h" />
166 <ClInclude Include="Randomizer.h" /> 166 <ClInclude Include="Randomizer.h" />
167 <ClInclude Include="Randomizer2.h" /> 167 <ClInclude Include="Randomizer2.h" />
@@ -173,7 +173,7 @@
173 <ClCompile Include="ChallengeRandomizer.cpp" /> 173 <ClCompile Include="ChallengeRandomizer.cpp" />
174 <ClCompile Include="Memory.cpp" /> 174 <ClCompile Include="Memory.cpp" />
175 <ClCompile Include="Puzzle.cpp" /> 175 <ClCompile Include="Puzzle.cpp" />
176 <ClCompile Include="PuzzlerSerializer.cpp" /> 176 <ClCompile Include="PuzzleSerializer.cpp" />
177 <ClCompile Include="Random.cpp" /> 177 <ClCompile Include="Random.cpp" />
178 <ClCompile Include="Randomizer.cpp" /> 178 <ClCompile Include="Randomizer.cpp" />
179 <ClCompile Include="Randomizer2.cpp" /> 179 <ClCompile Include="Randomizer2.cpp" />