new recursive backtracking builder

recursive
Ondřej Hruška 5 years ago
parent 4e4ce7c962
commit 081f252e89
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 75
      script.js

@ -1214,7 +1214,8 @@ class Game {
} }
placeOrbs(template) { placeOrbs(template) {
let placer = new RadialOrbPlacer(this, template); // let placer = new RadialOrbPlacer(this, template);
let placer = new RecursiveOrbPlacer(this, template);
return placer.place(); return placer.place();
} }
@ -1960,6 +1961,78 @@ class RadialOrbPlacer extends BaseOrbPlacer {
} }
} }
class RecursiveOrbPlacer extends BaseOrbPlacer {
doPlace(toPlace) {
this.toPlace = toPlace;
this.recDepth = 0;
this.placeOne(0);
return {};
}
placeOne() {
this.recDepth++;
if (this.recDepth > 2000) {
throw new Error("Too many backtracks");
}
let symbol = this.toPlace.pop();
let candidates = [[],[],[],[],[],[],[]];
for (let n of this.template) {
if (!this.board.grid[n]) {
// is free
const cell = this.getCellInfo(n);
if (cell.freeSequence >= 3) {
candidates[cell.neighbours].push(n);
}
}
}
for (let neighs = 6; neighs >= 0; neighs--) {
this.rng.arrayShuffle(candidates[neighs]);
}
for (let i = 6; i >= 0; i--) {
if (candidates[i].length) {
for (let n of candidates[i]) {
this.placeOrb(n, symbol);
// avoid deadlocking
if (this.solution.length % 2 === 0) {
// this is the second orb in a pair (solution starts with gold)
let prevn = this.solution[this.solution.length-1][1];
if (!this.isAvailable(prevn)) {
this.trace("Avoid deadlock (this is the second of a pair)");
this.removeOrb(n);
continue;
}
}
this.solution.push([symbol, n]);
if (this.toPlace.length) {
if (this.placeOne()) {
return true;
} else {
this.trace("Undo and continue");
this.removeOrb(n);
this.solution.pop();
// and continue the iteration
}
} else {
return true;
}
}
}
}
// give it back
this.toPlace.push(symbol);
return false;
}
}
/* Start */ /* Start */

Loading…
Cancel
Save