  program othello;

  UNIT NEWPAGE : procedure;
   begin
     write( chr(27), "[2J")
   end newpage;

   UNIT gotoxy : procedure (row, column : integer);
        var c, d, e, f : char,
            i, j : integer;
   begin
     i := row div 10;
     j := row mod 10;
     c := chr (48+i);
     d := chr (48+j);
     i := column div 10;
     j := column mod 10;
     e := chr (48+i);
     f := chr (48+j);
     write (chr(27), "[", c, d, ";", e, f, "H");
   end gotoxy;

  unit Normal : procedure;
  begin
    write( chr(27), "[0m")
  end Normal;

  UNIT INCHAR : IIuwgraph function : integer;
   begin
     do
       i := inkey;
       if i <> 0 then exit fi;
     od;
     result := i;
   end inchar;

  unit pause:procedure(input seconde:integer);
  var temps:integer;
  begin
  for temps:=1 to (9000*seconde) do od;
  end pause;

  unit grille:class;
  var g:arrayof arrayof integer;
  var i:integer;
  begin
   array g dim (1:8);
   for i:=1 to 8
    do
     array g(i) dim (1:8);
    od;
  end grille;

  unit initialisegrille : procedure(inout gr: arrayof arrayof integer);
  var i,j:integer;
  begin
  (* creation de la grille *)
   array gr dim (1:8);
   for i:=1 to 8
    do
     array gr(i) dim (1:8);
    od;
  (* initialisation de la grille *)
  (* 0 case vide *)
  (* 1 case avec pion noir *)
  (* 2 case avec pion blanc *)
   for i:=1 to 8
    do
     for j:=1 to 8
      do
       gr(i,j):=0;
      od;
    od;
(*  for j:=1 to 8 do gr(8,j):=0 od;*)
   gr(4,4):=1;
   gr(5,5):=1;
   gr(4,5):=2;
   gr(5,4):=2;
  end initialisegrille;

unit affichecadre:procedure;
begin
call newpage;
call gotoxy(2,2);
writeln("    1    2    3    4    5    6    7    8   ");
writeln("  ÚÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄ¿");
writeln("1 ³    ³    ³    ³    ³    ³    ³    ³    ³");
writeln("  ÃÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄ´");
writeln("2 ³    ³    ³    ³    ³    ³    ³    ³    ³");
writeln("  ÃÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄ´");
writeln("3 ³    ³    ³    ³    ³    ³    ³    ³    ³");
writeln("  ÃÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄ´");
writeln("4 ³    ³    ³    ³    ³    ³    ³    ³    ³");
writeln("  ÃÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄ´");
writeln("5 ³    ³    ³    ³    ³    ³    ³    ³    ³");
writeln("  ÃÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄ´");
writeln("6 ³    ³    ³    ³    ³    ³    ³    ³    ³");
writeln("  ÃÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄ´");
writeln("7 ³    ³    ³    ³    ³    ³    ³    ³    ³");
writeln("  ÃÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄ´");
writeln("8 ³    ³    ³    ³    ³    ³    ³    ³    ³");
writeln("  ÀÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÙ");
call gotoxy(22,1);
if souris then
writeln("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ");
writeln("³ D‚placement : Souris  ³  Valider : Bouton 1   ³    Quitter : Bouton 3   ³ ");
writeln("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ");
else
writeln("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ");
writeln("³ D‚placement : FlŠches  ³  Valider : RETURN     ³     Quitter : ECHAP    ³ ");
writeln("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ");
fi;

end affichecadre;

  unit affichegrille : procedure(input gr: arrayof arrayof integer);
  (* 0 case vide *)
  (* 1 case avec pion noir *)
  (* 2 case avec pion blanc *)
  var i,j,v,w:integer;
  begin
  v:=4;
   for i:=1 to 8
    do
    w:=5;
     for j:=1 to 8
      do
       if (gr(i,j)=1) then call gotoxy(v,w);write(chr(27),"[33m");
			   writeln("x ");write(chr(27),"[36m");fi;
       if (gr(i,j)=2) then call gotoxy(v,w);write(chr(27),"[32m");
			   writeln("o ");write(chr(27),"[36m");fi;
       w:=w+5;
      od;
      v:=v+2;
    od;
  call gotoxy(v,1);
  end affichegrille;

