-
Notifications
You must be signed in to change notification settings - Fork 0
/
RoundRobin.js
112 lines (94 loc) · 3.19 KB
/
RoundRobin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
"use strict";
const War = require("./war.js");
const Player = require("./Player.js");
const Stats = require("./Stats.js");
/**
* Create object to run a round robin season schedule and game results
* See here for more details on round-robin tournaments:
* https://en.wikipedia.org/wiki/Round-robin_tournament
*/
function RoundRobin(players) {
this.roster = players;
this.schedule = [];
}
/**
* Round-robin
*/
RoundRobin.prototype.play = function () {
const numberOfPlayers = this.roster.length;
const evenTeams = numberOfPlayers % 2 == 0;
//Extra slot needed when there is an odd number of teams
const numberOfSlots = evenTeams ? numberOfPlayers : numberOfPlayers + 1;
let slots = [];
for (let i = 0; i < numberOfSlots; i++) {
//First slot is for blank slot, competitor gets a bye
let value = evenTeams ? i : i - 1;
slots.push(value);
}
//Ignore the first game of every week its a bye
let start = evenTeams ? 0 : 1;
for (let week = 0; week < slots.length - 1; week++) {
for (let i = start; i < slots.length / 2; i++) {
const playerOneIndex = slots[i];
const playerTwoIndex = slots[slots.length - (1 + i)];
const game = new War(2, 1);
game.deal();
const winner = game.play() == 0 ? playerOneIndex : playerTwoIndex;
const gameTransitions = Stats.getLeaderTransistions(game.hands);
const gameID = this.schedule.length;
this.schedule.push({
id: gameID,
week: week,
player1: this.roster[playerOneIndex].fullName,
player2: this.roster[playerTwoIndex].fullName,
winner: winner,
hands: game.hands,
});
this.roster[playerOneIndex].games.push({
id: gameID,
playerNo: 0,
opponent: this.roster[playerTwoIndex].fullName,
win: winner == playerOneIndex,
hands: game.hands.length,
playerHands: gameTransitions.handsPerPlayer[0],
opponentHands: gameTransitions.handsPerPlayer[1],
tiedHands: gameTransitions.handsPerPlayer[2],
});
this.roster[playerTwoIndex].games.push({
id: gameID,
playerNo: 1,
opponent: this.roster[playerOneIndex].fullName,
win: winner == playerTwoIndex,
hands: game.hands.length,
playerHands: gameTransitions.handsPerPlayer[1],
opponentHands: gameTransitions.handsPerPlayer[0],
tiedHands: gameTransitions.handsPerPlayer[2],
});
this.roster[winner].wins += 1;
}
slots.splice(1, 0, slots.pop());
}
this.ratePlayers();
};
/**
* Rate players based on number of wins,
* Wins are adjusted for game length (longer games are worth less)
*/
RoundRobin.prototype.ratePlayers = function () {
const maxNumberofHands = this.schedule.reduce((max, game) => {
return Math.max(max, game.hands.length);
}, 0);
for (let i = 0; i < this.roster.length; i++) {
const rating = this.roster[i].games
.filter((game) => {
return game.win;
})
.reduce((total, game) => {
const gameObject = this.schedule[game.id];
let gameRating = (3 - gameObject.hands.length / maxNumberofHands) / 3;
return total + gameRating;
}, 0);
this.roster[i].rating = rating;
}
};
module.exports = RoundRobin;