Algorithmique impérative/Tas de billes

Algorithmique impérative
PyQt
PyQt
Sommaire
Théorie de l'algorithmique impérative
  1. Qu'est ce qu'un algorithme impératif Fait à environ 50 %
  2. Les types, les opérateurs et les expressions Fait à environ 50 %
  3. Les constantes, les variables Fait à environ 50 %
  4. Les instructions, les blocs d'instructions Fait à environ 50 %
  5. L'assignation Fait à environ 50 %
  6. Les exécutions conditionnelles Fait à environ 50 %
  7. Les structures itératives Fait à environ 50 %
  8. Les tableaux Fait à environ 50 %
  9. Les procédures et les fonctions Ébauche
  10. Le type enregistrement Fait à environ 50 %
  11. L'algorithme au final : vue d'ensemble En cours
  12. Exercices En cours
Outils de travail
Problèmes posés, analysés, résolus et commentés
Annexes
Modifier ce modèle ce sommaire

Problématique

modifier

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

Analyse approfondie

modifier

Solution

modifier

Trouver un algorithme pour ce jeu n'est pas aussi évident qu'il y parait.

Implémentation en Pascal

modifier
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.