diff options
Diffstat (limited to 'Source/Randomizer2.cpp')
| -rw-r--r-- | Source/Randomizer2.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
| 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 | |||
| 6 | Randomizer2::Randomizer2(const std::shared_ptr<Memory>& memory) : _memory(memory) {} | ||
| 7 | |||
| 8 | void 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 | } | ||
