Skip to content

Commit

Permalink
changed results storage
Browse files Browse the repository at this point in the history
  • Loading branch information
slashinfty committed Apr 6, 2021
1 parent 06bb399 commit 4b569ac
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 24 deletions.
52 changes: 36 additions & 16 deletions lib/Tiebreakers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,69 @@ const Tiebreakers = {
/**
* Computes all tiebreakers for a player.
* @param {Player} p The player being processed.
* @param {Number} wv The value of a win.
* @param {Number} lv The value of a loss.
* @param {Number} dv The value of a draw.
* @param {Tournament} t The current tournament.
*/
compute: (p, wv, lv, dv) => {
compute: (p, t) => {
const calcCumulative = player => {
let score = 0;
let running = 0;
player.results.forEach(r => {
let inc = r.result === 'w' ? wv : r === 'd' ? dv : lv;
let inc = r.result === 'w' ? t.winValue : r === 'd' ? t.drawValue : t.lossValue;
score += inc;
running += score;
});
return running;
};
const calcMatchWin = (player, type) => {
let mwp = player.matchPoints / (wv * (player.results.length + player.byes));
let mwp = player.matchPoints / (t.winValue * (player.results.length + player.byes));
if (type === 'magic') return mwp < 0.33 ? 0.33 : mwp;
else return mwp < 0.25 ? 0.25 : mwp;
};
const calcGameWin = player => {
let gwp = player.gamePoints / (wv * (player.results.length + player.byes));
let gwp = player.gamePoints / (t.winValue * (player.results.length + player.byes));
return gwp < 0.33 ? 0.33 : gwp;
};
const oppScores = p.results.map(a => a.opponent.matchPoints);
const oppScores = p.results.map(a => {
const o = t.players.find(x => x.id === a.opponent);
return o.matchPoints;
});
p.tiebreakers.solkoff = oppScores.reduce((x, y) => x + y, 0);
oppScores.splice(oppScores.indexOf(Math.min(...oppScores)), 1);
p.tiebreakers.cutOne = oppScores.reduce((x, y) => x + y, 0);
oppScores.splice(oppScores.indexOf(Math.max(...oppScores)), 1);
p.tiebreakers.median = oppScores.reduce((x, y) => x + y, 0);
let neustadtlScore = 0;
p.results.forEach((r, i) => neustadtlScore += r === 'w' ? p.results[i].opponent.matchPoints : r === 'd' ? 0.5 * p.results[i].opponent.matchPoints : 0);
p.results.forEach((r, i) => {
const op = t.players.find(x => x.id === r.opponent);
if (r.result === 'w') neustadtlScore += op.matchPoints;
else if (r.result === 'd') neustadtlScore += 0.5 * op.matchPoints;
});
p.tiebreakers.neustadtl = neustadtlScore;
p.tiebreakers.cumulative = calcCumulative(p);
p.tiebreakers.oppCumulative = p.results.reduce((x, y) => x + calcCumulative(y.opponent), 0);
p.tiebreakers.oppCumulative = p.results.reduce((x, y) => {
const op = t.players.find(z => z.id === y.opponent);
x + calcCumulative(op)
}, 0);
p.tiebreakers.matchWinPctM = calcMatchWin(p, 'magic');
p.tiebreakers.matchWinPctP = calcMatchWin(p, 'pokemon');
p.tiebreakers.gameWinPct = calcGameWin(p);
p.tiebreakers.oppMatchWinPctM = p.results.reduce((x, y) => x + calcMatchWin(y.opponent, 'magic'), 0) / p.results.length;
p.tiebreakers.oppMatchWinPctP = p.results.reduce((x, y) => x + calcMatchWin(y.opponent, 'pokemon'), 0) / p.results.length;
p.tiebreakers.oppGameWinPct = p.results.reduce((x, y) => x + calcGameWin(y.opponent), 0) / p.results.length;
p.tiebreakers.oppMatchWinPctM = p.results.reduce((x, y) => {
const op = t.players.find(z => z.id === y.opponent);
return x + calcMatchWin(op, 'magic');
}, 0) / p.results.length;
p.tiebreakers.oppMatchWinPctP = p.results.reduce((x, y) => {
const op = t.players.find(z => z.id === y.opponent);
return x + calcMatchWin(op, 'pokemon');
}, 0) / p.results.length;
p.tiebreakers.oppGameWinPct = p.results.reduce((x, y) => {
const op = t.players.find(z => z.id === y.opponent);
return x + calcGameWin(op);
}, 0) / p.results.length;
let oppOppMatchSum = 0;
p.results.forEach(r => oppOppMatchSum += r.opponent.results.reduce((x, y) => x + calcMatchWin(y.opponent, 'pokemon'), 0) / r.length);
p.results.forEach(r => oppOppMatchSum += r.opponent.results.reduce((x, y) => {
const op = t.players.find(z => z.id === y.opponent);
return x + calcMatchWin(op, 'pokemon')
}, 0) / r.length);
p.tiebreakers.oppOppMatchWinPct = oppOppMatchSum / p.results.length;
},
/**
Expand Down Expand Up @@ -111,8 +131,8 @@ const Tiebreakers = {
* @type {Object}
*/
versus: {
equal: (a, b) => a.results.filter(m => m.opponent.id === b.id).every(m => m.result === 'd'),
diff: (a, b) => a.results.filter(m => m.opponent.id === b.id).reduce((x, y) => x += y.result === 'w' ? -1 : y.result === 'l' ? 1 : 0, 0)
equal: (a, b) => a.results.filter(m => m.opponent === b.id).every(m => m.result === 'd'),
diff: (a, b) => a.results.filter(m => m.opponent === b.id).reduce((x, y) => x += y.result === 'w' ? -1 : y.result === 'l' ? 1 : 0, 0)
},
/**
* Contains equality and difference functions for the Magic: the Gathering tiebreakers.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tournament-organizer",
"version": "1.2.2",
"version": "1.3.0",
"description": "JavaScript library for running tournaments",
"main": "./src/index",
"scripts": {
Expand Down
4 changes: 2 additions & 2 deletions src/Match.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ class Match {
this.playerTwo.gamePoints += this.playerTwoWins * wv + this.draws * dv;
this.playerOne.games += this.playerOneWins + this.playerTwoWins + this.draws;
this.playerTwo.games += this.playerOneWins + this.playerTwoWins + this.draws;
let playerOneResult = {match: this.id, opponent: this.playerTwo};
let playerTwoResult = {match: this.id, opponent: this.playerOne};
let playerOneResult = {match: this.id, opponent: this.playerTwo.id};
let playerTwoResult = {match: this.id, opponent: this.playerOne.id};
if (this.playerOneWins > this.playerTwoWins) {
this.playerOne.matchPoints += wv;
playerOneResult.result = 'w';
Expand Down
2 changes: 1 addition & 1 deletion src/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class Player {
this.byes = 0;

/**
* Array of results. Objects include match ID, opponent, and result ('w', 'l', or 'd').
* Array of results. Objects include match ID, opponent ID, and result ('w', 'l', or 'd').
* @type {Object[]}
*/
this.results = [];
Expand Down
8 changes: 4 additions & 4 deletions src/Tournament.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class Tournament {
* @return {Player[]}
*/
standings(active = true) {
this.players.forEach(p => Tiebreakers.compute(p, this.winValue, this.lossValue, this.drawValue));
this.players.forEach(p => Tiebreakers.compute(p, this));
let thesePlayers = active ? this.players.filter(p => p.active) : [...this.players];
thesePlayers.sort((a, b) => {
for (let i = 0; i < this.tiebreakers.length; i++) {
Expand Down Expand Up @@ -386,7 +386,7 @@ class Swiss extends Tournament {
newMatches = this.activeMatches();
}
}
this.players.forEach(p => Tiebreakers.compute(p, this.winValue, this.lossValue, this.drawValue));
this.players.forEach(p => Tiebreakers.compute(p, this));
return newMatches;
}
}
Expand Down Expand Up @@ -613,7 +613,7 @@ class RoundRobin extends Tournament {
newMatches = this.activeMatches();
}
}
this.players.forEach(p => Tiebreakers.compute(p, this.winValue, this.lossValue, this.drawValue));
this.players.forEach(p => Tiebreakers.compute(p, this));
return newMatches;
}

Expand All @@ -624,7 +624,7 @@ class RoundRobin extends Tournament {
* @return {Player[]}
*/
groupStandings(group, active = true) {
group.forEach(p => Tiebreakers.compute(p, this.winValue, this.lossValue, this.drawValue));
group.forEach(p => Tiebreakers.compute(p, this));
let thesePlayers = active ? group.filter(p => p.active) : [...group];
thesePlayers.sort((a, b) => {
for (let i = 0; i < this.tiebreakers.length; i++) {
Expand Down

0 comments on commit 4b569ac

Please sign in to comment.