X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=js%2Findex.js;h=b51d590dc128dcfff78b4404cec2f19862c4bd38;hb=942ca610ac679dba7ed09c10829d38b29c09bccc;hp=5f1870430d9a59514d354a96c1640d4c2e2c13b1;hpb=d940eb68fd6f58a6f637261854a6da615d087dea;p=westcastle.git diff --git a/js/index.js b/js/index.js index 5f18704..b51d590 100644 --- a/js/index.js +++ b/js/index.js @@ -76,10 +76,10 @@ new Vue({
- -
@@ -110,10 +110,10 @@ new Vue({
- - @@ -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'],