unit deplace:procedure;
var touche,bidon:integer;
begin
    call gotoxy(xx,yy);
    do
      touche := inchar;
      case touche
           when 50 : if xx<18 then xx:=xx+2;ii:=ii+1 fi;  (*Touche 2*)
           when 52 : if yy>5 then yy:=yy-5;jj:=jj-1 fi;   (*Touche 4*)
           when 54 : if yy<37 then yy:=yy+5;jj:=jj+1 fi;  (*Touche 6*)
           when 56 : if xx>4 then xx:=xx-2;ii:=ii-1 fi;   (*Touche 8*)
	   when 13 : exit;                                (*Touche RC*)
	   when 27 : arreter:=true;exit;                  (*Touche ECHAP*)
      esac;
      call gotoxy(xx,yy);
    od;
 end deplace;

 unit direction:procedure(ligne,colonne:integer;
                           deplacementcolonne,deplacementligne:integer;
                           couleur,invcouleur:integer;
                           tab:arrayof arrayof integer;
                           output nbpion:integer);
  var retourne:boolean;
  begin
   nbpion:=0;
   retourne:=true;
      do
       colonne:=colonne+deplacementcolonne;
       ligne:=ligne+deplacementligne;
       if (colonne=0) or (colonne=9) or (ligne=0) or (ligne=9) then
        (* debordement du tableau *)
        retourne:=false;
        exit;
       fi;

       if (tab(ligne,colonne)=invcouleur) then
        (* case de couleur inverse *)
        nbpion:=nbpion+1;
       fi;

       if (tab(ligne,colonne))=0 then
        (* case vide*)
        retourne:=false;
        exit;
       fi;

       if (tab(ligne,colonne)=couleur) then
        (* case de meme couleur *)
        exit;
       fi;
      od;

      if not(retourne) then nbpion:=0;fi;
  end direction;

unit retourne_pion:procedure(ligne,colonne:integer;
                           deplacementcolonne,deplacementligne:integer;
                           couleur,invcouleur:integer;
                           inout tab:arrayof arrayof integer);
  begin
      do
       colonne:=colonne+deplacementcolonne;
       ligne:=ligne+deplacementligne;

       if (tab(ligne,colonne)=couleur) then
        (* case de meme couleur *)
        exit;
       fi;

       if (tab(ligne,colonne)=invcouleur) then
        (* case de couleur inverse *)
        (* on inverse la couleur *)
        tab(ligne,colonne):=couleur;
       fi;
      od;
  end retourne_pion;

  unit nb_de_pion_a_poser:procedure(input couleur:integer;
                                            input tab:arrayof arrayof integer;
                                            input on_somme_prio:boolean;
                                            output nb_pion_a_poser,som_prio:integer);
  var i,j,nb:integer;
  var on_retourne_pion:boolean;
  begin
   nb_pion_a_poser:=0;
   on_retourne_pion:=false;
   for i:=1 to 8
    do
     for j:=1 to 8
      do
       if tab(i,j)=0 then
