Animating a recursive backtracking algorithm in javascript -
i'm trying create live demo of backtracking algorithm (with simple forward checking) in javascript. i've gotten algorithm down pat in recursive form, i'm stuck trying animate using javascript's settimeout
or setinterval
, i'm assuming require me convert recursive solution iterative one. here's function (rewritten little more general):
function solve(model) { if (model.issolved()) return true; var chosen = choosevariable(model); //could random or least constrained var domain = model.getdomain(chosen); var i, assn; (i = 0; < domain.length; i++) { assn = domain[i]; model.set(chosen, assn); if (solve(model)) return true; else model.undo(); } return false; }
as can see, i've made model can undo it's own actions, rather having separate action stack or cloning model @ each level of recursion. there way convert function above 1 used settimeout
or setinterval
? have change model/add stack keep track of chosen variable/attempted assignments? need closure mutating variables? i'm looking pseudocode point me in right direction.
i'm assuming require me convert recursive solution iterative one.
no, right other way round. yours still iterative in parts (the for
-loop).
you have make steps asynchronous, each step takes callback fired when animation done , can continue. since want animate every single iteration step, have make them asynchronous recursive-like callback - continuation passing style.
here's how:
function solve(model, callback) { if (model.issolved()) return callback(true); var chosen = choosevariable(model); // random or least constrained var domain = model.getdomain(chosen); var = 0, assn; (function nextstep() { if (i < domain.length) { assn = domain[i]; model.set(chosen, assn); solve(model, function(solved) { if (solved) callback(true); else { model.undo(); i++; nextstep(); } }); } else callback(false); })(); }
now can make recursive variant asynchronous introducing settimeout
need (usually after displaying model
state):
function solve(model, callback) { if (model.issolved()) return callback(true); var chosen = choosevariable(model); // random or least constrained var domain = model.getdomain(chosen); var = 0, assn; (function nextstep() { if (i < domain.length) { assn = domain[i]; model.set(chosen, assn); solve(model, function(solved) { if (solved) callback(true); else { model.undo(); i++; settimeout(nextstep, 100); } }); } else settimeout(callback, 100, false); })(); }
Comments
Post a Comment