diff options
Diffstat (limited to 'Source/Solver.cpp')
-rw-r--r-- | Source/Solver.cpp | 76 |
1 files changed, 0 insertions, 76 deletions
diff --git a/Source/Solver.cpp b/Source/Solver.cpp deleted file mode 100644 index 74fa099..0000000 --- a/Source/Solver.cpp +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | #include "pch.h" | ||
2 | #include "Solver.h" | ||
3 | #include "Validator.h" | ||
4 | |||
5 | int Solver::MAX_SOLUTIONS = 10000; | ||
6 | |||
7 | std::vector<Puzzle> Solver::Solve(Puzzle& p) { | ||
8 | std::vector<Puzzle> solutions; | ||
9 | // var start = (new Date()).getTime() | ||
10 | for (int x = 0; x < p.width; x++) { | ||
11 | for (int y = 0; y < p.height; y++) { | ||
12 | Cell cell = p.grid[x][y]; | ||
13 | if (cell.start) { | ||
14 | SolveLoop(p, x, y, solutions); | ||
15 | } | ||
16 | } | ||
17 | } | ||
18 | // var end = (new Date()).getTime() | ||
19 | // console.info('Solved', puzzle, 'in', (end-start)/1000, 'seconds') | ||
20 | return solutions; | ||
21 | } | ||
22 | |||
23 | void Solver::SolveLoop(Puzzle& p, int x, int y, std::vector<Puzzle>& solutions) { | ||
24 | // Stop trying to solve once we reach our goal | ||
25 | if (solutions.size() >= MAX_SOLUTIONS) return; | ||
26 | Cell cell = p.GetCell(x, y); | ||
27 | if (cell.undefined) return; | ||
28 | if (cell.gap != Cell::Gap::NONE) return; | ||
29 | |||
30 | if (p.symmetry == Puzzle::Symmetry::NONE) { | ||
31 | if (cell.color != Cell::Color::NONE) return; // Collided with ourselves | ||
32 | p.grid[x][y].color = Cell::Color::BLACK; // Otherwise, mark this cell as visited | ||
33 | } else { | ||
34 | // Get the symmetrical position, and try coloring it | ||
35 | auto sym = p.GetSymmetricalPos(x, y); | ||
36 | Cell::Color oldColor = p.GetLine(sym.x, sym.y); | ||
37 | p.grid[sym.x][sym.y].color = Cell::Color::YELLOW; | ||
38 | |||
39 | // Collided with ourselves or our reflection | ||
40 | if (cell.color != Cell::Color::NONE) { | ||
41 | p.grid[sym.x][sym.y].color = oldColor; | ||
42 | return; | ||
43 | } | ||
44 | p.grid[x][y].color = Cell::Color::BLUE; // Otherwise, mark this cell as visited | ||
45 | } | ||
46 | p.sequence.emplace_back(x, y); | ||
47 | |||
48 | if (cell.end != Cell::Dir::NONE) { | ||
49 | // Reached an endpoint, validate solution and keep going -- there may be other endpoints | ||
50 | Validator::Validate(p); | ||
51 | if (p.valid) { | ||
52 | Puzzle clone = p; | ||
53 | solutions.push_back(clone); | ||
54 | } | ||
55 | } | ||
56 | |||
57 | // Recursion order (LRUD) is optimized for BL->TR and mid-start puzzles | ||
58 | // Extend path left and right | ||
59 | if (y % 2 == 0) { | ||
60 | SolveLoop(p, x - 1, y, solutions); | ||
61 | SolveLoop(p, x + 1, y, solutions); | ||
62 | } | ||
63 | // Extend path up and down | ||
64 | if (x % 2 == 0) { | ||
65 | SolveLoop(p, x, y - 1, solutions); | ||
66 | SolveLoop(p, x, y + 1, solutions); | ||
67 | } | ||
68 | |||
69 | // Tail recursion: Back out of this cell | ||
70 | p.grid[x][y].color = Cell::Color::NONE; | ||
71 | p.sequence.pop_back(); | ||
72 | if (p.symmetry != Puzzle::Symmetry::NONE) { | ||
73 | auto sym = p.GetSymmetricalPos(x, y); | ||
74 | p.grid[sym.x][sym.y].color = Cell::Color::NONE; | ||
75 | } | ||
76 | } | ||