summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Source/Puzzle.h4
-rw-r--r--Source/PuzzleSerializer.cpp15
-rw-r--r--Source/Randomizer2.cpp20
-rw-r--r--Source/Randomizer2Core.cpp30
-rw-r--r--Source/Randomizer2Core.h3
5 files changed, 37 insertions, 35 deletions
diff --git a/Source/Puzzle.h b/Source/Puzzle.h index 962874e..1e00ef4 100644 --- a/Source/Puzzle.h +++ b/Source/Puzzle.h
@@ -65,8 +65,8 @@ struct Pos {int x; int y;};
65 65
66class Puzzle { 66class Puzzle {
67public: 67public:
68 int16_t height = 0; 68 int height = 0;
69 int16_t width = 0; 69 int width = 0;
70 bool hasDecorations = false; 70 bool hasDecorations = false;
71 71
72 enum class Symmetry {NONE, X, Y, XY}; 72 enum class Symmetry {NONE, X, Y, XY};
diff --git a/Source/PuzzleSerializer.cpp b/Source/PuzzleSerializer.cpp index c1e93a5..e845578 100644 --- a/Source/PuzzleSerializer.cpp +++ b/Source/PuzzleSerializer.cpp
@@ -1,5 +1,6 @@
1#include "PuzzleSerializer.h" 1#include "PuzzleSerializer.h"
2#include "Memory.h" 2#include "Memory.h"
3#include <cassert>
3 4
4#pragma warning (disable:26451) 5#pragma warning (disable:26451)
5#pragma warning (disable:26812) 6#pragma warning (disable:26812)
@@ -47,6 +48,16 @@ void PuzzleSerializer::WritePuzzle(const Puzzle& p, int id) {
47 WriteDecorations(p, id); 48 WriteDecorations(p, id);
48 WriteSequence(p, id); 49 WriteSequence(p, id);
49 50
51#ifndef NDEBUG
52 int maxDots = _memory->ReadEntityData<int>(id, NUM_DOTS, 1)[0];
53 assert(_intersectionFlags.size() <= maxDots);
54 assert(_intersectionLocations.size() <= maxDots*2);
55
56 int maxConnections = _memory->ReadEntityData<int>(id, NUM_CONNECTIONS, 1)[0];
57 assert(_connectionsA.size() <= maxConnections);
58 assert(_connectionsB.size() <= maxConnections);
59#endif
60
50 _memory->WriteEntityData<int>(id, GRID_SIZE_X, {(p.width + 1)/2}); 61 _memory->WriteEntityData<int>(id, GRID_SIZE_X, {(p.width + 1)/2});
51 _memory->WriteEntityData<int>(id, GRID_SIZE_Y, {(p.height + 1)/2}); 62 _memory->WriteEntityData<int>(id, GRID_SIZE_Y, {(p.height + 1)/2});
52 _memory->WriteEntityData<int>(id, NUM_DOTS, {static_cast<int>(_intersectionFlags.size())}); 63 _memory->WriteEntityData<int>(id, NUM_DOTS, {static_cast<int>(_intersectionFlags.size())});
@@ -376,6 +387,10 @@ void PuzzleSerializer::WriteDecorations(const Puzzle& p, int id) {
376 } 387 }
377 } 388 }
378 389
390#ifndef NDEBUG
391 int maxDecorations = _memory->ReadEntityData<int>(id, NUM_DECORATIONS, 1)[0];
392 assert(decorations.size() < maxDecorations);
393#endif
379 _memory->WriteEntityData<int>(id, NUM_DECORATIONS, {static_cast<int>(decorations.size())}); 394 _memory->WriteEntityData<int>(id, NUM_DECORATIONS, {static_cast<int>(decorations.size())});
380 _memory->WriteArray<int>(id, DECORATIONS, decorations); 395 _memory->WriteArray<int>(id, DECORATIONS, decorations);
381} 396}
diff --git a/Source/Randomizer2.cpp b/Source/Randomizer2.cpp index 7a50c7b..c28795a 100644 --- a/Source/Randomizer2.cpp +++ b/Source/Randomizer2.cpp
@@ -14,7 +14,7 @@ Randomizer2::Randomizer2(const std::shared_ptr<Memory>& memory) : _memory(memory
14 14
15void Randomizer2::Randomize() { 15void Randomizer2::Randomize() {
16 RandomizeTutorial(); 16 RandomizeTutorial();
17 RandomizeKeep(); 17 // RandomizeKeep();
18} 18}
19 19
20void Randomizer2::RandomizeTutorial() { 20void Randomizer2::RandomizeTutorial() {
@@ -24,7 +24,7 @@ void Randomizer2::RandomizeTutorial() {
24 p.grid[0][8].start = true; 24 p.grid[0][8].start = true;
25 p.grid[8][0].end = Cell::Dir::UP; 25 p.grid[8][0].end = Cell::Dir::UP;
26 26
27 for (Pos pos : Randomizer2Core::CutEdges(p, 14)) { 27 for (Pos pos : Randomizer2Core::CutEdges(p, 14, true)) {
28 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 28 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
29 } 29 }
30 _serializer.WritePuzzle(p, 0x293); 30 _serializer.WritePuzzle(p, 0x293);
@@ -32,7 +32,7 @@ void Randomizer2::RandomizeTutorial() {
32 32
33 { 33 {
34 Puzzle p; 34 Puzzle p;
35 p.NewGrid(7, 7); 35 p.NewGrid(6, 6);
36 36
37 switch (Random::RandInt(1, 4)) { 37 switch (Random::RandInt(1, 4)) {
38 case 1: 38 case 1:
@@ -60,7 +60,7 @@ void Randomizer2::RandomizeTutorial() {
60 break; 60 break;
61 } 61 }
62 62
63 for (Pos pos : Randomizer2Core::CutEdges(p, 35)) { 63 for (Pos pos : Randomizer2Core::CutEdges(p, 35, true)) {
64 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 64 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
65 } 65 }
66 66
@@ -88,7 +88,7 @@ void Randomizer2::RandomizeKeep() {
88 p.grid[4][8].start = true; 88 p.grid[4][8].start = true;
89 p.grid[6][0].end = Cell::Dir::UP; 89 p.grid[6][0].end = Cell::Dir::UP;
90 90
91 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges2(p, 5); 91 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges(p, 5, false);
92 Puzzle copy = p; 92 Puzzle copy = p;
93 std::vector<int> gates = {0x00344, 0x00488, 0x00489, 0x00495, 0x00496}; 93 std::vector<int> gates = {0x00344, 0x00488, 0x00489, 0x00495, 0x00496};
94 for (int i=0; i<gates.size(); i++) { 94 for (int i=0; i<gates.size(); i++) {
@@ -118,7 +118,7 @@ void Randomizer2::RandomizeKeep() {
118 p.grid[0][8].start = true; 118 p.grid[0][8].start = true;
119 p.grid[8][0].end = Cell::Dir::RIGHT; 119 p.grid[8][0].end = Cell::Dir::RIGHT;
120 120
121 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges2(p, 7); 121 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges(p, 7, false);
122 for (Pos pos : cutEdges) { 122 for (Pos pos : cutEdges) {
123 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 123 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
124 } 124 }
@@ -133,7 +133,7 @@ void Randomizer2::RandomizeKeep() {
133 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 133 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
134 } 134 }
135 // Cut to 6 of 9 additional edges 135 // Cut to 6 of 9 additional edges
136 for (Pos pos : Randomizer2Core::CutEdges2(q, 6)) { 136 for (Pos pos : Randomizer2Core::CutEdges(q, 6, false)) {
137 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 137 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
138 } 138 }
139 _serializer.WritePuzzle(q, 0x19DC); 139 _serializer.WritePuzzle(q, 0x19DC);
@@ -158,7 +158,7 @@ void Randomizer2::RandomizeKeep() {
158 158
159 std::vector<int> pebbleMarkers = {0x034a9, 0x034b1, 0x034be, 0x034c4}; 159 std::vector<int> pebbleMarkers = {0x034a9, 0x034b1, 0x034be, 0x034c4};
160 160
161 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges2(p, 7); 161 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges(p, 7, false);
162 for (Pos pos : cutEdges) { 162 for (Pos pos : cutEdges) {
163 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK; 163 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
164 } 164 }
@@ -187,7 +187,7 @@ void Randomizer2::RandomizeKeep() {
187 p.grid[0][8].start = true; 187 p.grid[0][8].start = true;
188 p.grid[4][0].end = Cell::Dir::UP; 188 p.grid[4][0].end = Cell::Dir::UP;
189 189
190 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges2(p, 2); 190 std::vector<Pos> cutEdges = Randomizer2Core::CutEdges(p, 2, false);
191 for (Pos pos : cutEdges) { 191 for (Pos pos : cutEdges) {
192 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 192 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
193 } 193 }
@@ -201,7 +201,7 @@ void Randomizer2::RandomizeKeep() {
201 for (Pos pos : cutEdges) { 201 for (Pos pos : cutEdges) {
202 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 202 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
203 } 203 }
204 for (Pos pos : Randomizer2Core::CutEdges2(q, 7)) { 204 for (Pos pos : Randomizer2Core::CutEdges(q, 7, false)) {
205 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL; 205 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
206 } 206 }
207 _serializer.WritePuzzle(q, 0x1A0F); 207 _serializer.WritePuzzle(q, 0x1A0F);
diff --git a/Source/Randomizer2Core.cpp b/Source/Randomizer2Core.cpp index 8bd5765..0310ae2 100644 --- a/Source/Randomizer2Core.cpp +++ b/Source/Randomizer2Core.cpp
@@ -6,31 +6,19 @@
6#include <iostream> 6#include <iostream>
7#include <cassert> 7#include <cassert>
8 8
9// @Cutnpaste 9std::vector<Pos> Randomizer2Core::CutEdges(const Puzzle& p, size_t numEdges, bool allowEdges) {
10std::vector<Pos> Randomizer2Core::CutEdges(const Puzzle& p, size_t numEdges) {
11 std::vector<Pos> edges; 10 std::vector<Pos> edges;
12 for (int x=0; x<p.width; x++) { 11 int xMin = allowEdges ? 0 : 1;
13 for (int y=0; y<p.height; y++) { 12 int xMax = allowEdges ? p.width : p.width-1;
14 if (x%2 == y%2) continue; 13 int yMin = allowEdges ? 0 : 1;
15 if (p.grid[x][y].gap != Cell::Gap::NONE) continue; 14 int yMax = allowEdges ? p.height : p.height-1;
16 15
17 // If the puzzle already has a sequence, don't cut along it. 16 for (int x=xMin; x<xMax; x++) {
18 bool inSequence = false; 17 for (int y=yMin; y<yMax; y++) {
19 for (Pos pos : p.sequence) inSequence |= (pos.x == x && pos.y == y);
20 if (inSequence) continue;
21 edges.emplace_back(Pos{x, y});
22 }
23 }
24 return CutEdgesInternal(p, edges, numEdges);
25}
26
27std::vector<Pos> Randomizer2Core::CutEdges2(const Puzzle& p, size_t numEdges) {
28 std::vector<Pos> edges;
29 // Note the iterator bounds; we skip the outer edges.
30 for (int x=1; x<p.width-1; x++) {
31 for (int y=1; y<p.height-1; y++) {
32 if (x%2 == y%2) continue; 18 if (x%2 == y%2) continue;
33 if (p.grid[x][y].gap != Cell::Gap::NONE) continue; 19 if (p.grid[x][y].gap != Cell::Gap::NONE) continue;
20 if (p.grid[x][y].start) continue;
21 if (p.grid[x][y].end != Cell::Dir::NONE) continue;
34 22
35 // If the puzzle already has a sequence, don't cut along it. 23 // If the puzzle already has a sequence, don't cut along it.
36 bool inSequence = false; 24 bool inSequence = false;
diff --git a/Source/Randomizer2Core.h b/Source/Randomizer2Core.h index 63ba6a8..443f893 100644 --- a/Source/Randomizer2Core.h +++ b/Source/Randomizer2Core.h
@@ -7,8 +7,7 @@ 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 static std::vector<Pos> CutEdges(const Puzzle& p, size_t numEdges); 10 static std::vector<Pos> CutEdges(const Puzzle& p, size_t numEdges, bool allowEdges);
11 static std::vector<Pos> CutEdges2(const Puzzle& p, size_t numEdges);
12 11
13private: 12private:
14 static std::vector<Pos> CutEdgesInternal(const Puzzle& p, std::vector<Pos>& edges, size_t numEdges); 13 static std::vector<Pos> CutEdgesInternal(const Puzzle& p, std::vector<Pos>& edges, size_t numEdges);