summary refs log tree commit diff stats
path: root/Source/Randomizer2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Randomizer2.cpp')
-rw-r--r--Source/Randomizer2.cpp644
1 files changed, 0 insertions, 644 deletions
diff --git a/Source/Randomizer2.cpp b/Source/Randomizer2.cpp deleted file mode 100644 index 421ce69..0000000 --- a/Source/Randomizer2.cpp +++ /dev/null
@@ -1,644 +0,0 @@
1#include "pch.h"
2#include "Randomizer2.h"
3#include "PuzzleSerializer.h"
4#include "Randomizer2Core.h"
5#include "Random.h"
6#include "Solver.h"
7#include "Windows.h"
8
9Randomizer2::Randomizer2(const PuzzleSerializer& serializer) : _serializer(serializer) {
10}
11
12void Randomizer2::Randomize() {
13 // RandomizeTutorial();
14 // RandomizeGlassFactory();
15 RandomizeSymmetryIsland();
16 // RandomizeKeep();
17}
18
19void Randomizer2::RandomizeTutorial() {
20 { // Far center
21 Puzzle p;
22 p.NewGrid(4, 4);
23 p.grid[0][8].start = true;
24 p.grid[8][0].end = Cell::Dir::UP;
25
26 for (Pos pos : Randomizer2Core::CutEdges(p, 14)) {
27 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
28 }
29 _serializer.WritePuzzle(p, 0x293);
30 }
31
32 { // Center left
33 Puzzle p;
34 p.NewGrid(6, 6);
35
36 int x = Random::RandInt(0, (p.width-1)/2)*2;
37 int y = Random::RandInt(0, (p.height-1)/2)*2;
38 int rng = Random::RandInt(1, 4);
39 if (rng == 1) p.grid[x][0].end = Cell::Dir::UP;
40 else if (rng == 2) p.grid[x][p.height-1].end = Cell::Dir::DOWN;
41 else if (rng == 3) p.grid[0][y].end = Cell::Dir::LEFT;
42 else if (rng == 4) p.grid[p.width-1][y].end = Cell::Dir::RIGHT;
43
44 // [4/6/8][4/6/8]
45 p.grid[Random::RandInt(0, 2)*2 + 4][Random::RandInt(0, 2)*2 + 4].start = true;
46
47 for (Pos pos : Randomizer2Core::CutEdges(p, 35)) {
48 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
49 }
50
51 _serializer.WritePuzzle(p, 0x295);
52 }
53
54 { // Far left
55 Puzzle p;
56 p.NewGrid(10, 10);
57
58 p.grid[0][20].start = true;
59 p.grid[20][0].end = Cell::Dir::RIGHT;
60
61 for (Pos pos : Randomizer2Core::CutEdges(p, 96)) {
62 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
63 }
64 _serializer.WritePuzzle(p, 0x2C2);
65 }
66
67 { // Back left
68 Puzzle p;
69 p.NewGrid(6, 6);
70
71 p.grid[0][12].start = true;
72 p.grid[12][0].end = Cell::Dir::RIGHT;
73 p.grid[12][12].end = Cell::Dir::RIGHT;
74
75 for (Pos pos : Randomizer2Core::CutEdges(p, 27)) {
76 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
77 }
78 _serializer.WritePuzzle(p, 0xA3B5);
79 }
80
81 { // Back right
82 Puzzle p;
83 p.NewGrid(6, 6);
84
85 p.grid[0][12].start = true;
86 p.grid[12][12].start = true;
87 p.grid[6][0].end = Cell::Dir::UP;
88
89 // @Cleanup
90 std::vector<Pos> cuts;
91 bool toTheRight;
92 // Start by generating a cut line, to ensure one of the two startpoints is inaccessible
93 int x, y;
94 switch (Random::RandInt(1, 4)) {
95 case 1:
96 x = 1; y = 1;
97 toTheRight = true;
98 cuts.emplace_back(0, 1);
99 break;
100 case 2:
101 x = 1; y = 1;
102 toTheRight = true;
103 cuts.emplace_back(1, 0);
104 break;
105 case 3:
106 x = 11; y = 1;
107 toTheRight = false;
108 cuts.emplace_back(12, 1);
109 break;
110 case 4:
111 x = 11; y = 1;
112 toTheRight = false;
113 cuts.emplace_back(11, 0);
114 break;
115 }
116 while (y < p.height) { // The final cut will push y below the bottom of the puzzle, which means we're done.
117 switch (Random::RandInt(1, 4)) {
118 case 1: // Go right
119 if (x < p.width-2) {
120 cuts.emplace_back(x+1, y);
121 x += 2;
122 }
123 break;
124 case 2: // Go left
125 if (x > 1) {
126 cuts.emplace_back(x-1, y);
127 x -= 2;
128 }
129 break;
130 case 3:
131 case 4: // Go down (biased x2)
132 cuts.emplace_back(x, y+1);
133 y += 2;
134 break;
135 }
136 }
137
138 for (Pos pos : cuts) {
139 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
140 }
141
142 for (Pos pos : Randomizer2Core::CutEdges(p, 30 - cuts.size())) {
143 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
144 }
145 _serializer.WritePuzzle(p, 0xA3B2);
146 }
147}
148
149void Randomizer2::RandomizeGlassFactory() {
150 { // Back wall 1
151 Puzzle p;
152 p.NewGrid(3, 3);
153 p.symmetry = Puzzle::Symmetry::X;
154 p.grid[0][6].start = true;
155 p.grid[6][6].start = true;
156 p.grid[2][0].end = Cell::Dir::UP;
157 p.grid[4][0].end = Cell::Dir::UP;
158
159 std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 2);
160 for (Pos pos : cutEdges) {
161 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
162 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
163 p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
164 }
165 _serializer.WritePuzzle(p, 0x86);
166 }
167 { // Back wall 2
168 Puzzle p;
169 p.NewGrid(4, 4);
170 p.symmetry = Puzzle::Symmetry::X;
171 p.grid[0][8].start = true;
172 p.grid[8][8].start = true;
173 p.grid[2][0].end = Cell::Dir::UP;
174 p.grid[6][0].end = Cell::Dir::UP;
175 std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 4);
176 for (int i=0; i<cutEdges.size(); i++) {
177 Pos pos = cutEdges[i];
178 if (i%2 == 0) {
179 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
180 } else {
181 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
182 p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
183 }
184 }
185
186 _serializer.WritePuzzle(p, 0x87);
187 }
188 { // Back wall 3
189 Puzzle p;
190 p.NewGrid(5, 6);
191 p.symmetry = Puzzle::Symmetry::X;
192 p.grid[2][10].start = true;
193 p.grid[8][10].start = true;
194 p.grid[4][0].end = Cell::Dir::UP;
195 p.grid[6][0].end = Cell::Dir::UP;
196 std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 10);
197 for (int i=0; i<cutEdges.size(); i++) {
198 Pos pos = cutEdges[i];
199 if (i%2 == 0) {
200 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
201 } else {
202 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
203 p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
204 }
205 }
206
207 _serializer.WritePuzzle(p, 0x59);
208 }
209 { // Back wall 4
210 Puzzle p;
211 p.NewGrid(5, 8);
212 p.symmetry = Puzzle::Symmetry::X;
213 p.grid[2][16].start = true;
214 p.grid[8][16].start = true;
215 p.grid[4][0].end = Cell::Dir::UP;
216 p.grid[6][0].end = Cell::Dir::UP;
217 std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 15);
218 for (int i=0; i<cutEdges.size(); i++) {
219 Pos pos = cutEdges[i];
220 if (i%2 == 0) {
221 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
222 } else {
223 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
224 p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
225 }
226 }
227
228 _serializer.WritePuzzle(p, 0x62);
229 }
230 // TODO: Positioning is off, slightly -- which means you can start from the bottom left, if you peek around.
231 { // Back wall 5
232 Puzzle p;
233 p.NewGrid(11, 8);
234 p.symmetry = Puzzle::Symmetry::X;
235 p.grid[0][16].start = true;
236 p.grid[10][16].start = true;
237 p.grid[12][16].start = true;
238 p.grid[22][16].start = true;
239 p.grid[2][0].end = Cell::Dir::UP;
240 p.grid[8][0].end = Cell::Dir::UP;
241 p.grid[14][0].end = Cell::Dir::UP;
242 p.grid[20][0].end = Cell::Dir::UP;
243
244 Puzzle q;
245 q.NewGrid(5, 8);
246 q.symmetry = Puzzle::Symmetry::X;
247
248 for (Pos pos : Randomizer2Core::CutSymmetricalEdgePairs(q, 16)) {
249 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
250 }
251 for (Pos pos : Randomizer2Core::CutSymmetricalEdgePairs(q, 16)) {
252 p.grid[pos.x + 12][pos.y].gap = Cell::Gap::BREAK;
253 }
254
255 for (int y=0; y<p.height; y+=2) {
256 p.grid[5][y].gap = Cell::Gap::BREAK;
257 }
258
259 _serializer.WritePuzzle(p, 0x5C);
260 }
261
262 { // Rotational 1
263 Puzzle p;
264 p.NewGrid(3, 3);
265 p.symmetry = Puzzle::Symmetry::XY;
266 p.grid[6][0].start = true;
267 p.grid[0][6].start = true;
268 p.grid[4][0].end = Cell::Dir::UP;
269 p.grid[2][6].end = Cell::Dir::DOWN;
270
271 p.grid[5][0].gap = Cell::Gap::BREAK;
272 p.grid[1][6].gap = Cell::Gap::BREAK;
273
274 for (Pos pos : Randomizer2Core::CutSymmetricalEdgePairs(p, 1)) {
275 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
276 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
277 p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
278 }
279 _serializer.WritePuzzle(p, 0x8D);
280 }
281 { // Rotational 2
282 Puzzle p;
283 p.NewGrid(3, 3);
284 p.symmetry = Puzzle::Symmetry::XY;
285 p.grid[6][0].start = true;
286 p.grid[0][6].start = true;
287 p.grid[4][0].end = Cell::Dir::UP;
288 p.grid[2][6].end = Cell::Dir::DOWN;
289
290 p.grid[5][0].gap = Cell::Gap::BREAK;
291 p.grid[1][6].gap = Cell::Gap::BREAK;
292
293 std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 3);
294 for (int i=0; i<cutEdges.size(); i++) {
295 Pos pos = cutEdges[i];
296 if (i%2 == 0) {
297 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
298 } else {
299 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
300 p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
301 }
302 }
303
304 p.grid[1][6].gap = Cell::Gap::NONE;
305
306 _serializer.WritePuzzle(p, 0x81);
307 }
308 { // Rotational 3
309 Puzzle p;
310 p.NewGrid(4, 4);
311 p.symmetry = Puzzle::Symmetry::XY;
312 p.grid[8][0].start = true;
313 p.grid[0][8].start = true;
314 p.grid[0][0].end = Cell::Dir::LEFT;
315 p.grid[8][8].end = Cell::Dir::RIGHT;
316
317 std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 7);
318 for (int i=0; i<cutEdges.size(); i++) {
319 Pos pos = cutEdges[i];
320 if (i%2 == 0) {
321 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
322 } else {
323 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
324 p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
325 }
326 }
327
328 _serializer.WritePuzzle(p, 0x83);
329 }
330 { // Melting
331 Puzzle p;
332 p.NewGrid(6, 6);
333 p.symmetry = Puzzle::Symmetry::XY;
334 p.grid[12][0].start = true;
335 p.grid[0][12].start = true;
336 p.grid[0][0].end = Cell::Dir::LEFT;
337 p.grid[12][12].end = Cell::Dir::RIGHT;
338 Puzzle q = p;
339
340 std::vector<Pos> cutEdges = Randomizer2Core::CutSymmetricalEdgePairs(p, 15);
341 for (int i=0; i<cutEdges.size(); i++) {
342 Pos pos = cutEdges[i];
343 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
344
345 if (i%2 == 0) {
346 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
347 } else {
348 p.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
349 }
350
351 if (pos.x < sym.x) {
352 q.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
353 } else {
354 q.grid[sym.x][sym.y].gap = Cell::Gap::BREAK;
355 }
356 }
357
358 _serializer.WritePuzzle(p, 0x84); // Melting 1
359 _serializer.WritePuzzle(q, 0x82); // Melting 2
360 _serializer.WritePuzzle(q, 0x343A); // Melting 3
361 }
362}
363
364void Randomizer2::RandomizeSymmetryIsland() {
365 { // Entry door
366 Puzzle p;
367 p.NewGrid(4, 3);
368 p.grid[0][6].start = true;
369 p.grid[8][0].end = Cell::Dir::RIGHT;
370 p.grid[4][3].gap = Cell::Gap::FULL;
371
372 std::vector<Pos> corners;
373 std::vector<Pos> cells;
374 std::vector<Pos> edges;
375 for (int x=0; x<p.width; x++) {
376 for (int y=0; y<p.height; y++) {
377 if (x%2 == 0 && y%2 == 0) corners.emplace_back(Pos{x, y});
378 else if (x%2 == 1 && y%2 == 1) cells.emplace_back(Pos{x, y});
379 else edges.emplace_back(Pos{x, y});
380 }
381 }
382
383 for (int j=0;; j++) {
384 std::vector<Pos> dots = Random::SelectFromSet(edges, 4);
385 for (Pos pos : dots) p.grid[pos.x][pos.y].dot = Cell::Dot::BLACK;
386
387 auto solutions = Solver::Solve(p);
388 if (solutions.size() > 0 && solutions.size() < 10) break;
389
390 for (Pos pos : dots) p.grid[pos.x][pos.y].dot = Cell::Dot::NONE;
391 }
392
393 _serializer.WritePuzzle(p, 0xB0);
394 }
395
396 { // Dots 1
397 Puzzle p;
398 p.NewGrid(3, 3);
399 p.symmetry = Puzzle::Symmetry::Y;
400 p.grid[0][2].start = true;
401 p.grid[0][4].start = true;
402 p.grid[6][2].end = Cell::Dir::RIGHT;
403 p.grid[6][4].end = Cell::Dir::RIGHT;
404
405 std::vector<Pos> corners;
406 std::vector<Pos> cells;
407 std::vector<Pos> edges;
408 for (int x=0; x<p.width; x++) {
409 for (int y=0; y<p.height/2; y++) {
410 if (x%2 == 0 && y%2 == 0) corners.emplace_back(Pos{x, y});
411 else if (x%2 == 1 && y%2 == 1) cells.emplace_back(Pos{x, y});
412 else edges.emplace_back(Pos{x, y});
413 }
414 }
415 edges.insert(edges.end(), corners.begin(), corners.end());
416
417 std::vector<Pos> dots;
418 for (int j=0;; j++) {
419 dots = Random::SelectFromSet(edges, 3);
420 for (Pos pos : dots) p.grid[pos.x][pos.y].dot = Cell::Dot::BLACK;
421
422 auto solutions = Solver::Solve(p);
423 if (solutions.size() == 2) break;
424
425 for (Pos pos : dots) p.grid[pos.x][pos.y].dot = Cell::Dot::NONE;
426 }
427
428 for (Pos pos : dots) {
429 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
430 p.grid[sym.x][sym.y].dot = Cell::Dot::BLACK;
431 }
432
433 _serializer.WritePuzzle(p, 0x22);
434 }
435 { // Dots 2
436 Puzzle p;
437 p.NewGrid(3, 3);
438 p.symmetry = Puzzle::Symmetry::Y;
439 p.grid[0][2].start = true;
440 p.grid[0][4].start = true;
441 p.grid[6][2].end = Cell::Dir::RIGHT;
442 p.grid[6][4].end = Cell::Dir::RIGHT;
443
444 std::vector<Pos> corners;
445 std::vector<Pos> cells;
446 std::vector<Pos> edges;
447 for (int x=0; x<p.width; x++) {
448 for (int y=0; y<p.height/2; y++) {
449 if (x%2 == 0 && y%2 == 0) corners.emplace_back(Pos{x, y});
450 else if (x%2 == 1 && y%2 == 1) cells.emplace_back(Pos{x, y});
451 else edges.emplace_back(Pos{x, y});
452 }
453 }
454 edges.insert(edges.end(), corners.begin(), corners.end());
455
456 std::vector<Pos> dots;
457 for (int j=0;; j++) {
458 dots = Random::SelectFromSet(edges, 3);
459 for (Pos pos : dots) p.grid[pos.x][pos.y].dot = Cell::Dot::BLACK;
460
461 auto solutions = Solver::Solve(p);
462 if (solutions.size() == 2) break;
463
464 for (Pos pos : dots) p.grid[pos.x][pos.y].dot = Cell::Dot::NONE;
465 }
466
467 Pos pos = dots[1];
468 Pos sym = p.GetSymmetricalPos(pos.x, pos.y);
469 p.grid[pos.x][pos.y].dot = Cell::Dot::NONE;
470 p.grid[sym.x][sym.y].dot = Cell::Dot::BLACK;
471
472 _serializer.WritePuzzle(p, 0x23);
473 }
474}
475
476void Randomizer2::RandomizeKeep() {
477 { // Hedges 1
478 Puzzle p;
479 p.NewGrid(4, 4);
480
481 p.grid[2][1].gap = Cell::Gap::FULL;
482 p.grid[4][1].gap = Cell::Gap::FULL;
483 p.grid[6][1].gap = Cell::Gap::FULL;
484 p.grid[3][2].gap = Cell::Gap::FULL;
485 p.grid[5][2].gap = Cell::Gap::FULL;
486 p.grid[8][3].gap = Cell::Gap::FULL;
487 p.grid[2][5].gap = Cell::Gap::FULL;
488 p.grid[6][5].gap = Cell::Gap::FULL;
489 p.grid[7][6].gap = Cell::Gap::FULL;
490 p.grid[2][7].gap = Cell::Gap::FULL;
491 p.grid[4][7].gap = Cell::Gap::FULL;
492
493 p.grid[4][8].start = true;
494 p.grid[6][0].end = Cell::Dir::UP;
495
496 std::vector<Pos> cutEdges = Randomizer2Core::CutInsideEdges(p, 5);
497 Puzzle copy = p;
498 std::vector<int> gates = {0x00344, 0x00488, 0x00489, 0x00495, 0x00496};
499 for (int i=0; i<cutEdges.size(); i++) {
500 Pos pos = cutEdges[i];
501 copy.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
502 SetGate(gates[i], pos.x, pos.y);
503 }
504 auto solution = GetUniqueSolution(copy);
505 p.sequence = solution.sequence;
506 _serializer.WritePuzzle(p, 0x139);
507 }
508
509 { // Hedges 2
510 Puzzle p;
511 p.NewGrid(4, 4);
512
513 p.grid[2][1].gap = Cell::Gap::FULL;
514 p.grid[1][2].gap = Cell::Gap::FULL;
515 p.grid[5][2].gap = Cell::Gap::FULL;
516 p.grid[7][4].gap = Cell::Gap::FULL;
517 p.grid[4][5].gap = Cell::Gap::FULL;
518 p.grid[6][5].gap = Cell::Gap::FULL;
519 p.grid[1][6].gap = Cell::Gap::FULL;
520 p.grid[2][7].gap = Cell::Gap::FULL;
521 p.grid[5][8].gap = Cell::Gap::FULL;
522
523 p.grid[0][8].start = true;
524 p.grid[8][0].end = Cell::Dir::RIGHT;
525
526 std::vector<Pos> cutEdges = Randomizer2Core::CutInsideEdges(p, 7);
527 for (Pos pos : cutEdges) {
528 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
529 }
530 auto solution = GetUniqueSolution(p);
531
532 Puzzle q;
533 q.NewGrid(4, 4);
534 q.grid[0][8].start = true;
535 q.grid[8][0].end = Cell::Dir::RIGHT;
536 q.sequence = solution.sequence;
537 for (Pos pos : cutEdges) {
538 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
539 }
540 // Cut to 6 of 9 additional edges
541 for (Pos pos : Randomizer2Core::CutInsideEdges(q, 6)) {
542 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
543 }
544 _serializer.WritePuzzle(q, 0x19DC);
545 }
546
547 { // Hedges 3 [WIP]
548 Puzzle p;
549 p.NewGrid(4, 4);
550
551 p.grid[2][1].gap = Cell::Gap::FULL;
552 p.grid[5][2].gap = Cell::Gap::FULL;
553 p.grid[7][2].gap = Cell::Gap::FULL;
554 p.grid[4][3].gap = Cell::Gap::FULL;
555 p.grid[1][4].gap = Cell::Gap::FULL;
556 p.grid[6][5].gap = Cell::Gap::FULL;
557 p.grid[1][6].gap = Cell::Gap::FULL;
558 p.grid[3][6].gap = Cell::Gap::FULL;
559 p.grid[6][7].gap = Cell::Gap::FULL;
560
561 p.grid[0][8].start = true;
562 p.grid[8][2].end = Cell::Dir::RIGHT;
563
564 std::vector<Pos> cutEdges = Randomizer2Core::CutInsideEdges(p, 7);
565 for (Pos pos : cutEdges) {
566 p.grid[pos.x][pos.y].gap = Cell::Gap::BREAK;
567 }
568
569 std::vector<int> pebbleMarkers = {0x034a9, 0x034b1, 0x034be, 0x034c4};
570
571 // _serializer.WritePuzzle(p, 0x19E7);
572 }
573
574 { // Hedges 4
575 Puzzle p;
576 p.NewGrid(4, 4);
577
578 p.grid[3][0].gap = Cell::Gap::FULL;
579 p.grid[4][1].gap = Cell::Gap::FULL;
580 p.grid[8][1].gap = Cell::Gap::FULL;
581 p.grid[1][2].gap = Cell::Gap::FULL;
582 p.grid[4][3].gap = Cell::Gap::FULL;
583 p.grid[8][3].gap = Cell::Gap::FULL;
584 p.grid[1][4].gap = Cell::Gap::FULL;
585 p.grid[5][4].gap = Cell::Gap::FULL;
586 p.grid[2][5].gap = Cell::Gap::FULL;
587 p.grid[6][5].gap = Cell::Gap::FULL;
588 p.grid[3][6].gap = Cell::Gap::FULL;
589 p.grid[0][7].gap = Cell::Gap::FULL;
590 p.grid[8][7].gap = Cell::Gap::FULL;
591 p.grid[5][8].gap = Cell::Gap::FULL;
592
593 p.grid[0][8].start = true;
594 p.grid[4][0].end = Cell::Dir::UP;
595
596 std::vector<Pos> cutEdges = Randomizer2Core::CutInsideEdges(p, 2);
597 for (Pos pos : cutEdges) {
598 p.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
599 }
600 auto solution = GetUniqueSolution(p);
601
602 Puzzle q;
603 q.NewGrid(4, 4);
604 q.grid[0][8].start = true;
605 q.grid[4][0].end = Cell::Dir::UP;
606 q.sequence = solution.sequence;
607 for (Pos pos : cutEdges) {
608 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
609 }
610 for (Pos pos : Randomizer2Core::CutInsideEdges(q, 7)) {
611 q.grid[pos.x][pos.y].gap = Cell::Gap::FULL;
612 }
613 _serializer.WritePuzzle(q, 0x1A0F);
614 }
615}
616
617Puzzle Randomizer2::GetUniqueSolution(Puzzle& p) {
618 auto solutions = Solver::Solve(p);
619 assert(solutions.size() == 1);
620 return solutions[0];
621}
622
623void Randomizer2::SetGate(int panel, int X, int Y) {
624 float x, y, z, w;
625 if (X%2 == 0 && Y%2 == 1) { // Horizontal
626 x = -1.49f * X + 0.22f * Y + 66.58f;
627 y = 0.275f * X + 1.6f * Y + 108.4f;
628 z = -.77f;
629 w = .63f;
630 } else { // Vertical
631 assert(X%2 == 1 && Y%2 == 0);
632 x = -1.6f * X + 0.35f * Y + 66.5f;
633 y = 0.25f * X + 1.6f * Y + 108.55f;
634 z = -0.1f;
635 w = 1.0f;
636 }
637
638 SetPos(panel, x, y, 19.2f);
639 // _memory->WriteEntityData<float>(panel, ORIENTATION, {0.0f, 0.0f, z, w});
640}
641
642void Randomizer2::SetPos(int panel, float x, float y, float z) {
643 // _memory->WriteEntityData<float>(panel, POSITION, {x, y, z});
644} \ No newline at end of file