Hey !
Du coup tu as une solution assez simple (>= 1.14) en passant par les NBT !
Dans l'idée :
- Tu crées un storage dans lequel tu places un tableau vide que l'on nommera "Vote"
- Tu attribues un nombre (UID) à chaque joueur compris entre 0 et nombre de joueur - 1 de façon à ce que chaque joueur est un id différent
- Tu remplies ton tableau "Vote" d'autant de tableau vide qu'il y a de joueurs
Lorsqu'une personne vote pour quelqu'un :
- Tu récupères l'id de la personne pour qui le joueur courant à voté
- Tu places l'id du joueur courant dans le tableau dont l'index est l'id du joueur pour qui la personne à voté
Pour savoir qui a le plus de vote :
- Tu fais un "execute store result score" avec pour commande un "data get storage [nom du storage] Vote", ça aura pour effet de te retourner le nombre d'éléments qu'il y a dans le tableau (et donc le nombre de joueurs ayant voté pour la personne dont l'index est son id)
Pour retirer un joueur des tableaux de vote :
- Tu cherches la valeur dans tous les sous-tableaux de "Vote" puis tu la supprimes
Avantage :
- Simple et élégant
- Flexible pour autant de joueurs que l'on veut
Faiblesse :
- Assez coûteux en nombre de boucle pour parcourir les tableaux, bien que tout peut s'exécuter sur 1 seul tick
C'est la solution la plus élégante je trouve, mais je peux t'en proposer une autre qui ne se base que sur un scoreboard (ou deux pour stocker les UID) :
L'idée est de se baser sur les propriétés des nombres premiers.
Initialisation :
- Tu attribues à chaque joueur un UID qui est un nombre premier (2, 3, 5, 7, 11, 13, 17, 23, ...)
Pour les votes :
- Tu définis le score de chaque joueur à 0
- Pour chaque personne qui vote pour X, tu multiplies le score de X par l'id de la personne votant
Savoir qui gagne le vote :
- Celui qui a le score le plus gros
Annuler le vote d'une personne :
- Les nombres premiers ont une particularité, ils ne sont divisibles par aucun nombre outre 1 et eux-même. Le produit de 2 nombres premiers n'est donc divisibles que par ces deux nombres premiers. De façon plus généralisé, le produit de N nombre premier n'est divisible que par ces N nombres premiers.
On se base donc sur cela pour annuler le vote : si la personne n'a voté que pour une personne, il n'existe qu'un seul score étant divisible par l'id de la personne en question. Il suffit donc de faire le test suivant sur tous les scores S à partir de l'id I : S % I = 0 ? Si c'est le cas, alors le score est divisible entièrement par I et donc pour peut diviser S par I de façon à annuler le vote, si non, on continue à chercher.
Avantage :
- Léger
- Entièrement calculatoire
Faiblesse :
- On ne peut pas récupérer facilement le nombre de vote pour une personne, bien que l'on peut tenter de le modulo du score par tous les id que l'on a, puis compter le nombre de réussite
- Tous les joueurs ne peuvent pas voter pour une même personne : le produit des 12 premiers nombres premiers à pour résultat ~4*10^12 ce qui est largement plus grand que la capacité d'un scoreboard : ~2*10^9
Une dernière solution qui se rapproche un peu de celle utilisant les nombres premiers, c'est de passer par les nombres de la base de 2 :
Initialisation :
- Tu attribues à chaque joueur un UID appartenant à la base de 2 (1, 2, 4, 8, 16, 32, 64...) de façon à ce que, pour 12 joueurs, le dernier joueur est l'id 2^11 et le premier 2^0
Pour les votes :
- Même système que le précédent, sauf que tu additionnes au lieu de multiplier
Savoir qui gagne le vote :
- Celui qui se décompose en le plus de facteurs de 2. Pour cela, petit algorithme :
Code:
entier max
entier nb1
pour tout score S :
copier score S dans S'
entier compteur = 0
tant que S' != 0 :
si S' % 2 == 1 :
compteur = compteur + 1
S' = S' / 2
si compteur > nb1 :
max = S
nb1 = compteur
retourner (max, nb1)
Dans cet algorithme, max est donc le score du joueur ayant le plus de vote, et nb1 le nombre de personne ayant voté pour.
Si tu ne comprends pas comment cela fonctionne, on peut se pencher du côté du binaire :
À chaque fois que tu ajoutes un nombre de la base de 2 à un nombre quelconque ne possédant pas ce nombre de la base de 2, tu ajoutes un "1" dans son nombre binaire, par exemple : 3 + 4 = 7 ce qui se traduit par : 11 + 100 = 111, on a donc bien un 1 de plus que notre nombre initial (11).
Pour savoir le nombre de joueurs, il suffit donc de compter le nombre de 1, et pour cela, il faut vérifier que le nombre inclu bien la puissance de 2 en question. On divise donc en boucle le nombre par 2 jusqu'à ce que celui-ci valle 0, et on compte au passage le nombre de fois où l'on n'arrive pas à le diviser entièrement (Donc le nombre de fois où le modulo par 2 vaut 1).
Annuler un vote :
- Un peu plus compliqué que les deux autres sytèmes, il faut reprendre l'algorithme du dessus, mais tu ajoutes une variable V initialisée à 2^11 (2048), puis à chaque fois que tu divises S' par 2, tu divises aussi cette variable par 2. Ainsi, si S' % 2 = 1 lorsque V vaut l'id de la personne dont tu veux annuler le vote, alors cette personne à voté pour le titulaire du score S, tu as juste à faire S - le score du votant donc.
Avantage :
- Calculatoire
- Fonctionne pour un grand nombre de joueur (jusqu'à 30 ou 31)
Faiblesse :
- Est plus compliqué à mettre en place
- Demande pas mal de calculs
Voilà pour les 3 systèmes que je peux te proposer ! Il y en a sans doute plein d'autres et des plus optimisés, mais ce sont ceux qui me sont venu à l'idée à la lecture du ta question.
On peut les résumer ainsi : Soit tu passes par une structure de données, soit tu codes le résultat des votes.