49 lines
1.8 KiB
JavaScript
49 lines
1.8 KiB
JavaScript
function buildMatches(pool) {
|
|
var matches = [];
|
|
for (var index = 0; index < pool.length; index += 2) {
|
|
matches.push({ left: pool[index], right: pool[index + 1] || null, winner: pool[index + 1] ? null : pool[index] });
|
|
}
|
|
return matches;
|
|
}
|
|
|
|
function create(candidates) {
|
|
var pool = candidates.slice();
|
|
return { round: 1, pool: pool, matches: buildMatches(pool), eliminated: [], decisions: [] };
|
|
}
|
|
|
|
function current(state) {
|
|
var match = state.matches.filter(function (item) { return item.right && !item.winner; })[0];
|
|
return match ? [match.left, match.right] : null;
|
|
}
|
|
|
|
function advance(state) {
|
|
if (state.matches.some(function (item) { return !item.winner; })) return false;
|
|
state.pool = state.matches.map(function (item) { return item.winner; });
|
|
if (state.pool.length === 1) return true;
|
|
state.round += 1;
|
|
state.matches = buildMatches(state.pool);
|
|
return false;
|
|
}
|
|
|
|
function chooseAt(state, matchIndex, winner) {
|
|
var match = state.matches[matchIndex];
|
|
if (!match || !match.right || match.winner) throw new Error('invalid bracket match');
|
|
if (winner.id !== match.left.id && winner.id !== match.right.id) throw new Error('winner is not in match');
|
|
var loser = match.left.id === winner.id ? match.right : match.left;
|
|
match.winner = winner;
|
|
state.eliminated.unshift(loser);
|
|
state.decisions.push({ round: state.round, left_id: match.left.id, right_id: match.right.id, winner_id: winner.id });
|
|
return advance(state);
|
|
}
|
|
|
|
function choose(state, winner) {
|
|
var index = state.matches.findIndex(function (item) { return item.right && !item.winner; });
|
|
return chooseAt(state, index, winner);
|
|
}
|
|
|
|
function ranking(state) {
|
|
return state.pool.concat(state.eliminated).map(function (item) { return item.id; });
|
|
}
|
|
|
|
module.exports = { create: create, current: current, choose: choose, chooseAt: chooseAt, ranking: ranking };
|