Créer vos feuilles de tournoi avec jQuery Bracket

Magazine
Marque
Linux Pratique
HS n°
Numéro
44
|
Mois de parution
février 2019
|
Domaines


Résumé

Lorsque l’on organise des tournois, il est souvent intéressant de mettre les résultats en ligne et de pouvoir les modifier aisément. Dans cet article, nous allons utiliser la librairie jQuery Bracket pour publier des feuilles de tournoi. Nous ajouterons aussi notre propre code pour rendre l’utilisation de la librairie plus facile.


Body

 

resultat

 

Figure 1

1. Préparation de la page HTML

 

menu

 

Figure 2

Nous allons utiliser la librairie jQuery Bracket dont le site se trouve à l’adresse suivante : http://www.aropupu.fi/bracket/ [1]

Préparons notre environnement de travail et récupérons les librairies dont nous avons besoin :

$ mkdir tournoi

$ mkdir php
$ cd js
$ wget https://code.jquery.com/jquery-3.3.1.min.js
$ wget https://raw.githubusercontent.com/teijo/jquery-bracket/master/dist/jquery.bracket.min.js
$ touch tournoi.js
$ cd ../css
$ wget https://raw.githubusercontent.com/teijo/jquery-bracket/master/dist/jquery.bracket.min.css
$ cd ..

Cela nous donne donc la structure suivante (commande tree) :

.

├──css

│ └──jquery.bracket.min.css

├──index.html

├──js

│ ├──jquery-3.3.1.min.js

│ ├──jquery.bracket.min.js

│ └──tournoi.js

└──php

Tout est prêt, créons maintenant notre page HTML index.html :

01: <!DOCTYPE html>

03: <head>

04: <title>jQuery Bracket</title>

05: <meta charset="UTF-8">

06: <meta name="viewport" content="width=device-width, initial-scale=1.0">

07: <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>

08: <script type="text/javascript" src="js/jquery.bracket.min.js"></script>

09: <script type="text/javascript" src="js/tournoi.js"></script>

10: <link rel="stylesheet" type="text/css" href="css/jquery.bracket.min.css" />

11: </head>

12: <body>

13: <input type="text" id="participant" placeholder="Participant">

14: <button id="ajouter">Ajouter</button><br><br>

15: <button id="vider">Vider</button>

16: <button id="aleatoire">Tirage au sort + équilibrage</button>

17: <button id="enregistrer">Enregistrer</button>

18: <div id="tournoi"></div>

19: </body>

20: </html>

Voici les explications des lignes les plus importantes :

 

Lignes

Explication

7,8,9

Déclaration des librairies que nous utiliserons dans notre projet. Tout d’abord, la librairie jquery-3.3.1.min.js est un prérequis à la seconde librairie jquery.bracket.min.js (c’est la librairie qui nous intéresse). Pour finir, notre programme principal tounois.js qui pour le moment est vide.

13

Zone de texte permettant d’ajouter un joueur à notre tournoi.

14

Bouton permettant d’ajouter le joueur à notre tournoi.

15

Bouton permettant de réinitialiser notre feuille de tournoi.

16

Bouton permettant une fois tous les joueurs saisis de faire un tirage aléatoire.

17

Bouton permettant d’enregistrer notre feuille de tournoi.

18

Zone où sera affichée notre feuille de tournoi.

2. Affichage d’une feuille de tournoi

 

01

 

Figure 3

Tout d’abord, écrivons un fichier d’exemple pour notre tournoi js/resultats.json :

01: {

02: "teams":[

03: [ "Arnaud", "Sebastien" ],

04: [ "Emmanuel", "Cedric" ],

05: [ "Patrick", null ],

06: [ "Olivier", null ]

07: ],

08: "results":[]

09: }

Nous avons 6 joueurs et pas encore de résultats.

Attaquons-nous au programme principal js/tournoi.js :

01: infos={};

03: function sauver() {} // A suivre...

04: function ajoute_participant() {} // A suivre...

05: function tirage_aleatoire() {} // A suivre...

06: function enregistrer() {} // A suivre...

07: function vider() {} // A suivre…

09: function edit_fn(container, data, doneCb) { }

10: function render_fn(container, data, score, state) {

11: switch(state) {

12: case "empty-bye":

13: return;

14: case "empty-tbd":

15: container.append("à déterminer");

16: return;

17: case "entry-no-score":

18: case "entry-default-win":

19: case "entry-complete":

20: container.append(data);

21: return;

22: }

23: }

24:

25: function affiche_tournoi()

