Program morpion;

Const Taille_grille = 3;
   Nb_align            = 3;
                    
Type t_indice_grille = 1..Taille_grille;
   t_pion             = 0..2;
   t_grille             = Array[t_indice_grille,t_indice_grille] of t_pion;
                     



Function grille_vide(): t_grille;
var i,j          : integer;
   grille : t_grille;
begin          
   for i:=1 to Taille_grille do
      for j:=1 to Taille_grille do
         grille[i][j] := 0;
   grille_vide := grille;
end



Procedure affichage(grille : t_grille);
var i,j        : integer;

begin
   for i:=1 to Taille_grille do
      write('+---');
   writeln('+');
   for i:=1 to Taille_grille do
   begin
      for j:=1 to Taille_grille do
      begin
         case grille[i][j] of
           0 : write('|   ');
           1 : write('| X ');
           2 : write('| O ');
         end;
      end;
      writeln('|');
      for j:=1 to Taille_grille do
         write('+---');
      writeln('+');
   end;
end;



Function Test_ligne_horiz(g : t_grille; l,c,j:integer):boolean;
var b : boolean;
   i  : integer;
begin
   if ((c+Nb_align-1>Taille_grille) or (l>Taille_grille)) then
      begin
         {writeln('erreur');}
         Test_ligne_horiz:=false;
      end
      else
      begin
         b:=true;
         for i:=0 to Nb_align-1 do
            if g[l][c+i] <> j then b:=false;
         Test_ligne_horiz:=b;
      end;
end

Function Test_ligne_vert(g : t_grille; l,c,j:integer):boolean;
var b : boolean;
   i  : integer;
begin
   if ((l+Nb_align-1>Taille_grille) or (c>Taille_grille)) then
      begin
         {writeln('erreur');}
         Test_ligne_vert:=false;
      end
      else
      begin
         b:=true;
         for i:=0 to Nb_align-1 do
            if g[l+i][c] <> j then b:=false;
         Test_ligne_vert:=b;
      end;
end

Function Test_diag_montante(g : t_grille; l,c,j:integer):boolean;
var b : boolean;
   i  : integer;
begin
   if ((l-Nb_align+1<0) or (c+Nb_align-1>Taille_grille)) then
      begin
         {writeln('erreur');}
         Test_diag_montante:=false;
      end
      else
      begin
         b:=true;
         for i:=0 to Nb_align-1 do
            if g[l-i][c+i] <> j then b:=false;
         Test_diag_montante:=b;
      end;
end

Function Test_diag_descendante(g : t_grille; l,c,j:integer):boolean;
var b : boolean;
   i  : integer;
begin
   if ((l+Nb_align-1>Taille_grille) or (c-Nb_align+1>Taille_grille)) then
      begin
         {writeln('erreur');}
         Test_diag_descendante:=false;
      end
      else
      begin
         b:=true;
         for i:=0 to Nb_align-1 do
            if g[l+i][c+i] <> j then b:=false;
         Test_diag_descendante:=b;
      end;
end

Function Test_reussite(g : t_grille;j:integer):boolean;
var b  : boolean;
   c,l : integer;
begin
   b:=false;
   l:=1;
   c:=1;
   repeat
      b:= (Test_ligne_horiz(g,l,c,j) or Test_ligne_vert(g,l,c,j) or
      Test_diag_descendante(g,l,c,j) or Test_diag_montante(g,l,c,j));
      if l<Taille_grille then l:=l+1 else begin l:=1; c:=c+1; end;
   until ((b=true) or (c=Taille_grille+1));
   Test_reussite:=b;
end;
   


Procedure Ajout_pion(var g : t_grille; l,c,j:integer);
begin
   if ((l<=Taille_grille) and (c<=Taille_grille)  and (g[l][c] = 0))
      then g[l][c]:=j;
end



Procedure Saisie_pion(var g : t_grille; j:integer);
var l,c        : integer;
begin
   repeat
   write('Joueur ',j,' : coordonnees (ligne, colonne):');
   readln(l,c);
   until ((l<=Taille_grille) and (c<=Taille_grille) and (g[l][c] = 0));
   Ajout_pion(g,l,c,j);
end;



Var n          : integer;
   grille : t_grille;

begin
   n:=0;
   grille := grille_vide();
   
   while ((n<Taille_grille*Taille_grille) and (not test_reussite(grille,1))
          and (not test_reussite(grille,2))) do
   begin
      saisie_pion(grille,n mod 2 + 1);
      affichage(grille);
      n:=n+1;
   end;
   If test_reussite(grille,1) then
      writeln('Joueur 1 a gagné !')
   else if test_reussite(grille,2) then
      writeln('Joueur 2 a gagné !')
   else writeln('Match nul');
end.