call peut_on_poser_pion(i,j,couleur,tab,on_retourne_pion,on_somme_prio,nb,som_prio);
        if nb<>0 then nb_pion_a_poser:=nb_pion_a_poser+1;fi;
        fi;
      od;
    od;
  end nb_de_pion_a_poser;

  unit peut_on_poser_pion:procedure(input ligne,colonne:integer;
                                    input couleur:integer;
                                    input tab:arrayof arrayof integer;
                                    input on_retourne_pion,on_somme_prio:boolean;
                                    output pionretourne,som_prio:integer);
  var nord,sud,ouest,est:boolean;
  var nord_ouest,nord_est,sud_ouest,sud_est:boolean;
  var nbpion,invcouleur,i,j:integer;
  var deplacementcolonne,deplacementligne:integer;
  var prio : integer;
  begin
    prio:=0;
    if (couleur=1) then invcouleur:=2 else invcouleur:=1;fi;
    nord:=true;
    sud:=true;
    ouest:=true;
    est:=true;
    nord_ouest:=true;
    nord_est:=true;
    sud_ouest:=true;
    sud_est:=true;
    if (ligne<=2) then nord:=false;nord_ouest:=false;nord_est:=false;fi;
    if (ligne>=7) then sud:=false;sud_ouest:=false;sud_est:=false;fi;
    if (colonne>=7) then est:=false;sud_est:=false;nord_est:=false;fi;
    if (colonne<=2) then ouest:=false;sud_ouest:=false;nord_ouest:=false;fi;
    pionretourne:=0;
      (* faire chaque direction *)
      if (nord) then deplacementcolonne:=0;
                     deplacementligne:=-1;
                     call direction(ligne,colonne,
                                    deplacementcolonne,deplacementligne,
                                    couleur,invcouleur,tab,nbpion);
                     pionretourne:=pionretourne+nbpion;
                     if (nbpion<>0) and (on_retourne_pion) then
                           call retourne_pion(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab);
                           tab(ligne,colonne):=couleur;
                     fi;
                     if (nbpion<>0) and (on_somme_prio) then
                           call prio_pion_retourne(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab,gr_p,prio);
                           som_prio:=som_prio+prio;
                     fi;
                   fi;

       if (sud) then deplacementcolonne:=0;
                     deplacementligne:=1;
                     call direction(ligne,colonne,
                                    deplacementcolonne,deplacementligne,
                                    couleur,invcouleur,tab,nbpion);
                     pionretourne:=pionretourne+nbpion;
                     if (nbpion<>0) and (on_retourne_pion) then
                           call retourne_pion(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab);
                           tab(ligne,colonne):=couleur;
                     fi;
                     if (nbpion<>0) and (on_somme_prio) then
                           call prio_pion_retourne(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab,gr_p,prio);
                           som_prio:=som_prio+prio;
                     fi;
                   fi;

      if (ouest) then deplacementcolonne:=-1;
                     deplacementligne:=0;
                     call direction(ligne,colonne,
                                    deplacementcolonne,deplacementligne,
                                    couleur,invcouleur,tab,nbpion);
                     pionretourne:=pionretourne+nbpion;
                     if (nbpion<>0) and (on_retourne_pion) then
                           call retourne_pion(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab);
                           tab(ligne,colonne):=couleur;
                     fi;
                     if (nbpion<>0) and (on_somme_prio) then
                           call prio_pion_retourne(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab,gr_p,prio);
                           som_prio:=som_prio+prio;
                     fi;
                   fi;

       if (est) then deplacementcolonne:=1;
                     deplacementligne:=0;
                     call direction(ligne,colonne,
                                    deplacementcolonne,deplacementligne,
                                    couleur,invcouleur,tab,nbpion);
                     pionretourne:=pionretourne+nbpion;
                     if (nbpion<>0) and (on_retourne_pion) then
                           call retourne_pion(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab);
                           tab(ligne,colonne):=couleur;
                     fi;
                     if (nbpion<>0) and (on_somme_prio) then
                           call prio_pion_retourne(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab,gr_p,prio);
                           som_prio:=som_prio+prio;
                     fi;
                   fi;

      if (nord_ouest) then deplacementcolonne:=-1;
                     deplacementligne:=-1;
                     call direction(ligne,colonne,
                                    deplacementcolonne,deplacementligne,
                                    couleur,invcouleur,tab,nbpion);
                     pionretourne:=pionretourne+nbpion;
                     if (nbpion<>0) and (on_retourne_pion) then
                           call retourne_pion(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab);
                           tab(ligne,colonne):=couleur;
                     fi;
                     if (nbpion<>0) and (on_somme_prio) then
                           call prio_pion_retourne(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab,gr_p,prio);
                           som_prio:=som_prio+prio;
                     fi;
                   fi;

       if (sud_ouest) then deplacementcolonne:=-1;
                     deplacementligne:=1;
                     call direction(ligne,colonne,
                                    deplacementcolonne,deplacementligne,
                                    couleur,invcouleur,tab,nbpion);
                     pionretourne:=pionretourne+nbpion;
                     if (nbpion<>0) and (on_retourne_pion) then
                           call retourne_pion(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab);
                           tab(ligne,colonne):=couleur;
                     fi;
                     if (nbpion<>0) and (on_somme_prio) then
                           call prio_pion_retourne(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab,gr_p,prio);
                           som_prio:=som_prio+prio;
                     fi;
                   fi;

      if (nord_est) then deplacementcolonne:=1;
                     deplacementligne:=-1;
                     call direction(ligne,colonne,
                                    deplacementcolonne,deplacementligne,
                                    couleur,invcouleur,tab,nbpion);
                     pionretourne:=pionretourne+nbpion;
                     if (nbpion<>0) and (on_retourne_pion) then
                           call retourne_pion(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab);
                           tab(ligne,colonne):=couleur;
                     fi;
                     if (nbpion<>0) and (on_somme_prio) then
                           call prio_pion_retourne(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab,gr_p,prio);
                           som_prio:=som_prio+prio;
                     fi;
                   fi;

       if (sud_est) then deplacementcolonne:=1;
                     deplacementligne:=1;
                     call direction(ligne,colonne,
                                    deplacementcolonne,deplacementligne,
                                    couleur,invcouleur,tab,nbpion);
                     pionretourne:=pionretourne+nbpion;
                     if (nbpion<>0) and (on_retourne_pion) then
                           call retourne_pion(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab);
                           tab(ligne,colonne):=couleur;
                     fi;
                     if (nbpion<>0) and (on_somme_prio) then
                           call prio_pion_retourne(ligne,colonne,
                           deplacementcolonne,deplacementligne,
                           couleur,invcouleur,tab,gr_p,prio);
                           som_prio:=som_prio+prio;
                     fi;
                   fi;
  end peut_on_poser_pion;

unit joueur_humain : coroutine;
var i,j,x,y:integer;
begin
 return;
 do
 call gotoxy(21,1);
 if (rep='2')  then
         if (pion=1) then
	 write("Joueur 1 : ");write(chr(27),"[33m");
	 writeln("Noir  x  ");write(chr(27),"[36m")
	 else
	 write("Joueur 2 : ");write(chr(27),"[32m");
	 writeln("Blanc o  ");write(chr(27),"[36m");
         fi
else
         if (rep='o') or (rep='O') then
         write("Joueur : ");write(chr(27),"[33m");
         writeln("Noir  x  ");write(chr(27),"[36m")
         else
         write("Joueur : ");write(chr(27),"[32m");
         writeln("Blanc o  ");write(chr(27),"[36m");
         fi;
 fi;
 call deplace;
 lig:=ii;
 col:=jj;
 detach;
 od;
end joueur_humain;

unit depace_souris : procedure;
   var x,y:integer;