26: {

27: fr={"1st":"1er",

28: "2nd":"2nd",

29: "3rd":"3e",

30: "4th":"4e"};

31:

32: $('#tournoi').bracket(

33: { teamWidth: 90,

34: disableToolbar:true,

35: disableTeamEdit:true,

36: centerConnectors:true,

37: init: infos,

38: save:sauver ,

39: decorator: {edit: edit_fn, render: render_fn}

40: });

41:

42: $(".bubble").each(function(index,element){

43: $(element).html(fr[$(element).html()]);

44: });

45: }

46:

47: $(document).ready(function(){

48: $.ajaxSetup({ cache: false });

49: $.getJSON( "js/resultats.json", function( data ) {

50: infos=data;

51: affiche_tournoi();

52: });

53:

54: $("#ajouter").click(ajoute_participant);

55: $("#aleatoire").click(tirage_aleatoire);

56: $("#enregistrer").click(enregistrer);

57: $("#vider").click(vider);

58: });

Nous allons utiliser une variable globale pour maintenir nos informations de tournoi (i.e. joueurs et scores), il s’agit de la variable infos initialisée à vide en ligne 1.

Des lignes 03 à 07, nous définissons un certain nombre de fonctions que nous développerons plus tard, ici le corps de la fonction est vide pour éviter des erreurs dans la console JavaScript.

2.1 Le programme principal (lignes 47 à 60)

En ligne 47, nous attendons que notre page HTML soit prête (ready) pour exécuter notre programme.
En ligne 48, nous désactivons le cache sur les requêtes AJAX. En effet, les données relatives au tournoi seront stockées dans un fichier externe qui sera modifié régulièrement : resultats.json.
Des lignes 49 à 52, nous effectuons un appel AJAX pour accéder au fichier JSON précédemment cité. La réponse est stockée dans la variable infos, puis l’affichage est déclenché avec la fonction affiche_tournoi décrite plus loin.
Enfin, des lignes 54 à 57 nous associons des fonctions aux clics sur les différents boutons.

2.2 Affichage du tournoi (lignes 25 à 45)

Malheureusement, jQuery Bracket ne connaît pas le français, il faut donc faire quelques adaptations pour lui apprendre la langue. Des lignes 27 à 30, nous créons notre tableau de conversion anglais vers français. Nous nous servirons de ce tableau en lignes 42 à 44. Dans ces lignes, nous récupérons tous les éléments de la page HTML de la classe bubble et pour chaque élément trouvé nous effectuons la traduction.

 

langue

 

Figure 4

Les lignes 32 à 40 nous permettent d’afficher notre feuille de tournoi. Voici plus de détails :

 

Lignes

Explication

33

Élargissement de la largeur d’affichage des noms (certains prénoms dépassaient de la zone).

34

Désactivation de la barre d’outils incluse dans jQuery Bracket. (nous utiliserons la nôtre).

35

Désactivation de l’édition des noms saisis. Notre outil permettra d’ajouter des noms.

36

Centrage des connexions entre les différentes cases.

37

Informations à afficher, nous utiliserons notre variable globale infos.

38

Déclaration de la fonction à appeler lorsque l’on saisit un score dans le tableau, ici sauver.

39

Utilisation des fonctions permettant de personnaliser le visuel.

2.3 Personnalisation de l’affichage (lignes 9 à 23)

En ligne 9, la fonction edit_fn permet de personnaliser l’édition d’un score. Ici, nous ne voulons pas de personnalisation, nous allons donc laisser la fonction vide.

En ligne 10, la fonction render_fn permet de personnaliser le contenu des cases :

 

Ligne

Valeur par défaut

Remplacé par :

12

BYE

vide

15

TBD

« à déterminer »

 

langue_cases

 

Figure 5

3. Menu personnalisé

Les fonctions que nous allons déclarer dans cette section remplaceront les fonctions vides du fichier tournois.js.

3.1 Vider la feuille de tournoi

Voici le code permettant de vider la feuille de tournoi :

01: function vider() {

02: infos={"teams":[], "results":[]};

03: affiche_tournoi();

04: }

La fonction est très simple, on vide la liste des joueurs ainsi que les résultats et on réaffiche.

3.2 Ajouter un joueur

Voici le code permettant de rajouter un joueur à la feuille de tournoi :

01: function liste_participants() {

02: return infos.teams.flat().filter(function (el) {

03: return el !== null;

04: });

05: }

06:

