Skip to content

Commit

Permalink
unscorable was too strict when re-scoring matches that dropped on LB …
Browse files Browse the repository at this point in the history
…matches with WO markers (smarter _safe virtual now) - fixes #6
  • Loading branch information
clux committed Jan 3, 2015
1 parent 3c09d65 commit a59f97d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,7 @@
3.0.1 / 2015-01-03
==================
* Fix bug in `_safe` implementation which made `unscorable` too strict when not having full access (#6 via @a5sk4s)

3.0.0 / 2014-10-11
==================
* Bump tournament to 3.0.0 for better serialization via `::state` and `.restore`
Expand Down
18 changes: 12 additions & 6 deletions duel.js
Expand Up @@ -323,12 +323,18 @@ Duel.prototype._verify = function (m, score) {
};

Duel.prototype._safe = function (m) {
var rres = this.right(m.id)
, dres = this.down(m.id)
, rm = rres && this.findMatch(rres[0])
, dm = dres && this.findMatch(dres[0]);
// safe to re-score iff no direct dependents are scored
return !(rm && rm.m) && !(dm && dm.m);
// ensure matches [right, down, down ∘ right] are all unplayed (ignoring WO)
var r = this.right(m.id)
, d = this.down(m.id)
, rm = r && this.findMatch(r[0])
, dm = d && this.findMatch(d[0])
, dr = dm && this.right(dm.id) // right from down
, drm = dr && this.findMatch(dr[0]);

return [rm, dm, drm].every(function (next) {
// safe iff (match not there, or unplayed, or contains WO markers)
return !next || !next.m || next.p[0] === WO || next.p[1] === WO;
});
}

Duel.prototype._early = function () {
Expand Down
36 changes: 36 additions & 0 deletions test/duel.extras.test.js
Expand Up @@ -28,3 +28,39 @@ exports.noDraws = function (t) {
t.ok(!d.score(d.matches[0].id, [1,1]), "not allowed");
t.done();
};

exports.safePropagation = function (t) {
var d = new Duel(5, { last: 2 });

// cannot score the WO matches in WBR1
t.ok(d.unscorable({ s: 1, r: 1, m: 1 }, [1, 0]), 'WBR1 WO matches');
t.ok(d.unscorable({ s: 1, r: 1, m: 3 }, [1, 0]), 'WBR1 WO matches');
t.ok(d.unscorable({ s: 1, r: 1, m: 4 }, [1, 0]), 'WBR1 WO matches');
// but can score the non-WO match
t.ok(d.score({ s: 1, r: 1, m: 2 }, [0, 1]), 'WBR1 non-wo match');
// and should be fine to rescore without allowpast
// despite this match having WO dependant (played) match in LBR1
t.equal(null, d.unscorable( { s: 1, r: 1, m: 2 }, [1, 0]), 'WBR1 safe');

// score WBR2
d.score({ s: 1, r: 2, m: 1 }, [1, 0]);
d.score({ s: 1, r: 2, m: 2 }, [1, 0]);
// so WBR1 is now unsafe
t.ok(d.unscorable( { s: 1, r: 1, m: 2 }, [1, 0]), 'WBR1 unsafe now');

// WBR2 also has a match that drops on top of a WO match - check it is safe
t.equal(null, d.unscorable({ s: 1, r: 2, m: 2 }, [0, 1]), 'WBR2 safe');

// score LBR2 match so LBR3 is ready (requires relevant WBR2 played)
d.score({s:2, r: 2, m: 1}, [1, 0]);

// score LBR3 match that is ready via WO progressor from WBR2 via LBR2
d.score({s:2, r: 3, m: 1}, [1, 0]);

// at this point - we can see that WBR3 is unplayed, yet it is unsafe
// to re-score WBR2 because it's loser has fought a match PAST its
// immediate descendant match (thus _safe checks deeper)
t.ok(d.unscorable({ s: 1, r: 2, m: 2 }, [0, 1]), 'WBR2 unsafe now');

t.done();
};

0 comments on commit a59f97d

Please sign in to comment.