Jeu de la ronde (2)
Des enfants jouent dans une cour de récréation : ils se placent en rond et choisissent au hasard l'un d'entre eux.
A partir de là, la règle est simple :
-
Le premier enfant tape sur l'épaule de son voisin de gauche : celui-ci est éliminé. Au début l'enfant \(1\) élimine donc l'enfant \(2\) ;
-
On passe à l'enfant restant suivant et l'on recommence : il élimine celui situé à sa gauche. Dans l'exemple, l'enfant \(3\) élimine le \(4\) ;
- On continue encore et encore jusqu'à ce qu'il ne reste plus qu'un seul enfant : c'est le gagnant !
Dans le cas où \(13\) enfants jouent comme sur la figure, le gagnant est l'enfant \(11\).
La question est simple : qui va gagner ?
On représente la ronde des joueurs à l'aide d'une liste chaînée circulaire. Pour ce faire on fournit la classe Joueur possédant deux attributs :
-
le nom du joueur (la chaîne de caractères
nom) ; -
le successeur de ce joueur (attribut
successeurdu typeJoueur).
La fonction nouvelle_ronde prend en paramètre la liste des noms des joueurs triée du premier joueur au dernier et crée la liste chaînée circulaire les représentant. Cette fonction renvoie l'objet représentant le premier joueur.
La fonction affiche_ronde prend en paramètre un objet de type Joueur et renvoie la chaîne de caractères illustrant la ronde débutant par le joueur représenté par cet objet.
>>> noms = ["Riri", "Fifi", "Loulou"]
>>> premier = nouvelle_ronde(noms)
>>> premier.nom
'Riri'
>>> premier.successeur.nom
'Fifi'
>>> affiche_ronde(premier)
╭→ Riri → Fifi → Loulou ╮
╰───────────────────────╯
>>> premier.successeur.successeur.successeur == premier
True
La classe Joueur, la fonction nouvelle_ronde et la fonction affiche_ronde sont déjà chargées dans l'éditeur. Il est inutile de les importer.
La classe Joueur
On fournit pour information la classe Joueur et les fonctions nouvelle_ronde et affiche_ronde :
class Joueur:
def __init__(self, nom, successeur=None):
self.nom = nom
self.successeur = successeur
def nouvelle_ronde(noms):
assert len(noms) > 0, f"La liste noms doit contenir au moins un élément"
premier = Joueur(noms[0])
actuel = premier
for i in range(1, len(noms)):
prochain = Joueur(noms[i])
actuel.successeur = prochain
actuel = prochain
prochain.successeur = premier
return premier
def affiche_ronde(joueur):
noms = [joueur.nom]
actuel = joueur.successeur
while actuel.nom != joueur.nom:
noms.append(actuel.nom)
actuel = actuel.successeur
total = "╭→ " + " → ".join(noms)
return total + " ╮\n╰" + "─" * (len(total)) + "╯"
Écrire la fonction gagnant qui prend en paramètre la liste contenant les noms des joueurs et renvoie le nom du joueur gagnant.
On garantit que la liste est non vide et que les noms des joueurs sont tous distincts.
Exemples
>>> noms = ["Riri", "Fifi", "Loulou"]
>>> gagnant(noms)
'Loulou'
>>> noms = ["Paul", "John", "Ringo", "Georges"]
>>> gagnant(noms)
'Paul'
>>> noms = ["Brian", "Ian", "Mick", "Keith", "Dick"]
>>> gagnant(noms)
'Mick'
# Tests (insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)
# Tests(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)