-
@@ -110,10 +110,10 @@ new Vue({
-
+
Enregistrer
-
+
Annuler
Fermer
@@ -122,7 +122,95 @@ new Vue({
`,
methods: {
+ // TODO: télécharger la ronde courante
+ // TODO: mémoriser les appariements passés pour éviter que les mêmes joueurs se rencontrent plusieurs fois
+ // --> dans la base: tableau rounds, rounds[0] : {tables[0,1,...], chacune contenant 4 indices de joueurs; + sessions[0,1,...]}
+ // --> devrait séparer les components en plusieurs fichiers...
+ // cas à 5 joueurs : le joueur exempt doit tourner (c'est fait automatiquement en fait)
+ cancelRound: function() {
+ this.scored.forEach( (s,i) => {
+ if (s)
+ {
+ // Cancel this table
+ this.currentIndex = i; //TODO: clumsy. funcions should take "index" as argument
+ this.resetScore();
+ }
+ });
+ this.currentIndex = -1;
+ this.doPairings();
+ },
doPairings: function() {
+ let rounds = JSON.parse(localStorage.getItem("rounds"));
+
+ if (this.scored.some( s => { return s; }))
+ {
+ this.commitScores(); //TODO: temporary: shouldn't be here... (incremental commit)
+ if (rounds === null)
+ rounds = [];
+ rounds.push(this.tables);
+ }
+
+ // 1) Compute the "meeting" matrix: who played who and how many times
+ let meetMat = _.range(this.players.length).map( i => {
+ _.range(this.players.length).map( j => {
+ return 0;
+ });
+ });
+ rounds.forEach( r => { //for each round
+ r.forEach( t => { //for each table within round
+ for (let i=0; i<4; i++) //TODO: these loops are ugly
+ {
+ for (let j=0; j<4; j++)
+ {
+ if (j!=i)
+ meetMat[i][j]++;
+ }
+ }
+ });
+ });
+
+ // 2) Pre-compute tables repartition (in numbers): depends on active players count % 4
+ let activePlayers = this.players
+ .map( (p,i) => { return Object.Assign({}, p, {index:i}); })
+ .filter( p => { return p.available; });
+ let repartition = _.times(Math.floor(activePlayers.length/4), _.constant(4));
+ switch (activePlayers.length % 4)
+ {
+ case 1:
+ // Need 2 more
+ if (repartition.length-1 >= 2)
+ {
+ repartition[0]--;
+ repartition[1]--;
+ repartition[repartition.length-1] += 2;
+ }
+ break;
+ case 2:
+ // Need 1 more
+ if (repartition.length-1 >= 1)
+ {
+ repartition[0]--;
+ repartition[repartition.length-1]++;
+ }
+ break;
+ }
+
+ // 3) Sort people by total games played (increasing) - naturally solve the potential unpaired case
+ let totalGames = _.range(this.players.length).map( i => { return 0; });
+ rounds.forEach( r => {
+ r.forEach(t => {
+ t.forEach( p => {
+ totalGames[p]++;
+ })
+ })
+ });
+ let sortedPlayers = activePlayers
+ .map( (p,i) => { return Object.Assign({}, p, {games:totalGames[p.index]}); })
+ .sort( (a,b) => { return a.games - b.games; });
+
+ // 4) Affect people on tables, following total games sorted order (with random sampling on ex-aequos)
+ // --> et surtout en minimisant la somme des rencontres précédentes (ci-dessus : cas particulier rare à peu de joueurs)
+//TODO
// Simple case first: 4 by 4
let tables = [];
let currentTable = [];
@@ -233,13 +321,17 @@ new Vue({
return {
time: 0, //remaining time, in seconds
running: false,
+ initialTime: 90, //1h30, in minutes
+ setter: false,
+ setterTime: 0, //to input new initial time
};
},
template: `
-
+
{{ formattedTime }}
+
`,
@@ -257,6 +349,11 @@ new Vue({
},
},
methods: {
+ setTime: function() {
+ this.initialTime = this.setterTime;
+ this.setter = false;
+ this.reset();
+ },
padToZero: function(a) {
if (a < 10)
return "0" + a;
@@ -269,7 +366,7 @@ new Vue({
},
reset: function(e) {
this.running = false;
- this.time = 5400; //1:30
+ this.time = this.initialTime * 60;
},
start: function() {
if (!this.running)
@@ -280,6 +377,8 @@ new Vue({
this.running = false;
return;
}
+ if (this.time == this.initialTime)
+ new Audio("sounds/gong.mp3").play(); //gong at the beginning
setTimeout(() => {
if (this.running)
this.time--;
@@ -288,8 +387,27 @@ new Vue({
},
},
created: function() {
+ this.setterTime = this.initialTime;
this.reset();
},
+ mounted: function() {
+ let timer = document.getElementById("timer");
+ let keyDict = {
+ 32: () => { this.setter = true; }, //Space
+ 27: () => { this.setter = false; }, //Esc
+ };
+ document.addEventListener("keyup", e => {
+ if (timer.style.display !== "none")
+ {
+ let func = keyDict[e.keyCode];
+ if (!!func)
+ {
+ e.preventDefault();
+ func();
+ }
+ }
+ });
+ },
},
'my-ranking': {
props: ['players','sortByScore','commitScores'],