From 081f252e897d41b2e310312c47d1083e514d6d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sun, 15 Dec 2019 00:14:45 +0100 Subject: [PATCH] new recursive backtracking builder --- script.js | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/script.js b/script.js index 810ac73..ea8297c 100644 --- a/script.js +++ b/script.js @@ -1214,7 +1214,8 @@ class Game { } placeOrbs(template) { - let placer = new RadialOrbPlacer(this, template); + // let placer = new RadialOrbPlacer(this, template); + let placer = new RecursiveOrbPlacer(this, template); 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 */