Program chinois; const blanc=15,bleu=1,vert=2,vertpetrole=3,rouge=4,violet=5,marron=6,grisclair=7, grisfonce=8,bleuroi=9,vertclair=10,free=-1; UNIT coord2D:class(x,y:integer); end; UNIT coord3D:class(x,y,h:integer); end; UNIT gestion_caractere: IIUWGRAPH class; UNIT SAISIE:function(ti,e,x,y:integer):arrayof char; var i,n:integer, c: integer, t :arrayof char; begin array t dim(1:e); for i:=1 to e do t(i):=' '; od; do i:=1; c:=inkey; while c<>13 and c<>27 and i<=e do case ti when 1: if c>=48 and c<=57 then t(i):=chr(c); call move(x+i*9,y); call hascii(c); i:=i+1; fi; when 2: if c>64 then t(i):=chr(c); call move(x+i*9,y); call hascii(c); i:=i+1; fi; esac; c:=inkey; od; if t(1)<>' ' then exit; fi; od; result:=t; end SAISIE; UNIT ConvEnt:function(t:arrayof char):integer; var n,i:integer; begin n:=0; for i:=1 to upper(t) do if t(i)<>' ' then n:=n*10+(ord(t(i))-48); fi; od; result:=n; end ConvEnt; UNIT displaystring:procedure(t:arrayof char,x,y,coul:integer); var i:integer; begin call color(coul); for i:=1 to upper(t) do call move(x+i*9,y); call hascii(ord(t(i))); od; end; END; UNIT element:class; var x,i,j,h:integer; END; UNIT ARBTAS : class; (* structure utilis‚e par la coroutine ordinateur *) var tab : arrayof element, (* tableau contenant les elements du tas *) nb : integer, (* entier le nombre d'elements du tas *) dimen: integer; (* fonction testant si le tas est vide ou non *) unit vide : function : boolean; begin if (tab(1) = none) then result := true; fi; end vide; (* fonction retournant le minimum du tas *) unit mini : function : element; begin if not vide then result := tab(1); fi; end mini; (* fonction retournant la position d'un element dans le tas *) unit membre : function(elem:element) : integer; var i : integer; begin if not vide then for i:=1 to nb do if tab(i).x = elem.x then result := i; exit; fi; od; fi; end membre; (* procedure pour inserer un nouvel element dans le tas *) unit inserer : procedure(elem : element); var i : integer, aux : element, tabaux : arrayof element; begin if (nb >= dimen) (* on aggrandit le tableau trop petit *) then array tabaux dim (1:nb+1); for i:=1 to nb do tabaux(i) := tab(i); od; tab := tabaux; dimen := dimen + 1; (* la dimension du tableau est *) (* incremente de 1 *) fi; nb := nb + 1; (* le nombre d'elements est incremente de 1 *) tab(nb) := elem; (* l'element a inserer est place a la fin *) i := nb; aux := new element; do (* on effectue des echanges tant que le fils est inferieur *) (* au pere *) if (i <= 1 ) orif ( tab(i).x >= tab(i div 2).x ) then exit; fi; aux := tab(i DIV 2); (* echange pere-fils *) tab(i DIV 2) := tab(i); tab(i) := aux; i := i div 2; od; end inserer; (* procedure pour supprimer un element du tas *) unit supprimer : procedure(elem : element); var i,j : integer, aux : element; begin i := membre(elem); if ( i <> 0 ) (* on teste si l'element appartient au tas *) then kill(tab(i)); tab(i) := tab(nb); (* le dernier element est place *) (* a l'endroit de l'element supprime *) nb := nb - 1; (* on decremente le nombre d'elements *) aux := new element; while ( i <= (nb div 2) ) do (* tant que tab(i) n'est pas une feuille *) if (2*i = nb) orif (tab(2*i).x < tab(2*i + 1).x) then j := 2*i; (* on calcule l'indice du plus petit *) else j := 2*i + 1; (* des 2 fils *) fi; if tab(i).x > tab(j).x then aux := tab(i); (* echange si la condition d'ordre *) tab(i) := tab(j);(* n'est pas satisfaite *) tab(j) := aux; i := j; else exit; fi; od; tab(nb + 1) := none; (* le dernier element est supprime *) fi; end supprimer; begin array tab dim (1:10); nb := 0; dimen:=10; end ARBTAS; UNIT elem:class(i,j,k:integer); var prec:elem; end; UNIT pile:class; (* structure utilis‚e par la coroutine controle*) var pointeur:elem; UNIT empiler:procedure(e:elem); begin e.prec:=pointeur; pointeur:=e; end; UNIT depiler:procedure; var tampon:elem; begin if not vide then tampon:=pointeur; pointeur:=pointeur.prec; kill(tampon); fi; end; UNIT sommet:function:elem; begin result:=pointeur; end; UNIT vide:function:boolean; begin result:=(pointeur=none); end; begin pointeur:=none; END; UNIT drawrect: IIUWGRAPH procedure(x1,y1,x2,y2,couleur:integer); begin call color(couleur); call move(x1,y1); call draw(x2,y1); call draw(x2,y2); call draw(x1,y2); call draw(x1,y1); end; UNIT player: gestion_caractere class(couleur:integer,pl:plateau_jeu); END; UNIT ordi: player coroutine; var coinlibre,find:boolean, coin,c,quel,version:integer, place:coord3D, pos:integer,cointab:arrayof coord2D, posajouer:arrayof arrayof integer, mem:arbtas, adver,moi:arrayof info; UNIT info: class(n,sur:integer); var rangee:arrayof arrayof combinaison; begin block var i,j:integer; begin array rangee dim(1:n); for i:=1 to n do array rangee(i) dim (1:sur); od; for i:=1 to n do for j:=1 to sur do rangee(i,j):=new combinaison; od; od; end; end; UNIT find_place:function(quoi,l,x,h:integer;inout p:coord3D):boolean; const ligne=1,colonne=2,lignediag=3,coldiag=4,axe=5,dbdiag=7,bigdiag=6; var i:integer, trouve:boolean; begin trouve:=false; case quoi when dbdiag: case x when 1: case h when 1: for i:=1 TO 4 do if pl.jeu(i,i,i)=free then if i=posajouer(i,i) then trouve:=true; p.x:=i;p.y:=i;p.h:=i; exit; fi; fi; od; when 2: for i:=1 TO 4 do if pl.jeu(i,i,(4-i)+1)=free then if posajouer(i,i)=(4-i)+1 then trouve:=true; p.x:=i;p.y:=i;p.h:=(4-i)+1; exit; fi; fi; od; esac; when 2: case h when 1: for i:=1 TO 4 do if pl.jeu(i,(4-i)+1,i)=free then if i=posajouer(i,(4-i)+1) then trouve:=true; p.x:=i;p.y:=(4-i)+1;p.h:=i; exit; fi; fi; od; when 2: for i:=1 TO 4 do if pl.jeu(i,(4-i)+1,(4-i)+1)=free then if posajouer(i,(4-i)+1)=(4-i)+1 then trouve:=true; p.x:=i;p.y:=(4-i)+1;p.h:=(4-i)+1; exit; fi; fi; od; esac; esac; when bigdiag: case l when 1: for i:=1 TO 4 do if pl.jeu(i,i,h)=free then if h=posajouer(i,i) then trouve:=true; p.x:=i;p.y:=i;p.h:=h; fi; exit; fi; od; when 2: for i:=1 TO 4 do if pl.jeu(i,(4-i)+1,h)=free then if h=posajouer(i,(4-i)+1) then trouve:=true; p.x:=i;p.y:=(4-i)+1;p.h:=h; fi; exit; fi; od; esac; when ligne: (* recherche d'une place dans la ligne sp‚cifi‚e *) for i:=1 to 4 do if pl.jeu(x,i,h)=free then if h=posajouer(x,i) then trouve:=true; fi; exit; fi; od; if trouve then p.x:=x; p.y:=i; p.h:=posajouer(x,i); fi; when colonne: (* recherche d'une place dans la colonne sp‚cifi‚e *) for i:=1 to 4 do if pl.jeu(i,x,h)=free then if posajouer(i,x)=h then trouve:=true; p.x:=i;p.y:=x;p.h:=posajouer(i,x); fi; exit; fi; od; when lignediag:(* recherche d'une place dans la diagonnal ligne sp‚cifi‚e *) case l when 1: for i:=1 to 4 do if pl.jeu(x,i,i)=free then if posajouer(x,i)=i then trouve:=true; p.x:=x;p.y:=i;p.h:=i; fi; exit; fi; od; when 2: for i:=1 to 4 do if pl.jeu(x,i,(4-i)+1)=free then if posajouer(x,i)=(4-i)+1 then trouve:=true; p.x:=x;p.y:=i;p.h:=(4-i)+1; fi; exit; fi; od; esac; when axe: (* recherche d'une place dans l'axe sp‚cifi‚e *) if posajouer(x,h)<>5 then p.x:=x; p.y:=h; p.h:=posajouer(x,h); trouve:=true; fi; when coldiag:(* recherche d'une place dans la diagonnal colonne sp‚cifi‚e *) case l when 1: for i:=1 to 4 do if pl.jeu(i,x,i)=free then if posajouer(i,x)=i then trouve:=true; p.x:=i;p.y:=x;p.h:=i; fi; exit; fi; od; when 2: for i:=1 to 4 do if pl.jeu(i,x,(4-i)+1)=free then if posajouer(i,x)=(4-i)+1 then trouve:=true; p.x:=i;p.y:=x;p.h:=(4-i)+1; fi; exit; fi; od; esac; esac; result:=trouve; end; UNIT isintwodiag:function(x,y,h:integer;inout a,b:integer):boolean; var trouve:boolean; begin trouve:=false; if (h=x) and (x=y) then trouve:=true; a:=1;b:=1; else if (x=y) and (h=(4-x)+1) then trouve:=true; a:=1;b:=2; else if (x=(4-y)+1) and (h=x) then trouve:=true; a:=2;b:=1; else if (x=(4-y)+1) and (h=y) then trouve:=true; a:=2;b:=2; fi; fi; fi; fi; result:=trouve; end; UNIT isinbigdiag:function(x,y:integer;inout quel:integer):boolean; const droite=1,gauche=2; var i:integer, trouve:boolean; begin quel:=0; trouve:=false; if (x=y) then trouve:=true; quel:=1; else if (x=(4-y)+1) then trouve:=true; quel:=2 fi; fi; result:=trouve; end; UNIT isindiag:function(l,h:integer;inout dg:integer):boolean; var trouve:boolean; begin trouve:=false; if h=l then trouve:=true; dg:=1; else if h=(4-l)+1 then trouve:=true; dg:=2; fi; fi; result:=trouve; end; unit troisboules:function(tab:arrayof info;inout p:coord3D):boolean; var i,j:integer, trouve:boolean; begin trouve:=false; if p<>none then if tab(1).rangee(p.x,p.h).nbre_boule=3 then trouve:=find_place(1,0,p.x,p.h,p); else if tab(2).rangee(p.y,p.h).nbre_boule=3 then trouve:=find_place(2,0,p.y,p.h,p); else if tab(5).rangee(p.x,p.y).nbre_boule=3 then trouve:=find_place(5,0,p.x,p.y,p); else if isinbigdiag(p.x,p.y,i) then if tab(6).rangee(p.h,i).nbre_boule=3 then trouve:=find_place(6,i,p.x,p.h,p); fi; fi; if isintwodiag(p.x,p.y,p.h,i,j) then if tab(7).rangee(i,j).nbre_boule=3 then trouve:=find_place(7,0,i,j,p); fi; fi; for i:=1 to 2 do if tab(3).rangee(p.x,i).nbre_boule=3 then trouve:=find_place(3,i,p.y,p.h,p); exit; fi; if tab(4).rangee(p.y,i).nbre_boule=3 then trouve:=find_place(4,i,p.x,p.h,p); exit; fi; od; fi; fi; fi; fi; result:=trouve; end; UNIT addcombinaison:procedure(tab:arrayof info,x,y,h:integer); begin call tab(1).rangee(x,h).plus; call tab(2).rangee(y,h).plus; call tab(5).rangee(x,y).plus; if isindiag(y,h,quel) then call tab(3).rangee(x,quel).plus; fi; if isindiag(x,h,quel) then call tab(4).rangee(y,quel).plus; fi; if isinbigdiag(x,y,quel) then call tab(6).rangee(h,quel).plus; fi; if isintwodiag(x,y,h,quel,version) then call tab(7).rangee(quel,version).plus; fi; end; UNIT delcombinaison:procedure(tab:arrayof info,x,y,h:integer); var quel,version:integer; begin (* si une boule a deja ete mise *) call tab(1).rangee(x,h).elimine; call tab(2).rangee(y,h).elimine; if isindiag(y,h,version) then (* diagonnale ligne*) call tab(3).rangee(x,version).elimine; fi; if isindiag(x,h,version) then (* diagonnale colonne*) call tab(4).rangee(y,version).elimine; fi; call tab(5).rangee(x,y).elimine; if isinbigdiag(x,y,quel) then call tab(6).rangee(h,quel).elimine; fi; if isintwodiag(x,y,h,quel,version) then call tab(7).rangee(quel,version).elimine; fi; end; UNIT selectcoup: procedure(inout p:coord3D); var coup:element, trouve,bien:boolean; begin trouve:=false; while (not mem.vide) and (not trouve) do coup:=mem.mini; posajouer(coup.i,coup.j):=posajouer(coup.i,coup.j)+1; p.x:=coup.i; p.y:=coup.j; p.h:=coup.h+1; if p.h<>5 then if not troisboules(adver,p) then p.h:=coup.h; p.x:=coup.i; p.y:=coup.j; trouve:=true; posajouer(coup.i,coup.j):=posajouer(coup.i,coup.j)-1; else posajouer(coup.i,coup.j):=posajouer(coup.i,coup.j)-1; call mem.supprimer(coup); fi; else trouve:=true; p.h:=coup.h; posajouer(coup.i,coup.j):=posajouer(coup.i,coup.j)-1; fi; od; while not mem.vide do call mem.supprimer(mem.mini); od; end; UNIT stratego:procedure; var coup:coord3D, e:element, poid,n,version,quel,x,i,j:integer; begin for i:=1 to 4 do for j:=1 to 4 do if posajouer(i,j)<5 then coup:=new coord3D(i,j,posajouer(i,j)); poid:=0; n:=0; if moi(1).rangee(coup.x,coup.h).possible then case moi(1).rangee(coup.x,coup.h).nbre_boule when 3:poid:=poid+100; otherwise poid:=poid+moi(1).rangee(coup.x,coup.h).nbre_boule; esac; n:=n+1; fi; if moi(2).rangee(coup.y,coup.h).possible then case moi(2).rangee(coup.y,coup.h).nbre_boule when 3:poid:=poid+100; otherwise poid:=moi(2).rangee(coup.y,coup.h).nbre_boule+poid; esac; n:=n+1; fi; if isindiag(coup.y,coup.h,quel) then if moi(3).rangee(coup.x,quel).possible then case moi(3).rangee(coup.x,quel).nbre_boule when 3:poid:=poid+100; otherwise poid:=poid+moi(3).rangee(coup.x,quel).nbre_boule; esac; n:=n+1; fi; fi; if isindiag(coup.x,coup.h,quel) then if moi(4).rangee(coup.y,quel).possible then case moi(4).rangee(coup.y,quel).nbre_boule when 3: poid:=poid+100; otherwise poid:=poid+moi(4).rangee(coup.y,quel).nbre_boule; esac; n:=n+1; fi; fi; if moi(5).rangee(coup.x,coup.y).possible then case moi(5).rangee(coup.x,coup.y).nbre_boule when 3:poid:=poid+100; otherwise poid:=poid+moi(5).rangee(coup.x,coup.y).nbre_boule; esac; n:=n+1; fi; if isinbigdiag(coup.x,coup.y,quel) then if moi(6).rangee(coup.h,quel).possible then case moi(6).rangee(coup.h,quel).nbre_boule when 3: poid:=poid+100; otherwise poid:=poid+moi(6).rangee(coup.h,quel).nbre_boule; esac; n:=n+1; fi; fi; if isintwodiag(coup.x,coup.y,coup.h,quel,version) then if moi(7).rangee(quel,version).possible then case moi(7).rangee(quel,version).nbre_boule when 3:poid:=poid+100; otherwise poid:=poid+moi(7).rangee(quel,version).nbre_boule; esac; n:=n+1; fi; fi; if adver(1).rangee(coup.x,coup.h).possible and adver(2).rangee(coup.y,coup.h).possible then if adver(1).rangee(coup.x,coup.h).nbre_boule=2 and adver(2).rangee(coup.y,coup.h).nbre_boule=2 then poid:=poid+20; fi; fi; if adver(1).rangee(coup.x,coup.h).possible and isindiag(coup.x,coup.h,quel) then if adver(4).rangee(coup.y,quel).possible then if adver(1).rangee(coup.x,coup.h).nbre_boule=2 and adver(4).rangee(coup.y,quel).nbre_boule=2 then poid:=poid+20; fi; fi; fi; x:=coup.x; for c:=1 to 2 do if adver(c).rangee(x,coup.h).possible and adver(5).rangee(coup.x,coup.y).possible then if adver(c).rangee(x,coup.h).nbre_boule=2 and adver(5).rangee(coup.x,coup.y).nbre_boule=2 then poid:=poid+20; fi; fi; if adver(c).rangee(x,coup.h).possible and isinbigdiag(coup.x,coup.y,quel) then if adver(6).rangee(coup.h,quel).possible then if adver(c).rangee(x,coup.h).nbre_boule=2 and adver(6).rangee(coup.h,quel).nbre_boule=2 then poid:=poid+20; fi; fi; fi; if adver(c).rangee(x,coup.h).possible and isintwodiag(coup.x,coup.y,coup.h,quel,version) then if adver(7).rangee(quel,version).possible then if adver(c).rangee(x,coup.h).nbre_boule=2 and adver(7).rangee(quel,version).nbre_boule=2 then poid:=poid+20; fi; fi; fi; x:=coup.y; od; if adver(1).rangee(coup.x,coup.h).possible then case adver(1).rangee(coup.x,coup.h).nbre_boule when 3:poid:=poid+80; otherwise poid:=poid+1; esac; n:=n+1; fi; if adver(2).rangee(coup.y,coup.h).possible then case adver(2).rangee(coup.y,coup.h).nbre_boule when 3:poid:=poid+80; otherwise poid:=1+poid; esac; n:=n+1; fi; if isindiag(coup.y,coup.h,quel) then if adver(3).rangee(coup.x,quel).possible then case adver(3).rangee(coup.x,quel).nbre_boule when 3:poid:=poid+80; otherwise poid:=poid+1; esac; n:=n+1; fi; fi; if isindiag(coup.x,coup.h,quel) then if adver(4).rangee(coup.y,quel).possible then case adver(4).rangee(coup.y,quel).nbre_boule when 3:poid:=poid+80; otherwise poid:=poid+1; esac; n:=n+1; fi; fi; if adver(5).rangee(coup.x,coup.y).possible then case adver(5).rangee(coup.x,coup.y).nbre_boule when 3:poid:=poid+80; otherwise poid:=poid+1; esac; n:=n+1; fi; if isinbigdiag(coup.x,coup.y,quel) then if adver(6).rangee(coup.h,quel).possible then case adver(6).rangee(coup.h,quel).nbre_boule when 3:poid:=poid+80; otherwise poid:=poid+1; esac; n:=n+1; fi; fi; if isintwodiag(coup.x,coup.y,coup.h,quel,version) then if adver(7).rangee(quel,version).possible then case adver(7).rangee(quel,version).nbre_boule when 3:poid:=poid+80; otherwise poid:=poid+1; esac; n:=n+1; fi; fi; if coinlibre and poid<20 then do pos:=round(random*3)+1; coup.x:=cointab(pos).x; coup.y:=cointab(pos).y; coup.h:=1; if pl.jeu(coup.x,coup.y,coup.h)=free then coin:=coin-1;poid:=poid+20; if coin=0 then coinlibre:=false; fi; exit; fi; od; fi; poid:=(-poid); e:=new element; e.x:=poid; e.i:=coup.x;e.j:=coup.y;e.h:=coup.h; call mem.inserer(e); fi; od; od; end; unit combinaison:class; var nb:integer, possible:boolean; unit incremente:function:integer; begin nb:=nb+1; result:=nb; end; unit plus:procedure; begin nb:=nb+1; end; unit nbre_boule:function:integer; begin result:=nb; end; unit elimine:procedure; begin possible:=false; end; begin nb:=0; possible:=true; END; begin mem:=new arbtas; array cointab dim(1:4); cointab(1):=new coord2D(1,1); cointab(2):=new coord2D(4,4); cointab(3):=new coord2D(1,4); cointab(4):=new coord2D(4,1); coinlibre:=true; coin:=4; block var i,j:integer; begin array adver dim (1:7); array moi dim (1:7); array posajouer dim(1:4); for i:=1 to 4 do array posajouer(i) dim(1:4); if (i<3) then adver(i):=new info(4,4); moi(i):=new info(4,4); else adver(i):=new info(4,2); moi(i):=new info(4,2); fi; od; adver(5):=new info(4,4); moi(5):=new info(4,4); adver(6):=new info(4,2); moi(6):=new info(4,2); adver(7):=new info(2,2); moi(7):=new info(2,2); for i:=1 to 4 do for j:=1 to 4 do posajouer(i,j):=1; od; od; end; return; place:=new coord3D(1,1,1); DO find:=false; call pl.arrow.ligne(pl.line,0); call pl.arrow.colonne(pl.col,0); (*****************************************) (* elimination de quelques combinaisons *) (*****************************************) if pl.haut<>0 then call addcombinaison(adver,pl.line,pl.col,pl.haut); call delcombinaison(moi,pl.line,pl.col,pl.haut); posajouer(pl.line,pl.col):=posajouer(pl.line,pl.col)+1; (*********************************) (*** est ce que j'ai gagne ? !!!!*) (*********************************) find:=troisboules(moi,place); (*********************************) (* contre des 3 boules align‚es *) (*********************************) if (pl.haut=1 and ((pl.line=4 or pl.line=1) and (pl.col=1 or pl.col=4))) then coin:=coin-1; fi; if coin=0 then coinlibre:=false; fi; if not find then if (adver(1).rangee(pl.line,pl.haut).nbre_boule=3) and (adver(1).rangee(pl.line,pl.haut).possible) then find:=find_place(1,0,pl.line,pl.haut,place); fi; if (adver(2).rangee(pl.col,pl.haut).nbre_boule=3) and (adver(2).rangee(pl.col,pl.haut).possible) then find:=find_place(2,0,pl.col,pl.haut,place); fi; if (adver(5).rangee(pl.line,pl.col).nbre_boule=3) and (adver(5).rangee(pl.line,pl.col).possible) then find:=find_place(5,0,pl.line,pl.col,place); fi; if isindiag(pl.col,pl.haut,quel) then if (adver(3).rangee(pl.line,quel).nbre_boule=3) and (adver(3).rangee(pl.line,quel).possible) then find:=find_place(3,quel,pl.line,pl.haut,place); fi; fi; if isindiag(pl.line,pl.haut,quel) then if (adver(4).rangee(pl.col,quel).nbre_boule=3) and (adver(4).rangee(pl.col,quel).possible) then find:=find_place(4,quel,pl.col,pl.haut,place); fi; fi; if isinbigdiag(pl.line,pl.col,quel) then if (adver(6).rangee(pl.haut,quel).nbre_boule=3) and (adver(6).rangee(pl.haut,quel).possible) then find:=find_place(6,quel,pl.line,pl.haut,place); fi; fi; if isintwodiag(pl.line,pl.col,pl.haut,quel,version) then if (adver(7).rangee(quel,version).nbre_boule=3) and (adver(7).rangee(quel,version).possible) then find:=find_place(7,0,quel,version,place); fi; fi; fi; fi; (******************************************) (* jouer les coins du niveau 1 en premier *) (******************************************) IF not find then (*********************) (* quel coup jouer ? *) (*********************) call stratego; (* evaluation de toutes les combinaisons*) call selectcoup(place); (* choisi un coup a jouer *) FI; (*****************************************) (* on incremente le nombre de boules... *) (*****************************************) call addcombinaison(moi,place.x,place.y,place.h); call delcombinaison(adver,place.x,place.y,place.h); posajouer(place.x,place.y):=posajouer(place.x,place.y)+1; if pl.enfiler(place.x,place.y,couleur) then call pl.arrow.ligne(place.x,blanc); call pl.arrow.colonne(place.y,blanc); fi; detach; od; end; UNIT humain:player COROUTINE; var i,j:integer; begin i,j:=1; return; do do call pl.arrow.selectaxe(i,j); if pl.enfiler(i,j,couleur) then exit; fi; od; detach; od; end; UNIT joueurs:class; var couleur:integer, joueur:player, nom:arrayof char; begin array nom dim(1:8); end; UNIT controle:iiuwgraph coroutine(equipe:arrayof joueurs,pl:Plateau_Jeu); var tour:integer, aux: arrayof arrayof arrayof integer, difference: pile, pion:elem; UNIT AquiLeTour:procedure; begin tour:=tour+1; if tour=3 then tour:=1; fi; end; UNIT copie_jeu:procedure; var k:integer; begin for k:=1 to 4 do aux(pl.line,pl.col,k):=pl.jeu(pl.line,pl.col,k); od; end; UNIT coup:function:boolean; var i,j,k,n,c:integer; begin call pl.arrow.ligne(pl.line,0); call pl.arrow.colonne(pl.col,0); n:=0; for i:=1 to 4 do for j:=1 to 4 do for k:=1 to 4 do if (pl.jeu(i,j,k)<>aux(i,j,k)) then n:=n+1; pion:=new elem(i,j,k); call difference.empiler(pion); fi; od; od; od; if n>1 or n=0 then result:=false; else pion:=difference.sommet; if pl.jeu(pion.i,pion.j,pion.k)=equipe(tour).couleur then result:=true; pl.line:=pion.i;pl.col:=pion.j;pl.haut:=pion.k; call pl.arrow.ligne(pl.line,blanc); call pl.arrow.colonne(pl.col,blanc); else result:=false; fi; fi; end; unit alignee_ligne:function(couleur:integer):integer; var a,n:integer; begin n:=0; for a:=1 to 4 do if pl.jeu(a,pion.j,pion.k)=couleur then n:=n+1; fi; od; result:=n; end; unit colhaut:function(couleur:integer):integer; var a,n:integer; begin n:=0; for a:=1 to 4 do if pl.jeu(pion.i,pion.j,a)=couleur then n:=n+1; fi; od; result:=n; end; unit alignee_colonne:function(couleur:integer):integer; var j,n:integer; begin n:=0; for j:=1 to 4 do if pl.jeu(pion.i,j,pion.k)=couleur then n:=n+1; fi; od; result:=n; end; unit diag_colonne:function(dir,couleur:integer):integer; var k,i,n:integer; begin n:=0;i:=1; if dir=-1 then k:=4; else k:=1; fi; for i:=1 to 4 do if pl.jeu(i,pion.j,k)=couleur then n:=n+1; fi; k:=k+(1*dir); od; result:=n; end; unit diagonnale: function(quel,couleur:integer):integer; var n,j,i:integer; begin n:=0; if quel=11 then j:=1; for i:=1 to 4 do if pl.jeu(i,j,pion.k)=couleur then n:=n+1; fi; j:=j+1; od; else j:=1; for i:=4 downto 1 do if pl.jeu(i,j,pion.k)=couleur then n:=n+1; fi; j:=j+1; od; fi; result :=n; end; unit doublediagonnale: function(quel,dir,couleur:integer):integer; var n,i,j,k:integer; begin n:=0;i:=1; if dir=-1 then k:=4; else k:=1; fi; if quel=11 then j:=1; for i:=1 to 4 do if pl.jeu(i,j,k)=couleur then n:=n+1; fi; j:=j+1;k:=k+(1*dir); od; else j:=1; for i:=4 downto 1 do if pl.jeu(i,j,k)=couleur then n:=n+1; fi; j:=j+1; k:=k+(1*dir); od; fi; result :=n; end; unit diag_ligne:function(dir,couleur:integer):integer; var k,j,n:integer; begin n:=0;j:=1; if dir=-1 then k:=4; else k:=1; fi; for j:=1 to 4 do if pl.jeu(pion.i,j,k)=couleur then n:=n+1; fi; k:=k+(1*dir); od; result:=n; end; UNIT gagne:function:boolean; const droite=-1,gauche=1; var rangee:boolean; begin pion:=difference.sommet; rangee:=false; if alignee_ligne(equipe(tour).couleur)=4 then rangee:=true; fi; if alignee_colonne(equipe(tour).couleur)=4 then rangee:=true; fi; if diag_colonne(droite,equipe(tour).couleur)=4 then rangee:= true;fi; if diag_colonne(gauche,equipe(tour).couleur)=4 then rangee:=true; fi; if diag_ligne(droite,equipe(tour).couleur)=4 then rangee:= true; fi; if diag_ligne(gauche,equipe(tour).couleur)=4 then rangee:= true; fi; if colhaut(equipe(tour).couleur)=4 then rangee:=true; fi; if diagonnale(11,equipe(tour).couleur)=4 then rangee:=true; fi; if doublediagonnale(11,droite,equipe(tour).couleur)=4 then rangee:=true;fi; if doublediagonnale(11,gauche,equipe(tour).couleur)=4 then rangee:=true; fi; if diagonnale(41,equipe(tour).couleur)=4 then rangee:=true; fi; if doublediagonnale(41,droite,equipe(tour).couleur)=4 then rangee:=true; fi; if doublediagonnale(41,gauche,equipe(tour).couleur)=4 then rangee:=true; fi; result:=rangee; call difference.depiler; (* pile est maintenant vide *) end; UNIT restore:procedure; begin while (not (difference.vide)) do pion:=difference.sommet; pl.jeu(pion.i,pion.j,pion.k):=aux(pion.i,pion.j,pion.k); call pl.boulle(pion.i,pion.j,pion.k,aux(pion.i,pion.j,pion.k)); call difference.depiler; od; end; UNIT nom_joueur: gestion_caractere procedure(nom:arrayof char,couleur:integer); var i,j:integer; begin call dialog1; call color(couleur); for i:=1 to 20 do call move(430,240+i); call draw(450,240+i); od; call displaystring(nom,460,245,blanc); end; begin block var i,j,k:integer; begin array aux dim(1:4); for i:=1 to 4 do array aux(i) dim(1:4); for j:=1 to 4 do array aux(i,j) dim (1:4); od; od; for i:=1 to 4 do for j:=1 to 4 do for k:=1 to 4 do aux(i,j,k):=-1; od; od; od; end; difference:=new pile; call pl.initialisation; tour:=0; return; do call AquiLeTour; do call nom_joueur(equipe(tour).nom,equipe(tour).couleur); if equipe(tour).joueur is humain then call move(450,300); call outstring("A VOTRE TOUR !"); fi; attach(equipe(tour).joueur); call color(0); call move(450,300); call outstring(" "); if coup then exit; else call restore; fi; od; if gagne then attach(main); else call copie_jeu; fi; od; END; UNIT pause: IIUWGRAPH procedure(t:string,x,y,couleur:integer); var c:integer; begin call move(x,y); call color(couleur); call outstring(t); c:=inkey; do if c<>0 then exit; fi; c:=inkey; od; end; UNIT Plateau_Jeu: IIUWGRAPH class; VAR grille:arrayof arrayof coord2D, line,col,haut:integer, jeu: arrayof arrayof arrayof integer; UNIT cadre: procedure; begin call move(179,321); call draw(392,250); call draw(282,140); call draw(69,211); call draw(179,321); end; UNIT ombre: procedure(cx,cy,cxx,cyy,fill_color:integer); var x,y,xx,yy,i:integer; begin call move(cx,cy); call draw(cxx,cyy); xx:=cxx; yy:=cyy; x:=cx; y:=cy; for i:=1 to 109 do x:=x+1; y:=y+1; xx:=xx+1; yy:=yy+1; call move(x,y); call draw(xx,yy); od; end; UNIT enlever:procedure(a,b:integer); var niveau:integer, occupe:boolean; begin niveau:=4; occupe:=false; while not occupe do occupe:=(jeu(a,b,niveau)<>free); if not occupe then niveau:=niveau-1; fi; od; jeu(a,b,niveau):=free; end; UNIT enfiler:function(a,b,couleur:integer):boolean; var niveau,c:integer, libre:boolean; begin niveau:=5; libre:=true; while libre do niveau:=niveau-1; if niveau<>0 then libre:= (jeu(a,b,niveau)=-1); else libre:=false; fi; od; niveau:=niveau+1; if niveau=5 then result:=false; else jeu(a,b,niveau):=couleur; call boulle(grille(b,a).x,grille(b,a).y,niveau,couleur); result:=true; fi; end; UNIT boulle:procedure(x,y,h,couleur:integer); begin call color(couleur); call move(x,y-(26*(h-1))); call draw(x,y-(26*(h-1))-26); call move(x+1,y-(26*(h-1))-1); call draw(x+1,y-(26*(h-1))-26); call move(x-1,y-(26*(h-1))-1); call draw(x-1,y-(26*(h-1))-26); call move(x+1,y-(26*(h-1))+1); call draw(x+1,y-(26*(h-1))-26); end; UNIT axe: procedure(x,y:integer); begin call move(x+1,y-1); call draw(x+1,y-108); call move(x,y); call draw(x,y-108); call move(x-1,y-1); call draw(x-1,y-108); call move(x+1,y+1); call draw(x+1,y-108); end; UNIT plan: procedure(x,y,i:integer); var xx,yy:integer; begin xx:=x; yy:=y; call axe(xx,yy); grille(i,1):=new coord2D(xx,yy); xx:=xx-42; yy:=yy-42; call axe(xx,yy); grille(i,2):=new coord2D(xx,yy); call move(xx,yy); call draw(136,278); xx:=xx-26; yy:=yy-26; call axe(xx,yy); grille(i,3):=new coord2D(xx,yy); call move(xx,yy); call draw(110,252); xx:=xx-41; yy:=yy-41; call axe(xx,yy); grille(i,4):=new coord2D(xx,yy); call move(xx,yy); call draw(x,y); end; unit rangee: procedure; begin call plan(round(213*0.38)+178,round(-71*0.38)+320,2); call plan(round(213*0.65)+178,round(-71*0.65)+320,3); call plan(213+178,-71+320,4); end; UNIT initialisation:procedure; var i,j,k:integer; begin for i:=1 to 4 do for j:=1 to 4 do for k:=1 to 4 do jeu(i,j,k):=-1; od; od; od; for i:=1 to 4 do for j:=1 to 4 do call boulle(grille(i,j).x,grille(i,j).y,3,blanc); call boulle(grille(i,j).x,grille(i,j).y,1,blanc); call boulle(grille(i,j).x,grille(i,j).y,4,blanc); call boulle(grille(i,j).x,grille(i,j).y,2,blanc); od; od; end; UNIT fleche: class; var tab_coord:arrayof arrayof coord2D; unit ligne:procedure(i,couleur:integer); var y1:integer; begin call color(couleur); y1:=(-(tab_coord(1,i).x-20)+tab_coord(1,i).x+3*tab_coord(1,i).y)div 3; call move(tab_coord(1,i).x,tab_coord(1,i).y); call draw(tab_coord(1,i).x-20,y1); y1:=(-(tab_coord(1,i).x-5)+tab_coord(1,i).x+3*tab_coord(1,i).y)div 3; call move(tab_coord(1,i).x-5-3,y1-3); call draw(tab_coord(1,i).x,tab_coord(1,i).y); call move(tab_coord(1,i).x,tab_coord(1,i).y+5); call draw(tab_coord(1,i).x,tab_coord(1,i).y); end; unit colonne:procedure(i,couleur:integer); begin call color(couleur); call move(tab_coord(2,i).x,tab_coord(2,i).y); call draw(tab_coord(2,i).x+15,tab_coord(2,i).y+15); call move(tab_coord(2,i).x,tab_coord(2,i).y); call draw(tab_coord(2,i).x+5,tab_coord(2,i).y); call move(tab_coord(2,i).x,tab_coord(2,i).y); call draw(tab_coord(2,i).x,tab_coord(2,i).y+5); end; UNIT SelectAxe:procedure(inout i,j:integer); const droite=-77,gauche=-75,hauts=-72,bas=-80,retour=13; var key:integer; begin call drawrect(0,0,413,349,rouge); call ligne(line,15); call colonne(col,15); do do key:=inkey; if key<>0 then exit; fi; od; case key when hauts : call ligne(line,0); if line+1<=4 then line:=line+1;fi; call ligne(line,15); when bas : call ligne(line,0); if line-1>=1 then line:=line-1; fi; call ligne(line,15); when gauche : call colonne(col,0); if col-1>=1 then col:=col-1; fi; call colonne(col,15); when droite : call colonne(col,0); if col+1<=4 then col:=col+1; fi; call colonne(col,15); when retour : i:=line; j:=col; exit; esac; od; call ligne(line,0); call colonne(col,0); call drawrect(0,0,413,349,blanc); end; begin array tab_coord dim(1:2); for line:=2 downto 1 do array tab_coord(line) dim(1:4); od; line:=line+1; tab_coord(1,4):=new coord2D(53,219); tab_coord(1,3):=new coord2D(92,258); tab_coord(1,2):=new coord2D(116,282); tab_coord(1,1):=new coord2D(160,326); tab_coord(2,1):=new coord2D(190,332); tab_coord(2,2):=new coord2D(271,305); tab_coord(2,3):=new coord2D(328,286); tab_coord(2,4):=new coord2D(398,256); end; var arrow:fleche; BEGIN block var i,j:integer; begin call gron(1); array grille dim(1:4); for i:=1 to 4 do array grille(i) dim(1:4); od; array jeu dim(1:4); for i:=1 to 4 do array jeu(i) dim(1:4); for j:=1 to 4 do array jeu(i,j) dim (1:4); od; od; call color(grisfonce); call ombre(69,223,282,152,4); call color(grisclair); call ombre(69,211,282,140,0); call color(blanc); call plan(178,320,1); call rangee; call cadre; call move(440,10); call outstring("PUISSANCE 4 CHINOIS"); call drawrect(418,220,620,349,blanc); call drawrect(0,0,413,349,blanc); line,col:=2; haut:=0; arrow:= new fleche; end; END; (* fin Plateau_Jeu *) UNIT menu: gestion_caractere function:integer; var choix:integer; begin call dialog2; call drawrect(418,220,620,349,blanc); call drawrect(418,50,620,200,rouge); call color(blanc); call move(480,60); call outstring(" OPTIONS "); call move(420,80); call outstring("[1] Un joueur"); call move(420,100); call outstring("[2] Deux joueurs"); call move(420,120); call outstring("[0] Quitter"); call move(470,180); call outstring("Votre choix :"); do choix:=ConvENT(saisie(1,1,570,180)); if choix>=0 and choix<=2 then exit; fi; od; result:=choix; call drawrect(418,50,620,200,blanc); call drawrect(418,220,620,349,rouge); end; UNIT withwho: gestion_caractere function:integer; var choix:integer; begin call dialog2; call drawrect(418,220,620,349,blanc); call drawrect(418,50,620,200,rouge); call color(blanc); call move(480,60); call outstring(" OPTIONS "); call move(420,80); call outstring("[1] Ordinateur"); call move(440,90); call outstring(" contre Vous"); call move(420,110); call outstring("[2] Ordinateur"); call move(440,120); call outstring(" contre Ordinateur"); call move(420,140); call outstring("[0] Retour"); call move(470,180); call outstring("Votre choix :"); do choix:=ConvENT(saisie(1,1,570,180)); if choix>=0 and choix<=2 then exit; fi; od; result:=choix; call drawrect(418,50,620,200,blanc); call drawrect(418,220,620,349,rouge); end; UNIT dialog1:iiuwgraph procedure; var i:integer; begin call color(0); for i:=1 to 108 do call move(419,220+i); call draw(619,220+i); od; end; UNIT dialog2:iiuwgraph procedure; var i:integer; begin call color(0); for i:=1 to 148 do call move(419,51+i); call draw(619,51+i); od; end; UNIT name:gestion_caractere function(i:integer):arrayof char; begin call dialog1; call drawrect(418,220,620,349,rouge); call color(blanc); call move(420,230); if i=1 then call outstring("Nom du joueur 1:"); else call outstring("Nom du joueur 2:"); fi; result:=saisie(2,8,430,250); call drawrect(418,220,620,349,blanc); end; UNIT whostart:gestion_caractere function:integer; var i,c,a:integer; begin call dialog1; call drawrect(418,220,620,349,rouge); call color(blanc); call move(420,230); call outstring(" Voulez-vous que"); call move(420,240); call outstring("je commence la partie ?"); i:=1; call move(440,260); call color(grisfonce); call outstring("NON"); call move(540,260); call color(grisclair); call outstring("OUI"); c:=inkey; while c<>13 do if c<>0 then i:=i+1; if i>2 then i:=1; fi; case i when 1:call move(440,260); call color(grisfonce); call outstring("NON"); call move(540,260); call color(grisclair); call outstring("OUI"); when 2:call move(440,260); call color(grisclair); call outstring("NON"); call move(540,260); call color(grisfonce); call outstring("OUI"); esac; fi; c:=inkey; od; result:=i; end; unit thegame: gestion_caractere procedure; var a:integer; begin call dialog2; call displaystring(team(1).nom,430,90,bleuroi); call move(490,120); call color(blanc); call outstring("contre"); call displaystring(team(2).nom,530,150,bleuroi); end; UNIT quelcouleur:gestion_caractere function(t:arrayof char):integer; const droite=-77,gauche=-75; var i,c,a:integer; begin call dialog1; call drawrect(418,220,620,349,rouge); call displaystring(t,420,230,blanc); call move(440,250); call outstring("Boule:"); c:=inkey; i:=1;a:=2; if i=boule then i:=i+1; a:=a+1 fi; call move(500,250); call color(i); call outstring(""); call displaystring(unpack("->:couleur suivante"),420,310,grisfonce); call displaystring(unpack("<-:couleur pr‚c‚dente"),420,320,grisfonce); while c<>13 do if c<>0 then case c when droite: i:=i+1; if i>14 then i:=1; fi; if i=boule then i:=i+1; fi; if i>14 then i:=1; fi; when gauche: i:=i-1; if i<1 then i:=14; fi; if i=boule then i:=i-1;fi; if i<1 then i:=14; fi; esac; fi; if i<>a then a:=i; call move(500,250); call color(i); call outstring(""); fi; c:=inkey; od; result:=i; call drawrect(418,220,620,349,blanc); end; signal quitter,gagner; VAR plateau:plateau_jeu, team: arrayof joueurs, c,i,j,boule:integer, partie:boolean, arbitre:controle; handlers when quitter: pref iiuwgraph block begin kill(arbitre); kill(team(1).joueur); kill(team(2).joueur); kill(team(1)); kill(team(2)); call groff; end; wind; when gagner: pref iiuwgraph block begin kill(team(1).joueur); kill(team(2).joueur); kill(arbitre); call color(0); call move(450,270); call outstring(" "); call color(rouge); call move(500,270); call outstring(" A GAGNE !"); end; return; end; BEGIN plateau:=new plateau_jeu; array team dim(1:2); team(1):=new joueurs; team(2):=new joueurs; pref gestion_caractere block begin do boule:=0; partie:=false; case menu when 2:team(1).nom:=name(1); team(1).couleur:=quelcouleur(team(1).nom); boule:=team(1).couleur; team(1).joueur:=new humain(team(1).couleur,plateau); team(2).nom:=name(2); team(2).couleur:=quelcouleur(team(2).nom); team(2).joueur:=new humain(team(2).couleur,plateau); partie:=true; when 1: case withwho when 1: case whostart when 2:team(1).nom:=name(1); team(1).couleur:=quelcouleur(team(1).nom); boule:=team(1).couleur; team(1).joueur:=new humain(team(1).couleur,plateau); team(2).nom:=unpack("COMPUTER"); team(2).couleur:=quelcouleur(team(2).nom); team(2).joueur:=new ordi(team(2).couleur,plateau); partie:=true; when 1:team(2).nom:=name(2); team(2).couleur:=quelcouleur(team(2).nom); boule:=team(2).couleur; team(2).joueur:=new humain(team(2).couleur,plateau); team(1).nom:=unpack("COMPUTER"); team(1).couleur:=quelcouleur(team(1).nom); team(1).joueur:=new ordi(team(1).couleur,plateau); partie:=true; esac; when 2:team(1).nom:=unpack("Computer1"); team(1).couleur:=quelcouleur(team(1).nom); boule:=team(1).couleur; team(1).joueur:=new ordi(team(1).couleur,plateau); team(2).nom:=unpack("Computer2"); team(2).couleur:=quelcouleur(team(2).nom); team(2).joueur:=new ordi(team(2).couleur,plateau); partie:=true; esac; when 0: raise quitter; esac; if partie then call thegame; arbitre:=new controle(team,plateau); attach(arbitre); raise gagner; kill(arbitre); fi; od; end; END;