Algorithmique impérative/Tas de billes
Apparence
Problématique
[modifier | modifier le wikicode]On cherche à implémenter un jeu dont voici les règles :
Règles du jeu :
- On commence avec un tas de billes, le jeu se joue à deux,
- Les joueurs jouent l'un après l'autre,
- Chaque joueur, à son tour, peut retirer une, deux, ou trois billes du tas,
- Le joueur qui prend la dernière bille a perdu.
En plus d'implémenter le mécanisme du jeu, on veillera à respecter les consignes suivantes :
- Au lancement, le programme rappelle les règles du jeu énoncées ci-dessus.
- Le contenu du tas de départ est demandé au lancement. Si le nombre donné est 0 ou moins, on prend un nombre aléatoire entre 10 et 30 et on l'annonce.
- Les deux joueurs entreront leurs noms en début de partie.
- À chaque tour, le programme rappelle à qui est le tour, en appelant les joueurs par leurs noms. Pour qu'on voie que le tour à passé, l'affichage est vidé des informations et saisies du tour précédent.
- À chaque tour, le programme rappelle combien il reste de billes dans le tas et donne une représentation graphique s'il reste moins de 30 billes (afficher sur une seule ligne un '.' par bille restante fera amplement l'affaire).
- Le programme gère les tentatives de triche et rappelle les règles si nécessaire.
- À la fin du jeu, le gagnant est désigné par son nom.
Première analyse
[modifier | modifier le wikicode]Analyse approfondie
[modifier | modifier le wikicode]Solution
[modifier | modifier le wikicode]Trouver un algorithme pour ce jeu n'est pas aussi évident qu'il y parait.
Implémentation en Pascal
[modifier | modifier le wikicode]program billes;
var
nb_billes : integer; (* le nombre de billes dans le tas *)
coup : integer; (* nombre de billes à retirer lors d'un tour*)
tour : boolean; (* vrai si c'est le tour du joueur 1 *)
joueur1, joueur2 : string; (* noms des joueurs *)
i : integer; (* variable de boucle *)
begin
(* Affichage des règles *)
writeln('Règles du jeu :');
writeln('* On commence avec un tas de billes, le jeu se joue à deux.');
writeln('* Les joueurs jouent l''un après l''autre.');
writeln('* Chaque joueur, à son tour, peut retirer une, deux, ou trois billes du tas.');
writeln('* Le joueur qui prend la dernière bille a perdu.');
(* Recueil des informations nécessaires au jeu *)
writeln('Donner le nom du joueur 1 : ');
readln(joueur1);
writeln('Donner le nom du joueur 2 : ');
readln(joueur2);
writeln('Donner le nombre de billes : ');
readln(nb_billes);
(* gestion du nombre de billes *)
if (nb_billes <= 0) then begin
nb_billes := 10+random(20); (* random(n) renvoie un nombre entre 0 et n *)
writeln('Un nombre aléatoire est pris : ',nb_billes);
end;
(* on démarre à false, ainsi c'est le joueur 1 qui jouera en premier *)
tour := false;
repeat
(* nettoyer l'écran, un appel de clsrc() peut fonctionner également *)
for i:=1 to 20 do writeln();
(* on change le joueur à qui est le tour *)
tour := not(tour);
(* on indique à qui est le tour *)
write('C''est au tour de ');
if (tour) then writeln(joueur1) else writeln(joueur2);
(* affichage (textuel et graphique) du nombre de billes restant *)
writeln('Il reste ',nb_billes,' billes. ');
if (nb_billes <= 30) then for i:= 1 to nb_billes do write('.');
writeln();
(* demande au joueur son coup , gestion de la triche *)
writeln('Combien retirez-vous de billes ?');
readln(coup);
while ((coup < 1) or (coup > 3) or (coup > nb_billes)) do begin
writeln('Tricheur !');
writeln('* On ne peut retirer qu''entre une et trois billes.');
writeln('* On ne peut plus de billes qu''il n''y en a.');
writeln('Combien retirez-vous de billes ?');
readln(coup)
end;
(* on a le coup voulu, on le joue *)
nb_billes := nb_billes - coup
until (nb_billes = 0);
(* c'est le joueur qui a joué en dernier qui est perdant *)
(* on inverse pour indiquer le gagnant *)
if (not(tour)) then write(joueur1) else write(joueur2);
writeln(' gagne !');
end.