07: function ajoute_participant() {

08: if ((infos.results.length !== 0) || ($("#participant").val()==="")) return;

09: if (infos.teams.length===0) {

10: infos.teams.push([$("#participant").val(),null]);

11: } else {

12: var participants=liste_participants();

13:

14: participants.push($("#participant").val());

15: var racine_2=Math.ceil(Math.log2(participants.length));

16:

17: var complement=Math.pow(2,racine_2)-participants.length;

18: for (i=0;i<complement;i++) {

19: participants.push(null);

20: }

21:

22: var retour=[];

23: for (i=0;i<participants.length;i=i+2) {

24: retour.push([participants[i],participants[i+1]]);

25: }

26:

27: infos.teams=retour;

28: }

29: affiche_tournoi();

30: $("#participant").val("");

31: }

 

Le problème principal de la librairie jQuery Bracket est qu’elle ne fonctionne qu’avec un nombre de joueurs étant un carré : 2n. Nous allons donc créer un programme qui accepte n’importe quel nombre de joueurs.

De la ligne 01 à 05, on crée la fonction liste_participants qui a pour but de créer une liste de participants à partir de la liste jQuery Bracket, exemple :

         [["Arnaud","Sebastien"],["Emmanuel","Cedric"],["Patrick",null],["Olivier",null]]
flat =>   ["Arnaud","Sebastien", "Emmanuel","Cedric", "Patrick",null, "Olivier",null]
filter => ["Arnaud","Sebastien", "Emmanuel","Cedric", "Patrick", "Olivier" ]

Examinons maintenant la fonction ajoute_participant :

 

Lignes

Explication

08

Dans le cas où il y a déjà des scores ou qu’il n’y a pas de nom à ajouter, on ne fait rien.

09,10

Si la liste est vide, créonsuneliste composéed’un joueur : [["nom_joueur",null]].

12

Création d’une liste simple avec tous les joueurs : participants.

14

Ajout du joueur saisi dans le formulaire à la fin de la liste participants.

15

Calcul de la valeur racine_2 tel que 2racine_2 ≥ nb(participants) > 2racine_2-1.

17

Calcul du nombre de joueurs manquants pour obtenir une puissance de 2 : complement.

18,19

Complément de la liste des joueurs avec des null à l’aide du complement.

22 à 25

Création d’une liste compréhensible par jQuery Bracket.

27

Mise à jour de la variable globale infos.teams.

29

Affichage de la feuille de tournoi pour tenir compte des modifications.

30

Suppression du nom du joueur dans le formulaire pour éviter les doublons.

Voici un exemple d’exécution :

Ligne 12 => ["Arnaud","Sebastien", "Emmanuel","Cedric", "Patrick","Olivier"]

Ligne 19 => ["Arnaud","Sebastien", "Emmanuel","Cedric", "Patrick","Olivier", null,null]

Ligne 27 => [["Arnaud","Sebastien"],["Emmanuel","Cedric"],["Patrick","Olivier"],[null,null]]

3.3 Tirage au sort des matchs

Attaquons-nous maintenant au code permettant de tirer au sort les différents matchs du tournoi :

01: function shuffle(a) {

02: var j, x, i;

03: for (i = a.length - 1; i > 0; i--) {

04: j = Math.floor(Math.random() * (i + 1));

05: x = a[i];

06: a[i] = a[j];

07: a[j] = x;

08: }

09: return a;

10: }

11:

12: function tirage_aleatoire()

13: {

14: if (infos.results.length !== 0) return;

15: var participants=liste_participants();

16: participants=shuffle(participants);

17:

18: var retour=[];

19: var nb_matchs=infos.teams.length;

20:

21: for (i=0;i<nb_matchs;i++)

22: {

23: if(participants[i+nb_matchs]) {

24: retour.push([participants[i],participants[i+nb_matchs]]);

25: } else {

26: retour.push([participants[i],null]);

27: }

28: }

29: infos.teams=retour;

30: affiche_tournoi();

31: }

En ligne 1, la fonction shuffle permet de mélanger les éléments d’un tableau JavaScript. Le code provient du site StackOverflow [2].

En ligne 12, la fonction tirage_aleatoire nous permet le tirage au sort des différents matchs. Voyons plus en détail son fonctionnement :

 

Lignes

Explication

14

S’il y a déjà des scores, il est impossible de modifier les matchs.

15,16

On récupère la liste des participants que l’on mélange aléatoirement à l’aide des fonctions liste_participants et shuffle.

18

Création de la variable qui contiendra le résultat du tirage au sort : retour.

19

Récupération du nombre de matchs dans la variable : nb_matchs.

21 à 28