begin

  pref mouse block;

  var o8,dx,dy,gk,h,v,p,b:integer,
      l,r,c:boolean;
  begin
     o8 := 8;
     b:=0;
     call defcursor(1,11,12);
     call showcursor;
     call status(h,v,l,r,c);
     do
       call getpress(b,h,v,p,l,r,c);
       if c
       then
         exit
       fi;
       if l
       then
         dx:=h / o8; dy := v / o8;
         call gotoxy(dy+1,dx+1);
	 call SetPosition(h,v);
         if ((dx+1>=4) and (dx+1<=42) and (dy+1>=3) and (dy+1<=18)) then
          if (dx+1<>8) and (dx+1<>13) and(dx+1<>18) and(dx+1<>23)
             and (dx+1<>28) and (dx+1<>33) and (dx+1<>38) then exit;
          fi;
         fi;
       fi;
       if r
       then
         call getpress(1,h,v,p,l,r,c);
         dx :=h div o8;
	 dy :=v div o8;
	 call gotoxy(dy,dx);
         arreter:=true;
	 call SetPosition(h,v); exit;
       fi;
     od;
    x:=dx+1;
    y:=dy+1;

    if (x>=4) and (x<=7) then x:=1; fi;
    if (x>=9) and (x<=12) then x:=2; fi;
    if (x>=14) and (x<=17) then x:=3; fi;
    if (x>=19) and (x<=22) then x:=4; fi;
    if (x>=24) and (x<=27) then x:=5; fi;
    if (x>=29) and (x<=32) then x:=6; fi;
    if (x>=34) and (x<=37) then x:=7; fi;
    if (x>=39) and (x<=42) then x:=8; fi;
    jj:=x;

    if (y>=3) and (y<=4) then y:=1; fi;
    if (y>=5) and (y<=6) then y:=2; fi;
    if (y>=7) and (y<=8) then y:=3; fi;
    if (y>=9) and (y<=10) then y:=4; fi;
    if (y>=11) and (y<=12) then y:=5; fi;
    if (y>=13) and (y<=14) then y:=6; fi;
    if (y>=15) and (y<=16) then y:=7; fi;
    if (y>=17) and (y<=18) then y:=8; fi;
    ii:=y;

  end (* mouse *)

end depace_souris;





unit joueur_humain_souris : coroutine;
var i,j,x,y:integer;
begin
 return;
 do
 call gotoxy(21,1);
 if (rep='2')  then
         if (pion=1) then
	 write("Joueur 1 : ");write(chr(27),"[33m");
	 writeln("Noir  x  ");write(chr(27),"[36m")
	 else
	 write("Joueur 2 : ");write(chr(27),"[32m");
	 writeln("Blanc o  ");write(chr(27),"[36m");
         fi
else
         if (rep='o') or (rep='O') then
         write("Joueur : ");write(chr(27),"[33m");
         writeln("Noir  x  ");write(chr(27),"[36m")
         else
         write("Joueur : ");write(chr(27),"[32m");
         writeln("Blanc o  ");write(chr(27),"[36m");
         fi;
 fi;


  call depace_souris;

 lig:=ii;
 col:=jj;
 detach;
 od;
end joueur_humain_souris;


unit copie_tableau:procedure(input t1:arrayof arrayof integer;
                             inout t2:arrayof arrayof integer);
var i,j:integer;
begin

   for i:=1 to 8
    do
     for j:=1 to 8
      do
       t2(i,j):=t1(i,j);
      od;
    od;
end copie_tableau;


