A priori, programmer un morpion, c'est quelque chose d'assez simple, mais là le TP nous impose une façon de faire et j'avoue ne pas vraiment la comprendre....Pour ma part j'aurais plutôt essayer de faire ça en utilisant un tableau, ici je me perd dans tout ce que l'on fait car je ne vois pas comment l'ensemble va se construire ni comment la procédure principale devra marcher.
(JE m'excuse pour la longueur du message, j'aurais bien utiliser la fonction spoil pour cacher les lignes de code et raccourcir le pavé mais elle semble ne pas être disponible sur le forum...)
========================================================
Je ne sais pas si ça à un rapport direct mais la programmation du morpion, mais voilà ce que l'on bous a faire fait
Une procédure qui permet de tracer une valeur entière qui prend en argument une chaine de caractère donnant le nom de la variable et un entier donnant sa valeur
- Code: Tout sélectionner
procedure TraceVarInt (val:In Integer;x:In string) is
begin
put("variable ");put(x);put("=");put(val);
new_line;
end TraceVarInt;
Une procédure qui réalise la même chose mais qui met en pause tant que l'utilisateur n'appuies pas sur une valeur du clavier.
- Code: Tout sélectionner
procedure TraceVarIntPause (val:In Integer;x:In string) is
varPause:Integer;
begin
put("variable ");put(x);put("=");put(val);
new_line;
put("Pause: Entrez un entier pour reprendre");new_line;
get(varPause); --stoppe le prgme tant qu'une valeur n'est pas entrée
end TraceVarIntPause;
Une procédure qui petmet de saisir une valeur au clavier qui prend en argument un message d'invitation à la saisie et une variable entière pour stocker la saisie. La procédure affiche le message et saisit la variable
- Code: Tout sélectionner
procedure saisirInt (x:In string) is
val:Integer;
begin
put(x);
get(val);
end saisirInt;
Une procédure qui afficher une valeur entière précédée d'un message, elle prend en argument une chaine de caractère et la valeur à afficher
- Code: Tout sélectionner
procedure putStringInt(x:In string;val:Integer) is
begin
put(x);put(" vaut ");put(val);
end putStringInt;
======================================================
Ensuite commence la véritable partie du morpion
======================================================
La première partie consiste en l'affichage de la grille.
Je dois écrire une procédure qui affiche le bord supérieur de la grille et de même pour le bord inférieur.
- Code: Tout sélectionner
procedure afficherBordSuperieur is
begin
put(" ^^^^^^^");new_line;
end afficherBordSuperieur;
procedure afficherBordInferieur is
begin
put(" vvvvvvv");new_line;
end afficherBordInferieur;
On considère que le contenu dune case de la grille est représenté par une valeur
entière : 0 si la case est vide, 1 si la case est occupée par un pion du joueur 1 et 2 si la case est
occupée par un pion du joueur 2. Selon le pion occupant une case, on fait le choix dafficher à
lécran une croix (X) pour le joueur 1 et un rond (O) pour le joueur 2.
Écrivez une procédure afficherLigne qui prend en argument trois entiers pour représenter le
contenu des cases de la ligne de la gauche vers la droite et affiche cette ligne à lécran.
- Code: Tout sélectionner
procedure afficherLigne (x,y,z:Integer) is
begin
if(x=0) then
put("");
elsif(z = 1) then
put("X >");
else
put("0 >");
end if;
new_line;
end afficherLigne;
Une procédure qui va afficher la séparation entre les lignes de cases
- Code: Tout sélectionner
procedure afficherSeparationLigne is
begin
put("");
new_line;
end afficherSeparationLigne;
Pour laffichage de la grille, on va considérer maintenant que le
contenu des 9 cases de la grille est représenté par un entier de 9 chiffres, dont
chaque chiffre peut être 0 (case vide), 1 (case occupée par le joueur 1) ou 2 (case
occupée par le joueur 2). Ainsi, la grille affichée ci-contre est représentée par
lentier 001210201 (mais cela ne sert à rien de chercher la correspondance !).
Ecrivez la procédure afficherGrille qui prend en argument une grille sous la forme
dun entier. Pour ceci, vous utiliserez la procédure fournie extraireLigne (grille,
numLigne : in Integer; case1, case2, case3 : out Integer) qui retourne les valeurs
des 3 cases de la ligne numLigne de gauche à droite, sachant que la ligne du bas
porte le numéro 1, la ligne du milieu le numéro 2 et la ligne du haut le numéro 3.
^^^^^
vvvvv
C'est donc à ce niveau là que je bloque, je n'arrive pas à mettre en relation tout ce que l'on à fait et je ne vois pas comment obtenir le programme final du morpion.
Je vous met la suite du TP, ainsi que les fonctions que l'on nous a donné en annexes, je crois que cest surtout le fait que je ne comprenne pas comment marchent ces fonctions qui me perturvent le plus.
Ecrivez donc une procédure enregistrerCaseChoisie qui prend en argument une
grille (un entier) à mettre à jour et un numéro de joueur numJoueur (un autre entier).
Le comportement de la procédure consiste à demander au joueur numJoueur de choisir la case
dans laquelle il veut mettre sa marque, à vérifier que cette case est vide (sinon il faut lui demander
de choisir une nouvelle case) puis à ajouter la marque dans la grille.
Pour cela, on considère que chaque case est repérée par les chiffres 1 à 9 du pavé numérique du
clavier (7 étant la case supérieure gauche et 3 la case inférieure droite). Vous utiliserez les procédures fournies caseDejaOccupee(grille, lig, col : Integer) qui dit si la case de la ligne numéro
lig et de la colonne numéro col est déjà occupée ou pas et ajouterMarque(grille : in out Integer;
marque, lig, col : in Integer) qui met à jour la grille pour la case de coordonnées (lig, col) au moyen
de la marque 1 pour le joueur 1 et de la marque 2 pour le joueur 2. Attention, il vous faudra convertir
le numéro de touche du pavé numérique (entre 1 et 9) en un couple de coordonnées (lig, col)
sachant que la ligne 1 est celle des touches 1 à 3 et que la première colonne est celle des touches
1, 4, 7.
Ecrivez le programme principal qui affiche initialement une grille vide puis, tant que
la partie nest pas terminée, fait jouer alternativement chacun des 2 joueurs et affiche la grille
actualisée. Le programme affiche également le résultat de la partie quand le jeu est terminé. Vous
utiliserez ici la fonction grilleVide qui retourne un entier correspondant à une grille vide et la fonction
ilYAUnGagnant(grille : Integer) qui retourne 1 ou 2 selon que le joueur 1 ou le joueur 2 a gagné, ou
0 sinon.
ET voilà toutes les fonctions annexes que je pourrais avoir besoin d'utiliser.
- Code: Tout sélectionner
function grilleVide return Integer is
-- retourne une grille vide
begin
return 0;
end grilleVide;
procedure extraireLigne(grille, numLigne : in Integer;
case1, case2, case3 : out Integer) is
-- retourne les valeurs des 3 cases de la ligne extraite
i : Integer := numLigne; -- indice de boucle sur les lignes
tempo : Integer := grille;
ligne : Integer; -- entier de 3 chiffres correspondant à une ligne
begin
while (i > 1) loop
tempo := tempo / 1000;
i := i - 1;
end loop;
ligne := tempo mod 1000;
case1 := ligne mod 10;
ligne := ligne / 10;
case2 := ligne mod 10;
ligne := ligne / 10;
case3 := ligne;
end extraireLigne;
procedure extraireColonne(grille, numCol : in Integer;
case1, case2, case3 : out Integer) is
-- retourne les valeurs des 3 cases de la colonne extraite
i : Integer; -- indice de boucle sur les colonnes
tempo : Integer := grille;
ligne : Integer; -- entier de 3 chiffres correspondant à une ligne
begin
ligne := tempo mod 1000;
i := numCol;
while (i > 1) loop
ligne := ligne / 10;
i := i - 1;
end loop;
case3 := ligne mod 10;
tempo := tempo / 1000;
ligne := tempo mod 1000;
i := numCol;
while (i > 1) loop
ligne := ligne / 10;
i := i - 1;
end loop;
case2 := ligne mod 10;
ligne := tempo / 1000;
i := numCol;
while (i > 1) loop
ligne := ligne / 10;
i := i - 1;
end loop;
case1 := ligne mod 10;
end extraireColonne;
procedure extraireDiagonale(grille, numDiag : in Integer;
case1, case2, case3 : out Integer) is
-- retourne les valeurs des 3 cases de la diagonale extraite
-- numDiag doit être 1 ou -1
i : Integer; -- indice de boucle sur les colonnes
tempo : Integer := grille;
ligne : Integer; -- entier de 3 chiffres correspondant à une ligne
begin
ligne := tempo mod 1000;
if numDiag = 1
then i := 1;
else i := 3;
end if;
while (i > 1) loop
ligne := ligne / 10;
i := i - 1;
end loop;
case3 := ligne mod 10;
tempo := tempo / 1000;
ligne := tempo mod 1000;
i := 2;
while (i > 1) loop
ligne := ligne / 10;
i := i - 1;
end loop;
case2 := ligne mod 10;
ligne := tempo / 1000;
if numDiag = 1
then i := 3;
else i := 1;
end if;
while (i > 1) loop
ligne := ligne / 10;
i := i - 1;
end loop;
case1 := ligne mod 10;
end extraireDiagonale;
procedure ajouterMarque(grille : in out Integer; marque, lig, col : in Integer) is
-- ajouter dans la grille le symbole associé au joueur 1
-- dans la case de coordonnées (lig, col).
valMAJ : Integer;
begin
putStringInt("Le joueur ", marque);
put(" a joué en ");
putStringInt("(",lig);
putStringInt(",",col);
put(").");
new_line;
valMAJ := marque * (1000 ** (lig - 1)) * (10 ** (col - 1));
grille := grille + valMAJ;
end ajouterMarque;
function caseDejaOccupee(grille, lig, col : Integer) return boolean is
estOccupee : Boolean;
begin
-- traceVarIntPause("modulo",(3 * (lig -1) + (col - 1)));
estOccupee := (grille / (10 ** (3 * (lig -1) + (col - 1)))) mod 10 /= 0;
-- traceVarBool("estOccupee", estOccupee);
return estOccupee;
end CaseDejaOccupee;
function ilYAUnGagnant(grille : Integer) return Integer is
-- il y a un gagnant si toutes les cases d'une ligne sont égales
-- ou si toutes les cases d'une colonne sont egales ou
-- si toutes les diagonales d'une case sont egales.
indice : Integer; -- indice de parcours des lignes, colonnes ou diag
gagne : Boolean := false;
rep, case1, case2, case3 : Integer;
begin
-- inspecter les lignes
indice := 1;
while not gagne and (indice < 3) loop
extraireLigne(grille, indice, case1, case2, case3);
gagne := (case1 = case2) and (case2 = case3) and (case1 /= 0);
rep := case1;
indice := indice + 1;
end loop;
-- traceVarBool("gagne lignes", gagne);
-- putStringInt("rep",rep);
-- inspecter les colonnes
indice := 1;
while not gagne and (indice < 3) loop
extraireColonne(grille, indice, case1, case2, case3);
gagne := (case1 = case2) and (case2 = case3) and (case1 /= 0);
rep := case1;
indice := indice + 1;
end loop;
-- traceVarBool("gagne colonnes", gagne);
-- putStringInt("rep",rep);
-- inspecter les diagonales
indice := -1;
while not gagne and (indice < 2) loop
extraireDiagonale(grille, indice, case1, case2, case3);
gagne := (case1 = case2) and (case2 = case3) and (case1 /= 0);
rep := case1;
indice := indice + 2;
end loop;
-- traceVarBool("gagne diag", gagne);
-- putStringInt("rep",rep);
-- donner le résultat
if gagne
then return rep;
else return 0;
end if;
end ilYAUnGagnant;
Merci à tous pour votre aide.