Je souhaiterais faire suite à un précédent sujet (ici) sans le réouvrir car ma question diffère légèrement.
Pour remettre rapidement dans le contexte, je gère un site qui fait un suivi de parties de jeux de société, les gens entrent des parties avec des scores et ma requête trie les score avec usort pour attribuer des places et des points.
Mon problème est quand il y a une égalité, je souhaiterais attribuer le même nombre de points aux deux joueurs mais le usort trie et donne la meilleure place au joueur qui a le pseudo qui est devant dans l'ordre alphabétique.
Exemple : Steeve 57, Nico 57, Alex 35, Pierre 89 me renvoie Pierre 1er, Nico 2eme, Steeve 3ème, Alex 4ème. Je souhaiterais avoir Pierre 1er, Nico 2eme, Steeve 2ème, Alex 4ème.
Je bloque et ne vois pas comment faire. Voici mon code.
<!-- La connexion -->
<?php include("../include/connexion_bdd.php"); ?>
<?php
//On crée la partie et on récupère son id
$req = $bdd->prepare('INSERT INTO plays_parties (partie_jeu, duree_partie, nb_joueurs, partie_evenement, evenement, date_partie) VALUES(?, ?, ?, ?, ?, NOW())');
$req->execute(array($_POST['id_jeu'], $_POST['duree_partie'], $_POST['nb_joueurs'], $_POST['partie_evenement'], $_POST['evenement']));
//on affiche le dernier ID, ça fonctionne
$lastid = $bdd->lastInsertId();
//On ajoute les détails de la partie dans la table detail
$resultat = $bdd->prepare('INSERT INTO plays_details (detail_partie, detail_joueur, detail_score, detail_place, detail_points, detail_coef, detail_pts_coef) VALUES(?, ?, ?, ?, ?, ?, ?)');
// on fait une boucle sur le nombre de joueurs et on insère la ligne pour chaque joueur.
const POINTS = [
9 => [13, 9, 7, 4, 2, 1, 1, 1, 1],
8 => [13, 9, 7, 4, 2, 1, 1, 1],
7 => [13, 9, 7, 4, 2, 1, 1],
6 => [13, 9, 7, 4, 2, 1],
5 => [12, 8, 6, 4, 1], // quand il y a 5 joueurs, le 1er a un bonus de 13 points, le 2e : 9 points, ...
4 => [11, 7, 5, 1], // pour 4 joueurs, le 1er obtient un bonus de 11 points, le 2e : 7 points, ...
3 => [9, 5, 1],
2 => [5, 1],
];
if (isset($_POST['joueurs']) && is_array($_POST['joueurs']) /* && array_key_exists(count($_POST['joueurs']), BONUS)*/) {
usort(
$_POST['joueurs'],
function ($a, $b) {
return $b['score'] <=> $a['score'];
}
);
foreach ($_POST['joueurs'] as $k => $joueur) {
$resultat->execute([$lastid, $joueur['id_joueur'], $joueur['score'], $k + 1/*place*/, POINTS[count($_POST['joueurs'])][$k], $_POST['duree_partie'], $_POST['duree_partie'] * POINTS[count($_POST['joueurs'])][$k]]);
}
}
// Redirection du visiteur vers la page partie créée
header('Location: partie_enregistree.php');
?>
Cette ligne associe la première place correspondante pour un score donné.
Si je reprends ton exemple (Steeve 57, Nico 57, Alex 35, Pierre 89), ça va donner :
$scores = [
89 => 0, // premier
57 => 1, // deuxième
35 => 3, // quatrième vu qu'on a précédemment 2 ex æquo
];
La clé 2 (troisième) est ignorée/sautée via le ??= parce que 1 (la clé, qui correspond au deuxième) a déjà été attribuée au même score (57), il n'y a pas l'écrasement qu'on aurait eu avec une simple affectation (=)
> Je ne connaissais pas cette possibilité d'ignorer/sauter une clé avec ??=
Ce n'est pas vraiment ça : ??= a pour d'affecter ce qui se trouve à droite si et seulement la variable (à gauche) est NULL (autrement dit, ne pas l'écraser si elle a déjà une valeur et que celle-ci n'est pas NULL) - sinon de ne rien faire/ne pas modifier l'opérande de gauche.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli