X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=js%2Findex.js;h=f58a403d42ac7ff2d9590e456b4a664e3efc95b8;hb=8d4d23009371e7ca83e0793185f0ae8485190007;hp=870be76d8b0429c2f1e8f6835d904c82a0b7fd10;hpb=fd4a69e4ea369afb39c01f1207d79b0ab2d4cc8e;p=westcastle.git diff --git a/js/index.js b/js/index.js index 870be76..f58a403 100644 --- a/js/index.js +++ b/js/index.js @@ -9,7 +9,7 @@ new Vue({ props: ['players'], template: `
-
+

Présents

@@ -18,7 +18,7 @@ new Vue({
-
+

Absents

@@ -45,82 +45,28 @@ new Vue({ }, }, }, - 'my-ranking': { - props: ['players'], - data: function() { - return { - sortMethod: "score", - }; - }, - template: ` -
-
- - - - - - - - - - - - -
RangJoueurScorePdT
{{ p.rank }}{{ p.prenom }} {{ p.nom }}{{ p.score }}{{ p.pdt }}
-
- `, - computed: { //TODO: first sort on score, then on Pdt (and reciprocally) --> function add fraction relative Pdt / score (compute min max first, take care of 0 case) - sortedPlayers: function() { - let sortFunc = this.sortMethod == "score" - ? this.sortByScore - : this.sortByPdt; - let res = this.players - .map( p => { return Object.assign({}, p); }) //to not alter original array - .sort(sortFunc); - // Add rank information (taking care of ex-aequos) - let rank = 1; - for (let i=0; i
- -
Nouvelle ronde +

Table {{ index+1 }}

- +
{{ players[i].prenom }} {{ players[i].nom }}{{ pdts[index][j] }}{{ sessions[index][j] }}
@@ -137,12 +83,18 @@ new Vue({ {{ players[tables[currentIndex][i]].prenom }} {{ players[tables[currentIndex][i]].nom }} - + -
- - +
+ + +
+
+ Attention: un score a déjà été enregistré. + Les points indiqués ici s'ajouteront : il faut d'abord + restaurer l'état précédent. + Si c'est déjà fait, ignorer ce message :)
@@ -152,7 +104,7 @@ new Vue({ // Simple case first: 4 by 4 let tables = []; let currentTable = []; - let ordering = _.shuffle(_.range(this.players.length)); //TODO: take scores into account? + let ordering = _.shuffle(_.range(this.players.length)); for (let i=0; i { return []; }); //empty scores - this.pdts = tables.map( t => { return []; }); //empty pdts - }, - shuffle: function() { - this.doPairings(); + this.sessions = tables.map( t => { return []; }); //empty sessions + this.scored = tables.map( t => { return false; }); //nothing scored yet + this.currentIndex = -1; //required if reset while scoring }, showScoreForm: function(table,index) { - if (this.scores[index].length > 0) - return; //already scored - this.scores[index] = _.times(table.length, _.constant(0)); - this.pdts[index] = _.times(table.length, _.constant(0)); + if (this.sessions[index].length == 0) + this.sessions[index] = _.times(table.length, _.constant(0)); this.currentIndex = index; }, setScore: function() { - let sortedPdts = this.pdts[this.currentIndex] - .map( (s,i) => { return {value:s, index:i}; }) - .sort( (a,b) => { return parseInt(b.value) - parseInt(a.value); }); - let scores = [4, 2, 1, 0]; //TODO: ex-aequos ?! - for (let i=0; i { return {value:parseInt(s), index:i}; }) + .sort( (a,b) => { return b.value - a.value; }); + let pdts = [4, 2, 1, 0]; + // NOTE: take care of ex-aequos (spread points subtotal) + let curSum = 0, curCount = 0, start = 0; + for (let i=0; i<4; i++) { - this.players[this.tables[this.currentIndex][sortedPdts[i].index]].score += scores[i]; - this.players[this.tables[this.currentIndex][i]].pdt += parseInt(this.pdts[this.currentIndex][i]); + // Update pdts: + curSum += pdts[i]; + curCount++; + if (i==3 || sortedSessions[i].value > sortedSessions[i+1].value) + { + let pdt = curSum / curCount; + for (let j=start; j<=i; j++) + this.players[this.tables[this.currentIndex][sortedSessions[j].index]].pdt += pdt; + curSum = 0; + curCount = 0; + start = i+1; + } + // Update sessions: + this.players[this.tables[this.currentIndex][i]].session += parseInt(this.sessions[this.currentIndex][i]); } + this.scored[this.currentIndex] = true; this.currentIndex = -1; this.writeScoreToDb(); }, - resetScore: function() { - this.scores[this.currentIndex] = []; - this.pdts[this.currentIndex] = []; - this.currentIndex = -1; + clickRestore: function() { + document.getElementById('restoreBtn').click(); + }, + }, + }, + 'my-timer': { + data: function() { + return { + time: 0, //remaining time, in seconds + running: false, + }; + }, + template: ` +
+
+ {{ formattedTime }} +
+ +
+ `, + computed: { + formattedTime: function() { + let seconds = this.time % 60; + let minutes = Math.floor(this.time / 60); + return this.padToZero(minutes) + ":" + this.padToZero(seconds); + }, + divHeight: function() { + return screen.height; }, - writeScoreToDb: function() - { + divWidth: function() { + return screen.width; + }, + }, + methods: { + padToZero: function(a) { + if (a < 10) + return "0" + a; + return a; + }, + pauseResume: function() { + this.running = !this.running; + if (this.running) + this.start(); + }, + reset: function(e) { + this.running = false; + this.time = 5400; //1:30 + }, + start: function() { + if (!this.running) + return; + if (this.time == 0) + { + new Audio("sounds/gong.mp3").play(); + this.running = false; + return; + } + setTimeout(() => { + if (this.running) + this.time--; + this.start(); + }, 1000); + }, + }, + created: function() { + this.reset(); + }, + }, + 'my-ranking': { + props: ['players','sortByScore','writeScoreToDb'], + template: ` +
+ + + + + + + + + + + + + +
RangJoueurPointsMini-pts
{{ p.rank }}{{ p.prenom }} {{ p.nom }}{{ p.pdt }}{{ p.session }}
+
+ + +
+
+ `, + computed: { + sortedPlayers: function() { + let res = this.rankPeople(); + // Add rank information (taking care of ex-aequos) + let rank = 1; + for (let i=0; i { + p.pdt = 0; + p.session = 0; + p.available = 1; + }); + this.writeScoreToDb(); + document.getElementById("runPairing").click(); + }, + restoreLast: function() { let xhr = new XMLHttpRequest(); - xhr.open("POST", "scripts/rw_players.php"); - xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - let orderedPlayers = this.players - .slice(1) //discard "Toto" - .map( p => { return Object.assign({}, p); }) //deep (enough) copy - .sort( (a,b) => { return b.score - a.score; }); - xhr.send("players="+encodeURIComponent(JSON.stringify(orderedPlayers))); + let self = this; + xhr.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) + { + let players = JSON.parse(xhr.responseText); + if (players.length > 0) + { + players.unshift({ //add ghost 4th player for 3-players tables + prenom: "Toto", + nom: "", + pdt: 0, + session: 0, + available: 0, + }); + // NOTE: Vue warning "do not mutate property" if direct self.players = players + for (let i=1; i { - p.score = !!p.score ? parseInt(p.score) : 0; - p.pdt = !!p.pdt ? parseInt(p.pdt) : 0; + p.pdt = !!p.pdt ? parseFloat(p.pdt) : 0; + p.session = !!p.session ? parseInt(p.session) : 0; p.available = !!p.available ? p.available : 1; //use integer for fputcsv PHP func }); players.unshift({ //add ghost 4th player for 3-players tables prenom: "Toto", nom: "", - score: 0, pdt: 0, + session: 0, available: 0, }); self.players = players; @@ -261,4 +361,19 @@ new Vue({ xhr.open("GET", "scripts/rw_players.php", true); xhr.send(null); }, + methods: { + // Used both in ranking and pairings: + sortByScore: function(a,b) { + return b.pdt - a.pdt + (Math.atan(b.session - a.session) / (Math.PI/2)) / 2; + }, + writeScoreToDb: function() { + let xhr = new XMLHttpRequest(); + xhr.open("POST", "scripts/rw_players.php"); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + let orderedPlayers = this.players + .slice(1) //discard Toto + .sort(this.sortByScore); + xhr.send("players="+encodeURIComponent(JSON.stringify(orderedPlayers))); + }, + }, });