Création de la feuille de tournoi au format jQuery Bracket (voir exemple après le tableau).

29,30

Enregistrement du résultat dans la variable globale infos et affichage affiche_tournoi().

Voici un exemple de la création de la feuille de tournoi au format jQuery Bracket (lignes 21 à 28) :

0 1 2 3 4 5
participants=["Arnaud","Sebastien","Emmanuel","Cedric","Patrick","Olivier"]
nb_matchs=4
i=0 => retour=[["Arnaud","Patrick"]] indices 0(i) et 4(i+nb_matchs)
i=1 => retour=[["Arnaud","Patrick"],["Sebastien","Olivier"]] indices 1(i) et 5(i+nb_matchs)
i=2 => retour=[["Arnaud","Patrick"],["Sebastien","Olivier"],["Emmanuel",null]]
i=3 => retour=[["Arnaud","Patrick"],["Sebastien","Olivier"],["Emmanuel",null],["Cedric",null]]

3.4 Enregistrer la feuille de tournoi

Voici le code permettant d’enregistrer les modifications de la feuille de tournoi :

1 function sauver(data) {

2 infos=data;

3 affiche_tournoi();

4 }

5

6 function enregistrer() {

7 $.ajax({

8 async:true,

9 type:"POST",

10 url:"/php/enregistre.php",

11 data:JSON.stringify(infos),

12 datatype:"json",

13 success: function(){alert("Enregistrement réussi");},

14 error: function(){alert("Impossible d'enregistrer");}

15 });

16 }

La fonction sauver récupère les données renvoyées par jQuery Bracket et les sauvegarde dans la variable globale infos, ensuite réaffichons la feuille de tournoi.

La fonction enregistrer effectue un POST HTTP sur l’url /php/enregistre.php et passe en argument les infos au format JSON à l’aide de la fonction JSON.stringify.

4. Enregistrer la feuille de tournoi côté serveur

Dans cette section, nous allons implémenter la partie serveur. Dans notre exemple, nous utiliserons PHP.
Cette partie étant en dehors de l’utilisation de la librairie jQuery Backet, nous allons nous contenter d’un « quick & dirty » (« vite fait, mal fait »).

Voici donc le code de php/enregistre.php :

1 <?php

2 /*****************************

3 * ATTENTION A SECURISER !!! *

4 * NE PAS UTILISER EN L'ETAT *

5 *****************************/

6

7 $params = file_get_contents("php://input");

8 $json=json_decode($params, true);

9

10 $file = '../js/resultats.json';

11 file_put_contents($file, $params);

12 ?>

Le programme récupère des données HTTP POST en ligne 7, les convertit au format JSON en ligne 8 et écrit le résultat dans le fichier ../js/reusltats.json en lignes 10 et 11.

Conclusion

 

production

 

Figure 6

Et voilà ! Nous avons créé tout le nécessaire pour pouvoir aisément réaliser notre feuille de tournoi à l’aide de notre formulaire.

Pour aller plus loin, je vous invite à lire la documentation officielle de jQuery Bracket [1], vous y apprendrez par exemple comment :

- personnaliser votre affichage ;

- ajouter une consolante à votre tournoi ;

- créer un tournoi à double élimination.

Pour finir, il ne faudra pas oublier de sécuriser php/enregistrer.php. Vous pourrez par exemple rajouter un accès authentifié et supprimer l’écriture fichier au profit d’un stockage en base de données.

Références

[1] Site officiel de jQuery Bracket : http://www.aropupu.fi/bracket/

[2] Comment mélanger un tableau JavaScript sur le site StackOverflow : https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array

 

Sur le même sujet

Créez une fake webcam pour modifier l'image de vos visioconférences

Magazine
Marque
GNU/Linux Magazine
Numéro
239
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Avec le confinement, le nombre de visioconférences a augmenté de manière exponentielle. Malheureusement, seul Zoom propose de modifier l'arrière-plan de ce que filme votre caméra, masquant ainsi votre capharnaüm. Je vous propose donc d'utiliser Python et OpenCV pour créer un faux périphérique de webcam utilisable avec n'importe quelle application et sur lequel nous pourrons modifier l'image...

Premiers pas avec GDScript et Godot

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
109
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Le langage de scripting par défaut de Godot est le GDScript. Plutôt que de se lancer dans du C# ou encore du Python comme cela est possible, autant utiliser le langage natif du logiciel (surtout quand il s'inspire de Python…).

Écran e-paper NFC : une histoire d'exploration et de code

