-
Notifications
You must be signed in to change notification settings - Fork 0
/
solver.js
97 lines (92 loc) · 2.79 KB
/
solver.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Basic Backtracking solver, but looks more like brute force. Very slow...
var MAX_MOVES = 50; // max moves in one solution
var numRecursiveCalls = 0;
var findAtMostOneSolution = true;
var solutions = []; // array of solutions. Each solution is a sequence of moves
var sequenceOfMoves = [];
// generate possible move requests, ie moves that effectively move at least one tooth,
// and which do not generate a broken tooth
function generatePossibleMoves() {
let possibleMoves = [];
[
MOVE_REQUEST.LEFT,
MOVE_REQUEST.RIGHT,
MOVE_REQUEST.UP,
MOVE_REQUEST.DOWN,
].forEach(function (aMoveRequest) {
if (moveAllTeeth(aMoveRequest)) {
// the move request moved at least one tooth,
// we will add it in the list of possible moves only if it does not break a tooth
if (!isOneToothBroken()) {
possibleMoves.push(aMoveRequest);
}
undoLastMove();
} else {
// the move request did not move any tooth, no need to undo
}
});
return possibleMoves;
}
// recursive solve,
function recursiveSolve() {
solutionFound = false;
numRecursiveCalls++;
if (numRecursiveCalls % 1000 == 0) {
console.log("num recursive calls: ", numRecursiveCalls);
}
if (isAllTeethSaved()) {
solutionFound = true;
solutions.push(sequenceOfMoves);
strSolution = "";
sequenceOfMoves.forEach(function (aMove) {
strSolution += ",";
strSolution += aMove;
});
console.log("solution found: (", sequenceOfMoves.length, "):", strSolution);
console.log("num recursive calls: ", numRecursiveCalls);
} else {
// if we reached the maximum search depth, search no further
if (sequenceOfMoves.length >= MAX_MOVES) {
solutionFound = false;
} else {
// !! use "let" to force re-instanciation at each recursive call
let possibleMoves = generatePossibleMoves();
let i = 0;
while (
i < possibleMoves.length &&
(solutionFound == false || !findAtMostOneSolution)
) {
aMoveRequest = possibleMoves[i];
sequenceOfMoves.push(aMoveRequest);
if (DEBUG && 0) {
console.log(
"analyse:moves(",
i + 1,
"/",
possibleMoves.length,
")=",
sequenceOfMoves
);
}
moveAllTeeth(aMoveRequest);
if (recursiveSolve()) {
solutionFound = true;
}
undoLastMove();
sequenceOfMoves.pop();
if (DEBUG && 0) {
console.log("undo: moves = ", sequenceOfMoves);
}
i++;
}
}
}
return solutionFound;
}
// initialise variables for solve, then call the recursive solve
function solve() {
numRecursiveCalls = 0;
solutions = []; // array of solutions. Each solution is a sequence of moves
sequenceOfMoves = [];
recursiveSolve();
}