unit prio_pion_retourne:procedure(ligne,colonne:integer;
                           deplacementcolonne,deplacementligne:integer;
                           couleur,invcouleur:integer;
                           tab,gr_prio:arrayof arrayof integer;
                           output som_prio : integer);
  begin
      som_prio:=0;
      do
       colonne:=colonne+deplacementcolonne;
       ligne:=ligne+deplacementligne;

       if (tab(ligne,colonne)=couleur) then
        (* case de meme couleur *)
        exit;
       fi;

       if (tab(ligne,colonne)=invcouleur) then
        (* case de couleur inverse *)
        (* on somme la priorite du pion qu'on peut retourner *)
        som_prio:=som_prio+gr_prio(ligne,colonne);
       fi;
      od;
  end prio_pion_retourne;

unit cherche_pion_a_poser:procedure(input couleur:integer;
                                    input tab:arrayof arrayof integer;
				    inout coup:arrayof arrayof integer;
				    inout nb_coup:integer);
  var i,j,k,l,nb:integer;
  var on_retourne_pion:boolean;
  var som_prio:integer;
  var tab_2:arrayof arrayof integer;
  var invcouleur,max,som_adverse:integer;
  begin
   array tab_2 dim (1:8);
   for i:=1 to 8
    do
     array tab_2(i) dim (1:8);
    od;
   if (couleur=1) then invcouleur:=2 else invcouleur:=1;fi;
   on_retourne_pion:=false;
   nb_coup:=0;
   for i:=1 to 8
    do
     for j:=1 to 8
      do
       if tab(i,j)=0 then
        call copie_tableau(tab,tab_2);

        (* simule notre coup *)
        call peut_on_poser_pion(i,j,couleur,tab_2,on_retourne_pion,true,nb,som_prio);
        if nb<>0 then nb_coup:=nb_coup+1;
		      coup(nb_coup,1):=i; (* ligne *)
		      coup(nb_coup,2):=j; (* colonne *)
		      coup(nb_coup,3):=nb; (* pions retourn‚s *)
		      coup(nb_coup,4):=gr_p(i,j); (* priorit‚ du pion pos‚ *)
                      coup(nb_coup,5):=som_prio;  (* priorit‚ pions retourn‚s *)
        (* pose et retourne*)

        call peut_on_poser_pion(i,j,couleur,tab_2,true,false,nb,som_prio);
        (* simule le coup adverse *)
                      max:=-1000;
                      for k:=1 to 8
                       do
                       for l:=1 to 8
                         do
                         if tab_2(k,l)=0 then
call peut_on_poser_pion(k,l,invcouleur,tab_2,false,true,nb,som_prio);
                          if nb<>0 then
                           som_adverse:=2*nb+7*gr_p(k,l)+som_prio;
                           if max<som_adverse then max:=som_adverse;fi;
                          fi;
                         fi;
                         od;
                       od;
                      coup(nb_coup,6):=max;

        fi;
        fi;
      od;
    od;
kill(tab_2);
  end cherche_pion_a_poser;

unit remp_gr_prio:procedure(output gr_prio:arrayof arrayof integer);
var i,j:integer;
begin
array gr_prio dim (1:8);
   for i:=1 to 8
    do
     array gr_prio(i) dim (1:8);
    od;
gr_prio(1,1):=20;
gr_prio(1,8):=20;
gr_prio(8,1):=20;
gr_prio(8,8):=20;
gr_prio(1,3):=14;
gr_prio(1,6):=14;
gr_prio(8,3):=14;
gr_prio(8,6):=14;
gr_prio(3,1):=14;
gr_prio(6,1):=14;
gr_prio(3,8):=14;
gr_prio(6,8):=14;
gr_prio(1,4):=12;
gr_prio(1,5):=12;
gr_prio(8,4):=12;
gr_prio(8,5):=12;
gr_prio(4,1):=12;
gr_prio(5,1):=12;
gr_prio(4,8):=12;
gr_prio(5,8):=12;
gr_prio(1,2):=9;
gr_prio(1,7):=9;
gr_prio(8,2):=9;
gr_prio(8,7):=9;
gr_prio(2,1):=9;
gr_prio(7,1):=9;
gr_prio(2,8):=9;
gr_prio(7,8):=9;
gr_prio(3,3):=6;
gr_prio(3,6):=6;
gr_prio(6,3):=6;
gr_prio(6,6):=6;
gr_prio(3,4):=4;
gr_prio(3,5):=4;
gr_prio(6,4):=4;
gr_prio(6,5):=4;
gr_prio(4,3):=4;
gr_prio(5,3):=4;
gr_prio(4,6):=4;
gr_prio(5,6):=4;
gr_prio(2,3):=2;
gr_prio(2,4):=2;
gr_prio(2,5):=2;
gr_prio(2,6):=2;
gr_prio(7,3):=2;
gr_prio(7,4):=2;
gr_prio(7,5):=2;
gr_prio(7,6):=2;
gr_prio(3,2):=2;
gr_prio(4,2):=2;
gr_prio(5,2):=2;
gr_prio(6,2):=2;
gr_prio(3,7):=2;
gr_prio(4,7):=2;
gr_prio(5,7):=2;
gr_prio(6,7):=2;
gr_prio(2,2):=1;
gr_prio(2,7):=1;
gr_prio(7,2):=1;
gr_prio(7,7):=1;
gr_prio(4,4):=2;
gr_prio(4,5):=2;
gr_prio(5,4):=2;
gr_prio(5,5):=2;
end remp_gr_prio;

unit modifie_gr_prio : procedure(rep2 : char);
begin

(* changement des priorites *)
(* on le coin haut-gauche *)
if rep2='1' or rep2='2' or rep2='3' or rep2='4' then
gr_p(1,2):=16;
gr_p(2,1):=16;
gr_p(8,1):=15;
gr_p(1,3):=15;
gr_p(2,2):=15;
gr_p(4,1):=13;
gr_p(1,4):=13;
gr_p(2,3):=13;
gr_p(3,2):=13;
fi;

(* on le coin haut-droit *)
if rep2='2' or rep2='3' or rep2='4' then
gr_p(1,7):=16;
gr_p(2,8):=16;
gr_p(3,8):=15;
gr_p(1,6):=15;
gr_p(2,7):=15;
gr_p(4,8):=13;
gr_p(1,5):=13;
gr_p(2,6):=13;
gr_p(3,7):=13;
fi;

(* on le coin bas-droit *)
if rep2='3' or rep2='4' then
gr_p(8,7):=16;
gr_p(7,8):=16;
gr_p(6,8):=15;
gr_p(8,6):=15;
gr_p(7,7):=15;
gr_p(5,8):=13;
gr_p(8,5):=13;
gr_p(7,6):=13;
gr_p(6,7):=13;
fi;

(* on le coin bas-gauche *)
if rep2='4' then
gr_p(7,1):=16;
gr_p(8,2):=16;
gr_p(8,3):=15;
gr_p(7,2):=15;
gr_p(6,1):=15;
gr_p(8,4):=13;
gr_p(7,3):=13;
gr_p(6,2):=13;
gr_p(5,1):=13;
fi;

end modifie_gr_prio;


unit joueur_machine : coroutine;
var i,j,nb_point,nb_coup,max_pion_retourne,pion :integer;
var coup : arrayof arrayof integer;
begin
array coup dim (1:60);
for i:=1 to 60
 do
  array coup(i) dim (1:7);
 od;
return;
do
call gotoxy(21,1);
if (rep='n') or (rep='N') then
write("Machine : ");write(chr(27),"[33m");
writeln("Noir  x");write(chr(27),"[36m")
else
write("Machine : ");write(chr(27),"[32m");
writeln("Blanc o");write(chr(27),"[36m");
fi;

nb_point:=0;
(* recherche des cases ou l'on peut jouer *)
if (rep='o') or (rep='O') then pion:=2 else pion:=1 fi;
call cherche_pion_a_poser(pion,plateau,coup,nb_coup);

(*faire la somme des priorit‚*)
for i:=1 to nb_coup do
 coup(i,7):=coup(i,3)*2+coup(i,4)*5+coup(i,5)-coup(i,6);
                    od;
(* choix de la meilleure case *)
max_pion_retourne:=-1000;
for i:= 1 to nb_coup
 do
  if coup(i,7)>max_pion_retourne then max_pion_retourne:=coup(i,7);
		                      lig:=coup(i,1);
                		      col:=coup(i,2);
  fi;
 od;
ii:=lig;
jj:=col;
(* changement des priorites *)
(* on le coin haut-gauche *)
if lig=1 and col=1 then
gr_p(1,2):=16;
gr_p(2,1):=16;
gr_p(8,1):=15;
gr_p(1,3):=15;
gr_p(2,2):=15;
gr_p(4,1):=13;
gr_p(1,4):=13;
gr_p(2,3):=13;
gr_p(3,2):=13;
fi;

(* on le coin haut-droit *)
if lig=1 and col=8 then
gr_p(1,7):=16;
gr_p(2,8):=16;
gr_p(3,8):=15;
gr_p(1,6):=15;
gr_p(2,7):=15;
gr_p(4,8):=13;
gr_p(1,5):=13;
gr_p(2,6):=13;
gr_p(3,7):=13;
fi;

(* on le coin bas-droit *)
if lig=8 and col=8 then
gr_p(8,7):=16;
gr_p(7,8):=16;
gr_p(6,8):=15;
gr_p(8,6):=15;
gr_p(7,7):=15;
gr_p(5,8):=13;
gr_p(8,5):=13;
gr_p(7,6):=13;
gr_p(6,7):=13;
fi;

(* on le coin bas-gauche *)
if lig=8 and col=1 then
gr_p(7,1):=16;
gr_p(8,2):=16;
gr_p(8,3):=15;
gr_p(7,2):=15;
gr_p(6,1):=15;
gr_p(8,4):=13;
gr_p(7,3):=13;
gr_p(6,2):=13;
gr_p(5,1):=13;
fi;


xx:=lig*2+2;
yy:=col*5;
call gotoxy(xx,yy);
detach;
od;
end joueur_machine;

unit compte_pion:procedure(input tab:arrayof arrayof integer;
                           output nb_pion_blanc,nb_pion_noir:integer);
var i,j:integer;
  begin
   nb_pion_blanc:=0;
   nb_pion_noir:=0;
   for i:=1 to 8
     do
     for j:=1 to 8
      do
       if (tab(i,j)=1) then nb_pion_noir:=nb_pion_noir+1;fi;
       if (tab(i,j)=2) then nb_pion_blanc:=nb_pion_blanc+1;fi;
      od;
    od;
end compte_pion;

unit aff_nb_pion:procedure;
begin
 call gotoxy(3,55);
 writeln("ÚÄÄÄÄÄÄÄ¿");
 call gotoxy(4,55);
 writeln("³ SCORE ³");
 call gotoxy(5,55);
 writeln("ÀÄÄÄÄÄÄÄÙ");
 call gotoxy(6,46);
 write("Nombre de pions ");write(chr(27),"[33m");
 write("noir  ");write(chr(27),"[36m");write(": ");
 write(chr(27),"[33m");write(nb_pion_noir);write(chr(27),"[36m");
 call gotoxy(8,46);
 write("Nombre de pions ");write(chr(27),"[32m");
 write("blanc ");write(chr(27),"[36m");write(": ");
 write(chr(27),"[32m");write(nb_pion_blanc);write(chr(27),"[36m");
 call gotoxy(xx,yy);
end aff_nb_pion;


(***********************************************************************)
(************************ Programme Principal **************************)
(***********************************************************************)

var plateau,gr_p:arrayof arrayof integer;
var nb,nb_case_vide:integer;
var joueur1,joueur2:joueur_humain;
var joueur1_s,joueur2_s:joueur_humain_souris;
var joueur3:joueur_machine;
var col,lig,i,xx,yy,ii,jj:integer;
var pion,nb_pion_blanc,nb_pion_noir:integer;
var nb_noir_poser,nb_blanc_poser:integer;
var sec1,sec2:integer;
var arreter:boolean;
var bidon,rep,rep2:char;
var som_prio:integer;
var souris:boolean;

begin
 call newpage;
 write(chr(27),"[31m");
 call gotoxy(10,19);
 writeln("ÚÄÄÄÄ¿ ÄÄÂÄÄ ³    ³ ÚÄÄÄÄ ³     ³     ÚÄÄÄÄ¿ ");
 call gotoxy(11,19);
 writeln("³    ³   ³   ÃÄÄÄÄ´ ÃÄÄ   ³     ³     ³    ³ ");
 call gotoxy(12,19);
 writeln("ÀÄÄÄÄÙ   ³   ³    ³ ÀÄÄÄÄ ÀÄÄÄÄ ÀÄÄÄÄ ÀÄÄÄÄÙ ");
 call gotoxy(17,33);
 write(chr(27),"[36m");
 writeln("Presented by");
 call gotoxy(22,11);
 write(chr(27),"[32m");
 writeln("Defeuillet Patrick - Gosset V‚ronique - Dupin Christophe");
 call pause(2);
 do
 write(chr(27),"[36m");
 arreter:=false;
 ii:=1;
 jj:=1;
 xx:=4;
 yy:=5;
 rep := ' ';
 while (rep <> 'o') and (rep <> 'n') and (rep <> 'O') and (rep <> 'N')
 do
  call newpage;
 call gotoxy(8,1);
 writeln("                   Avez_vous une souris (O ou N) ? ");
 writeln;
 write("                            Votre choix : ");
 readln(rep);
 od;
if (rep='o') or (rep='O') then souris:=true;
else souris:=false;
fi;
 while (rep <> '1') and (rep <> '2')
 do
 call newpage;
 call gotoxy(3,20);
 writeln("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ");
 call gotoxy(4,20);
 writeln("³    PREPARATION DU JEU    ³ ");
 call gotoxy(5,20);
 writeln("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ");
 call gotoxy(8,1);
 writeln("               1 - UN   joueur");
 writeln("               2 - DEUX joueurs ");
 writeln;
 write("                            Votre choix : ");
 readln(rep);
 od;
 rep2:=' ';
 while rep2<>'0' and rep2<>'1' and rep2<>'2' and rep2<>'3' and rep2<>'4'
 do
  call gotoxy(13,1);
  writeln("          Les noirs commencent avec combien de coin(s) (0 … 4) ? ");
  writeln;
  write("                            Votre choix : ");
  readln(rep2);
 od;
  call initialisegrille(plateau);
  if rep2='0' then nb_case_vide:=60;fi;
  if rep2='1' then nb_case_vide:=59;plateau(1,1):=1;fi;
  if rep2='2' then nb_case_vide:=58;plateau(1,1):=1;plateau(1,8):=1;fi;
  if rep2='3' then nb_case_vide:=57;plateau(1,1):=1;plateau(1,8):=1;
                   plateau(8,1):=1;fi;
  if rep2='4' then nb_case_vide:=56;plateau(1,1):=1;plateau(1,8):=1;
                   plateau(8,1):=1;plateau(8,8):=1;fi;
 if rep = '1' then while (rep <> 'O') and (rep <> 'N') and (rep <> 'o') and (rep <> 'n')
		 do
		 call gotoxy(18,1);
		 writeln("               Voulez_vous commencer (O ou N) ?");
		 writeln;
		 write("                             Votre choix :  ");
		 readln(rep);
		 od;
		 if (rep = 'O') or (rep='o') then
		 if souris then
                  joueur1_s := new joueur_humain_souris
                 else
                  joueur1 := new joueur_humain;
                 fi;
		 joueur3 := new joueur_machine;
		 else
		 joueur3 := new joueur_machine;
                 if souris then
                  joueur2_s := new joueur_humain_souris
                 else
		  joueur2 := new joueur_humain;
                 fi;
		 fi;
 else
  if souris then
      joueur1_s := new joueur_humain_souris;
      joueur2_s := new joueur_humain_souris;
  else
      joueur1 := new joueur_humain;
      joueur2 := new joueur_humain;
  fi;
 fi;


 call remp_gr_prio(gr_p);
 if ((rep2<>'0') and (rep='n' or rep='N')) then
  call modifie_gr_prio(rep2);
 fi;
 call affichecadre;
 call affichegrille(plateau);
 call compte_pion(plateau,nb_pion_blanc,nb_pion_noir);
 call aff_nb_pion;

do
  call nb_de_pion_a_poser(1,plateau,false,nb_noir_poser,som_prio);
  if nb_noir_poser=0 then if nb_case_vide<>0 then
			  call gotoxy(10,46);
			  writeln("Les noirs ne peuvent pas jouer !");
			  call  gotoxy(xx,yy);
			  call pause(2);
			  call gotoxy(10,46);
                          writeln("                                ");
			  call gotoxy(xx,yy);fi;
  fi;
  if nb_noir_poser<>0 then
   do
    (* pion noir *)
    pion:=1;
    if (rep='2') or (rep = 'O') or (rep = 'o') then sec1:=1;
      if souris then attach(joueur1_s) else attach(joueur1);fi;
    fi;
    if (rep = 'N') or (rep = 'n') then sec1:=2;attach(joueur3);fi;
    if arreter then exit fi;
    if plateau(lig,col)=0 then
    call peut_on_poser_pion(lig,col,pion,plateau,true,false,nb,som_prio);
    if nb<>0 then nb_case_vide:=nb_case_vide-1;exit;fi;
    fi;
   od;
   if arreter then exit fi;
   write(chr(27),"[33m");
   call gotoxy(4+2*(ii-1),5+5*(jj-1));
   write("x");
   write(chr(27),"[36m");
   call pause(sec1);
   call affichegrille(plateau);
   call compte_pion(plateau,nb_pion_blanc,nb_pion_noir);
   if nb_pion_blanc=0 then exit;fi;
   call aff_nb_pion;
  fi;

  if (nb_blanc_poser=0) and (nb_noir_poser=0) then exit;fi;
  call nb_de_pion_a_poser(2,plateau,false,nb_blanc_poser,som_prio);
  if nb_blanc_poser=0 then if nb_case_vide<>0 then
			   call gotoxy(10,46);
			   writeln("Les blancs ne peuvent pas jouer !");
                           call  gotoxy(xx,yy);
			   call pause(2);
			   call gotoxy(10,46);
			   writeln("                                 ");
			   call  gotoxy(xx,yy);fi;
  fi;
  if nb_blanc_poser<>0 then
   do
    (* pion blanc *)
    pion:=2;
    if (rep='2') or (rep = 'N') or (rep = 'n') then sec2:=1;
       if souris then attach(joueur2_s) else attach(joueur2);fi;
    fi;
    if (rep = 'O') or (rep = 'o') then sec2:=2;attach(joueur3);fi;
    if arreter then exit fi;
    if plateau(lig,col)=0 then
    call peut_on_poser_pion(lig,col,pion,plateau,true,false,nb,som_prio);
    if nb<>0 then nb_case_vide:=nb_case_vide-1;exit;fi;
    fi;
   od;
   if arreter then exit fi;
   write(chr(27),"[32m");
   call gotoxy(4+2*(ii-1),5+5*(jj-1));
   write("o");
   write(chr(27),"[36m");
   call pause(sec2);
   call affichegrille(plateau);
   call compte_pion(plateau,nb_pion_blanc,nb_pion_noir);
   if nb_pion_noir=0 then exit;fi;
   call aff_nb_pion;
  fi;

  if (nb_blanc_poser=0) and (nb_noir_poser=0) then exit;fi;
  if nb_case_vide=0 then exit;fi;
 od;

if not arreter then
call aff_nb_pion;
call gotoxy(13,54);
writeln("FIN DE LA PARTIE");
call compte_pion(plateau,nb_pion_blanc,nb_pion_noir);
if nb_pion_blanc=nb_pion_noir then call gotoxy(16,46);
                                   writeln("        Match nul !");fi;
if nb_pion_blanc<nb_pion_noir then
 call gotoxy(15,46);
 writeln("Les noirs gagnent la partie avec ");
 call gotoxy(16,46);
 writeln(nb_pion_noir," pions noirs contre ");
 call gotoxy(17,46);
 writeln(nb_pion_blanc," pions blancs.");
fi;
if nb_pion_blanc>nb_pion_noir then
 call gotoxy(15,46);
 writeln("Les blancs gagnent la partie avec ");
 call gotoxy(16,46);
 writeln(nb_pion_blanc," pions blancs contre ");
 call gotoxy(17,46);
 writeln(nb_pion_noir," pions noirs.");
fi;

(* destruction des coroutines *)
if (rep = 'O') orif (rep = 'o') then
  kill (joueur1);
  kill (joueur3);
fi;
if (rep = 'N') orif (rep = 'n') then
  kill (joueur3);
  kill (joueur2);
fi;
if (rep ='2') then
  kill (joueur1);
  kill (joueur2);
fi;

call gotoxy(19,54);
write(chr(27),"[33m");
writeln("- Faites Retour - ");
read(bidon);
fi;
call newpage;
call normal;
rep := ' ';
 while (rep <> 'o') and (rep <> 'n') and (rep <> 'O') and (rep <> 'N')
 do
  call newpage;
 call gotoxy(8,1);
 writeln("              Voulez_vous faire une autre partie (O ou N) ? ");
 writeln;
 write("                             Votre choix : ");
 readln(rep);
 od;
if rep='n' or rep='N' then exit;fi;
od;
call newpage;
write(chr(27),"[33m");
call gotoxy(9,25);
writeln("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ");
call gotoxy(10,25);
writeln("³                          ³ ");
call gotoxy(11,25);
writeln("³       P A     P A !      ³ ");
call gotoxy(12,25);
writeln("³                          ³ ");
call gotoxy(13,25);
writeln("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ");
call pause(1);
call normal;
call newpage;
end othello