Magazine
Marque
Hackable
Numéro
34
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Il est difficile de trouver un titre adéquat pour le contenu qui va suivre, car le matériel dont il sera question est tout aussi atypique qu'absolument captivant en termes de fonctionnement. Pire encore, ce n'est pas tant le matériel qui importe que l'approche nécessaire pour obtenir exactement le comportement attendu. Il sera donc ici question de NFC, de papier électronique (e-paper), de C et de la maxime voulant « qu'à cœur vaillant, rien d'impossible ». Sans attendre, embarquez avec moi dans une petite aventure qui, je l'espère, vous apprendra autant qu'elle m'a appris...

À nous, Markdown !

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
109
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Le Markdown est devenu incontournable. Il est facilement manipulable, stockable, versionnable et partageable. Un moteur de rendu automatique peut transformer toute la substantifique moelle de l’auteur en un ouvrage broché digne de la Bible de Gutenberg. Alors, pourquoi ne pas appliquer ce modèle à l’écriture de nouveaux articles pour notre cher magazine ?

Développement ESP32 avec le nouveau ESP-IDF 4.0

Magazine
Marque
Hackable
Numéro
34
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Nous avons précédemment traité du développement sur la fantastique plateforme ESP32, héritière du non moins délectable ESP8266, aussi bien au travers de l'IDE Arduino que via l'environnement de développement créé par le constructeur, Espressif Systems, répondant au doux nom de ESP-IDF. Le 11 février dernier était annoncée la version 4.0 de cet environnement, majoritairement compatible avec la précédente version 3.3.1, mais apportant un lot majeur d'améliorations et quelques changements très intéressants dans le système de construction/compilation. Il est donc temps de revisiter la bête et de tester tout cela...

Par le même auteur

Contrôler vos modèles LEGO Powered Up au Nunchuk à l'aide de votre Arduino

Magazine
Marque
Hackable
Numéro
33
|
Mois de parution
avril 2020
|
Domaines
Résumé

Dans cet article, nous allons voir comment piloter un robot LEGO Powered Up à l’aide d’un Nintendo Nunchuk, grâce à un Arduino. Nous allons installer les librairies nécessaires pour pouvoir piloter notre modèle Powered Up et accéder aux informations du Nunchuk. Nous développerons ensuite notre programme de contrôle en C.

Auto-héberger son agenda avec Baïkal

Magazine
Marque
Linux Pratique
HS n°
Numéro
46
|
Mois de parution
octobre 2019
|
Domaines
Résumé

Il est très utile de pouvoir avoir un calendrier partagé accessible à tout moment sur toute sorte de clients : PC, tablette, téléphone... La solution la plus simple est souvent d’utiliser Google Calendar. Dans cet article, nous allons voir qu’il n’est pas si compliqué d’héberger soi-même un calendrier partagé à l’aide de Baïkal. Nous aborderons l’installation et la configuration de Baïkal. Pour finir, nous découvrirons la configuration des clients Thunderbird, Android et iOS.

Contrôler vos modèles Lego PoweredUp au Joypad à l'aide de votre Raspberry Pi

Magazine
Marque
Hackable
Numéro
30
|
Mois de parution
juillet 2019
|
Domaines
Résumé

Dans cet article, nous allons voir comment piloter un robot Lego PoweredUp à l’aide d’un JoyPad, grâce à un Raspberry Pi. Nous allons installer tout le nécessaire sur notre Raspberry Pi pour pouvoir piloter notre modèle Lego PoweredUp. Nous utiliserons NodeJS, donc le langage JavaScript, pour piloter notre modèle Lego.

Contrôler vos modèles Lego au joypad à l'aide de BrickPi

Magazine
Marque
Hackable
Numéro
29
|
Mois de parution
avril 2019
|
Domaines
Résumé

Dexter Industries propose des cartes d’extension pour Raspberry Pi. Dans cet article, nous allons nous intéresser à la carte BrickPi permettant de piloter les moteurs et senseurs Lego MindStorms. Nous verrons comment piloter notre robot Lego à l’aide d’un joypad. Nous développerons notre programme grâce au langage Python.

Créer vos feuilles de tournoi avec jQuery Bracket

Magazine
Marque
Linux Pratique
HS n°
Numéro
44
|
Mois de parution
février 2019
|
Domaines
Résumé

Lorsque l’on organise des tournois, il est souvent intéressant de mettre les résultats en ligne et de pouvoir les modifier aisément. Dans cet article, nous allons utiliser la librairie jQuery Bracket pour publier des feuilles de tournoi. Nous ajouterons aussi notre propre code pour rendre l’utilisation de la librairie plus facile.