program morp3d; (***************************************************************************) (* Fabien JOBIN Fr‚d‚ric GAUTIER *) (* LICENCE INFORMATIQUE 1995 *) (* 2eme Groupe *) (* MORPION en 3 DIMENSIONS *) (***************************************************************************) begin pref iiuwgraph block begin pref mouse block (* Fonction de lecture au clavier *) unit inchar:function:integer; var i:integer; begin do i:=inkey; if i<>0 then exit fi; od; result:=i; end inchar; (*--------------------------------------------------------------------------*) (* OPERATIONS SUR LA MATRICE EN 3 DIMENSION *) (*--------------------------------------------------------------------------*) (* Description d'un ‚l‚ment d'une matrice en 3 dimensions *) (* val : valeur du cube plac‚e par le joueur lorsqu'il colorie celui-ci*) (* marque : indique si le cube a ‚t‚ jou‚ (= 1) ou non (=0) *) (* x,y : position du cube … l'‚cran *) unit elem:class; var x,y,val,marque:integer; end elem; (* Description d'une matrice en 3 dimensions *) unit mat_3d:class(l,c,e:integer); (* Copie le contenu d'une matrice 3d dans une autre *) unit copy_mat3d:function:mat_3d; var i,j,k:integer; begin result:=new mat_3d(l,c,e); for i:=1 to l do for j:=1 to c do for k:=1 to e do result.tab(i,j,k).val := tab(i,j,k).val; result.tab(i,j,k).marque := tab(i,j,k).marque; result.tab(i,j,k).x := tab(i,j,k).x; result.tab(i,j,k).y := tab(i,j,k).y; od; od; od; end copy_mat3d; var tab:arrayof arrayof arrayof elem, i,j,k:integer; begin array tab dim(1:l); for i:=1 to l do array tab(i) dim (1:c); od; for i:=1 to l do for j:=1 to c do array tab(i,j) dim (1:e); od; od; for i:=1 to l do for j:=1 to c do for k:=1 to e do tab(i,j,k) := new elem; od; od; od; end mat_3d; (* Initialise la matrice *) unit init_mat:procedure(inout mat:mat_3d); var i,j,k,x,y:integer; begin for i:=1 to mat.l do for j:=1 to mat.c do x := 292-((j-1)*20); y := 100+((j-1)*20)+((i-1)*110); for k:=1 to mat.e do mat.tab(i,j,k).x :=x; mat.tab(i,j,k).y :=y; mat.tab(i,j,k).val := 0; mat.tab(i,j,k).marque := 0; x := x + 25; od; od; od; end init_mat; (*--------------------------------------------------------------------------*) (* GRAPHISMES *) (*--------------------------------------------------------------------------*) (*-------- DESSIN DE LA MATRICE, D'UN ELEMENT DE LA MATRICE, ... -----------*) (* Dessin d'un carr‚ de face *) unit carre_face:procedure(x,y,c,ep,coul,vide:integer); begin if vide = 1 then (* carre de face vide *) call patern(x,y,x+c,y+c,15,0); else (* carre de face plein *) (* partie cadre noir *) call patern(x+1,y+1,x+c-1,y+c-1,0,0); (* partie pleine *) call patern(x+2,y+2,x+c-2,y+c-2,coul,1); fi; end carre_face; (* Dessin d'un carr‚ haut *) unit carre_haut:procedure(x,y,c,ep,coul,vide:integer); var i:integer; begin if vide = 1 then (* carre haut vide *) call color(15); call move(x,y); call draw(x+ep,y-ep); call draw(x+ep+c,y-ep); call draw(x+c,y); else (* carre haut plein *) (* partie cadre noir *) call color(0); call move(x+2,y-1); call draw(x+ep,y-ep+1); call draw(x+c+ep-2,y-ep+1); call draw(x+c,y-1); call draw(x+2,y-1); (* partie pleine *) call color(coul); for i:=2 to 22 do call move(x+2+i,y-2); call draw(x+ep,y-ep+2); call draw(x+ep+c-2-i,y-ep+2); call draw(x+c,y-2); call draw(x+2+i,y-2); od; fi; end carre_haut; (* Dessin d'un carr‚ droit *) unit carre_droit:procedure(x,y,c,ep,coul,vide:integer); var i:integer; begin if vide = 1 then (* carre droit vide *) call color(15); call move(x+c,y+c); call draw(x+c+ep,y+c-ep); call draw(x+c+ep,y-ep); else (* carre droit plein *) (* partie cadre noir *) call color(0); call move(x+c+1,y+c-2); call draw(x+c+ep-1,y+c-ep); call draw(x+c+ep-1,y-ep+2); call draw(x+c+1,y); call draw(x+c+1,y+c-2); (* partie pleine *) call color(coul); for i:=2 to 22 do call move(x+c+2,y+c-2-i); call draw(x+c+ep-2,y+c-ep); call draw(x+c+ep-2,y-ep+2+i); call draw(x+c+2,y); call draw(x+c+2,y+c-2-i); od; fi; end carre_droit; (* Un cube est le dessin d'un ‚l‚ment d'une matrice en 3 dimensions *) (* Un cube (3d) est compos‚ : *) (* - d'un carr‚ de face *) (* - d'un carr‚ haut *) (* - d'uncarr‚ droit *) (* x et y coordonn‚es du sommet en haut … gauche appartenant au carr‚ *) (* de face *) (* c : longueur du cot‚ du cube *) (* coul : couleur *) (* ep : epaisseur du cube *) unit cube:procedure(x,y,c,ep,coul,vide:integer); var i:integer; begin call carre_face(x,y,c,ep,coul,vide); call carre_haut(x,y,c,ep,coul,vide); call carre_droit(x,y,c,ep,coul,vide); end cube; (* Un plan est constitu‚ de 9 cubes *) (* x et y coordonn‚es du cube du fond … gauche *) unit plan:procedure(x,y,c,ep,coul:integer); begin (* cubes du fond *) call cube(x,y,c,ep,coul,1); call cube(x+c,y,c,ep,coul,1); call cube(x+2*c,y,c,ep,coul,1); (* cubes du milieu *) call cube(x-ep,y+ep,c,ep,coul,1); call cube(x-ep+c,y+ep,c,ep,coul,1); call cube(x-ep+2*c,y+ep,c,ep,coul,1); (* cubes du debut *) call cube(x-2*ep,y+2*ep,c,ep,coul,1); call cube(x-2*ep+c,y+2*ep,c,ep,coul,1); call cube(x-2*ep+2*c,y+2*ep,c,ep,coul,1); end plan; (* Une matrice en 3 dimensions est constitu‚e de 3 plans *) (* x et y coordonn‚es du plan en haut *) unit des_mat_3d:procedure(x,y,c,ep,coul:integer); begin (* plan en haut *) call plan(x,y,c,ep,coul); (* plan en bas *) call plan(x,y+4*ep+30,c,ep,coul); (* plan du milieu *) call plan(x,y+8*ep+60,c,ep,coul); end des_mat_3d; (* Affiche la matrice *) unit affic:procedure(c,ep:integer); var i,j,k:integer; begin for i:=1 to mat.l do for j:=1 to mat.c do for k:=1 to mat.e do call affic_elem(i,j,k,c,ep); od; od; od; end affic; (* Affiche un ‚l‚ment de la matrice *) unit affic_elem:procedure(i,j,k,c,ep:integer); var coul:integer; begin (* cubes dont le carre haut est visible *) if (mat.tab(i,j,k).x=292 or mat.tab(i,j,k).x=317 or mat.tab(i,j,k).x=272 or mat.tab(i,j,k).x=297) then if (mat.tab(i,j,k).y=100 or mat.tab(i,j,k).y=120 or mat.tab(i,j,k).y=210 or mat.tab(i,j,k).y=230 or mat.tab(i,j,k).y=320 or mat.tab(i,j,k).y=340) then if mat.tab(i,j,k).val = 0 then coul:=0; else if mat.tab(i,j,k).val = 1 then coul:=12; else if mat.tab(i,j,k).val = 2 then coul:=10; else if mat.tab(i,j,k).val = 3 or mat.tab(i,j,k).val = 4 then coul:=9; else if mat.tab(i,j,k).val = 9 then coul:=15; fi; fi; fi; fi; fi; call carre_haut(mat.tab(i,j,k).x, mat.tab(i,j,k).y,c,ep,coul,0); fi; else (* cubes dont le carre haut et le carre droit sont *) (* visibles *) if (mat.tab(i,j,k).x=342 or mat.tab(i,j,k).x=322) then if (mat.tab(i,j,k).y=100 or mat.tab(i,j,k).y=120 or mat.tab(i,j,k).y=210 or mat.tab(i,j,k).y=230 or mat.tab(i,j,k).y=320 or mat.tab(i,j,k).y=340) then if mat.tab(i,j,k).val = 0 then coul:=0; else if mat.tab(i,j,k).val = 1 then coul:=12; else if mat.tab(i,j,k).val = 2 then coul:=10; else if mat.tab(i,j,k).val = 3 or mat.tab(i,j,k).val = 4 then coul:=9; else if mat.tab(i,j,k).val = 9 then coul:=15; fi; fi; fi; fi; fi; call carre_haut(mat.tab(i,j,k).x, mat.tab(i,j,k).y,c,ep,coul,0); call carre_droit(mat.tab(i,j,k).x, mat.tab(i,j,k).y,c,ep,coul,0); fi; else (* cubes dont le carre haut et le carre face sont *) (* visibles *) if (mat.tab(i,j,k).x=252 or mat.tab(i,j,k).x=277) then if (mat.tab(i,j,k).y=140 or mat.tab(i,j,k).y=250 or mat.tab(i,j,k).y=360) then if mat.tab(i,j,k).val = 0 then coul:=0; else if mat.tab(i,j,k).val = 1 then coul:=12; else if mat.tab(i,j,k).val = 2 then coul:=10; else if mat.tab(i,j,k).val = 3 or mat.tab(i,j,k).val = 4 then coul:=9; else if mat.tab(i,j,k).val = 9 then coul:=15; fi; fi; fi; fi; fi; call carre_face(mat.tab(i,j,k).x, mat.tab(i,j,k).y,c,ep,coul,0); call carre_haut(mat.tab(i,j,k).x, mat.tab(i,j,k).y,c,ep,coul,0); fi; else (* cubes dont le carre haut,face et droit sont *) (* visibles *) if (mat.tab(i,j,k).x=302) then if (mat.tab(i,j,k).y=140 or mat.tab(i,j,k).y=250 or mat.tab(i,j,k).y=360) then if mat.tab(i,j,k).val = 0 then coul:=0; else if mat.tab(i,j,k).val = 1 then coul:=12; else if mat.tab(i,j,k).val = 2 then coul:=10; else if mat.tab(i,j,k).val = 3 or mat.tab(i,j,k).val = 4 then coul:=9; else if mat.tab(i,j,k).val = 9 then coul:=15; fi; fi; fi; fi; fi; call cube(mat.tab(i,j,k).x, mat.tab(i,j,k).y,c,ep,coul,0); fi; fi; fi; fi; fi; end affic_elem; (* recherche_elem donne i,j,k en fonction de x et y *) (* Ceci permet d'acc‚der aux indices d'un ‚l‚ment *) (* de la matrice en fonction de la position de la *) (* case (ou du cube) … l'‚cran. *) unit recherche_elem:procedure(x,y:integer;output i,j,k:integer); var trouve:boolean; begin trouve:=false; i:=1; while (i<=mat.l and not trouve) do j:=1; while (j<=mat.c and not trouve) do k:=1; while (k<=mat.e and not trouve) do if (mat.tab(i,j,k).x =x and mat.tab(i,j,k).y =y) then trouve:=true; fi; k:=k+1; od; j:=j+1; od; i:=i+1; od; i:=i-1;j:=j-1;k:=k-1; end recherche_elem; (* indique si le point (x1,y1) est en_dessous du segment de droite *) (* passant par (x2,y2) et (x3,y3) *) (* Ceci permet de savoir si le pointeur de la souris est sur un *) (* carre haut ou un carre droit du cube. En effet, ces carr‚s ont *) (* des c“t‚s inclin‚s. *) unit en_dessous:function(x1,y1,x2,y2,x3,y3:real):boolean; var y_calcul:real; begin y_calcul:=(( ((y2-y3)/(x2-x3)) )*(x1-x3))+y3; if y1 > y_calcul then result:=true; else result:=false; fi; end en_dessous; (* Cette proc‚dure colorie un cube *) unit coloriage:procedure(i,j,k,val:integer); begin if val = 3 or val = 4 then if mat.tab(i,j,k).marque=0 then (* Le joueur 1 colorie un cube *) if val = 3 then mat.tab(i,j,k).val:=1 fi; (* Le joueur 2 colorie un cube *) if val = 4 then mat.tab(i,j,k).val:=4 fi; (* la saisie est prise en compte *) mat.tab(i,j,k).marque:=1; joue:=true; fi; else if mat.tab(i,j,k).marque=0 then (* Coloriage ou effacage du coloriage d'un cube *) (* cette saisie n'est pas prise en compte *) (* le joueur2 colorie le cube *) if val = 2 then val:=val+2 fi; mat.tab(i,j,k).val:=val; fi; fi; end coloriage; (* Effectue la modification d'un ‚l‚ment de la matrice. *) (* A partir des coordonn‚es du pointeur de la souris *) (* qui d‚signe un cube … l'‚cran, on accŠde … un *) (* ‚l‚ment de la matrice, on colorie le cube en fonction *) (* du joueur et on affiche le cube … l'‚cran. *) unit modification:procedure(xmouse,ymouse,ep,c,val,cpt:integer); var i,j,k:integer; begin (* Point dans cube en haut … gauche *) if (xmouse>=292 and xmouse<=292+ep+c and ymouse<=100+cpt and ymouse>=100-ep+cpt and en_dessous(xmouse,ymouse,292,100+cpt,292+ep,100-ep+cpt) and not(en_dessous(xmouse,ymouse,292+c,100+cpt,292+ep+c,100-ep+cpt))) then call recherche_elem(292,100+cpt,i,j,k); call coloriage(i,j,k,val); call affic_elem(i,j,k,c,ep); else (* Point dans cube en haut au milieu *) if (xmouse>=317 and xmouse<=317+ep+c and ymouse<=100+cpt and ymouse>=100-ep+cpt and en_dessous(xmouse,ymouse,317,100+cpt,317+ep,100-ep+cpt) and not(en_dessous(xmouse,ymouse,317+c,100+cpt,317+ep+c,100-ep+cpt))) then call recherche_elem(317,100+cpt,i,j,k); call coloriage(i,j,k,val); call affic_elem(i,j,k,c,ep); else (* Point dans cube en haut … droite *) if ((xmouse>=342 and xmouse<=342+ep+c and ymouse<=100+cpt and ymouse>=100-ep+cpt and en_dessous(xmouse,ymouse,342,100+cpt,342+ep,100-ep+cpt) and not(en_dessous(xmouse,ymouse,342+c,100+cpt,342+ep+c,100-ep+cpt))) or (xmouse>=342+c and xmouse<=342+ep+c and ymouse<=100+c+cpt and ymouse>=100-ep+cpt and en_dessous(xmouse,ymouse,342+c,100+cpt,342+ep+c,100-ep+cpt) and not(en_dessous(xmouse,ymouse,342+c,100+c+cpt,342+ep+c,100-ep+c+cpt)))) then call recherche_elem(342,100+cpt,i,j,k); call coloriage(i,j,k,val); call affic_elem(i,j,k,c,ep); else (* Point dans cube au milieu … gauche *) if (xmouse>=272 and xmouse<=272+ep+c and ymouse<=120+cpt and ymouse>=120-ep+cpt and en_dessous(xmouse,ymouse,272,120+cpt,272+ep,120-ep+cpt) and not(en_dessous(xmouse,ymouse,272+c,120+cpt,272+ep+c,120-ep+cpt))) then call recherche_elem(272,120+cpt,i,j,k); call coloriage(i,j,k,val); call affic_elem(i,j,k,c,ep); else (* Point dans cube au milieu au milieu *) if (xmouse>=297 and xmouse<=297+ep+c and ymouse<=120+cpt and ymouse>=120-ep+cpt and en_dessous(xmouse,ymouse,297,120+cpt,297+ep,120-ep+cpt) and not(en_dessous(xmouse,ymouse,297+c,120+cpt,297+ep+c,120-ep+cpt))) then call recherche_elem(297,120+cpt,i,j,k); call coloriage(i,j,k,val); call affic_elem(i,j,k,c,ep); else (* Point dans cube au milieu … droite *) if ((xmouse>=322 and xmouse<=322+ep+c and ymouse<=120+cpt and ymouse>=120-ep+cpt and en_dessous(xmouse,ymouse,322,120+cpt,322+ep,120-ep+cpt) and not(en_dessous(xmouse,ymouse,322+c,120+cpt,322+ep+c,120-ep+cpt))) or (xmouse>=322+c and xmouse<=322+ep+c and ymouse<=120+c+cpt and ymouse>=120-ep+cpt and en_dessous(xmouse,ymouse,322+c,120+cpt,322+ep+c,120-ep+cpt) and not(en_dessous(xmouse,ymouse,322+c,120+c+cpt,322+ep+c,120-ep+c+cpt)))) then call recherche_elem(322,120+cpt,i,j,k); call coloriage(i,j,k,val); call affic_elem(i,j,k,c,ep); else (* Point dans cube en bas … gauche *) if ((xmouse>=252 and xmouse<=252+ep+c and ymouse<=140+cpt and ymouse>=140-ep+cpt and en_dessous(xmouse,ymouse,252,140+cpt,252+ep,140-ep+cpt) and not(en_dessous(xmouse,ymouse,252+c,140+cpt,252+ep+c,140-ep+cpt))) or (xmouse>=252 and xmouse<=252+c and ymouse<=140+c+cpt and ymouse>=140+cpt)) then call recherche_elem(252,140+cpt,i,j,k); call coloriage(i,j,k,val); call affic_elem(i,j,k,c,ep); else (* Point dans cube en bas au milieu *) if ((xmouse>=277 and xmouse<=277+ep+c and ymouse<=140+cpt and ymouse>=140-ep+cpt and en_dessous(xmouse,ymouse,277,140+cpt,277+ep,140-ep+cpt) and not(en_dessous(xmouse,ymouse,277+c,140+cpt,277+ep+c,140-ep+cpt))) or (xmouse>=277 and xmouse<=277+c and ymouse<=140+c+cpt and ymouse>=140+cpt)) then call recherche_elem(277,140+cpt,i,j,k); call coloriage(i,j,k,val); call affic_elem(i,j,k,c,ep); else (* Point dans cube en bas … droite *) if ((xmouse>=302 and xmouse<=302+ep+c and ymouse<=140+cpt and ymouse>=140-ep+cpt and en_dessous(xmouse,ymouse,302,140+cpt,302+ep,140-ep+cpt) and not(en_dessous(xmouse,ymouse,302+c,140+cpt,302+ep+c,140-ep+cpt))) or (xmouse>=302+c and xmouse<=302+ep+c and ymouse<=140+c+cpt and ymouse>=140-ep+cpt and en_dessous(xmouse,ymouse,302+c,140+cpt,302+ep+c,140-ep+cpt) and not(en_dessous(xmouse,ymouse,302+c,140+c+cpt,302+ep+c,140-ep+c+cpt))) or (xmouse>=302 and xmouse<=302+c and ymouse<=140+c+cpt and ymouse>=140+cpt)) then call recherche_elem(302,140+cpt,i,j,k); call coloriage(i,j,k,val); call affic_elem(i,j,k,c,ep); fi; fi; fi; fi; fi; fi; fi; fi; fi; end modification; (* Saisie (colorie) un ‚l‚ment de la matrice *) unit saisie:procedure(xmouse,ymouse,bouton_mouse,ep,c,num_joueur:integer); var val:integer; begin if bouton_mouse = 1 or bouton_mouse = 2 or bouton_mouse = 3 then (* Le joueur1 colorie le cube mais cette saisie *) (* n'est pas prise en compte (il ne joue pas) *) if bouton_mouse = 1 and num_joueur = 1 then val := 1 fi; (* Le joueur2 colorie le cube mais cette saisie *) (* n'est pas prise en compte (il ne joue pas) *) if bouton_mouse = 1 and num_joueur = 2 then val := 2 fi; (* Le joueur efface le coloriage du cube *) if bouton_mouse = 2 then val := 0 fi; (* Le joueur1 colorie un cube et cette saisie *) (* est prise en compte (le joueur joue) *) if bouton_mouse = 3 and num_joueur = 1 then val := 3 fi; (* Le joueur2 colorie un cube et cette saisie *) (* est prise en compte (le joueur joue) *) if bouton_mouse = 3 and num_joueur = 2 then val := 4 fi; (* Pointeur de la souris dans le plan en haut *) if (ymouse>=100-ep and ymouse<=140+ep) then call modification(xmouse,ymouse,ep,c,val,0); else (* Pointeur de la souris dans le plan au milieu *) if (ymouse>=210-ep and ymouse<=250+ep) then call modification(xmouse,ymouse,ep,c,val,110); else (* Pointeur de la souris dans le plan en bas *) if (ymouse>=320-ep and ymouse<=360+ep) then call modification(xmouse,ymouse,ep,c,val,220); fi; fi; fi; fi; end saisie; (* Affiche les 3 cubes align‚s par un joueur en les faisant *) (* clignoter *) unit affic_3_alignes:procedure(i1,j1,k1,i2,j2,k2,i3,j3,k3:integer); var val,l,k:integer; var image1,image2:arrayof integer; begin (* on sauvegarde la valeur des cubes *) val:=mat.tab(i1,j1,k1).val; array image1 dim(1:100); array image2 dim(1:100); (* image1 contient l'‚cran avec les 3 cubes de la couleur du joueur *) call move(0,0); image1:=getmap(640,480); (* On met 9 dans la valeur des cubes pour les faire afficher *) (* en blanc *) mat.tab(i1,j1,k1).val:=9; call affic_elem(i1,j1,k1,25,20); mat.tab(i2,j2,k2).val:=9; call affic_elem(i2,j2,k2,25,20); mat.tab(i3,j3,k3).val:=9; call affic_elem(i3,j3,k3,25,20); (* image2 contient l'‚cran avec les 3 cubes de couleur blanc *) call move(0,0); image2:=getmap(640,480); (* On remet les valeurs pr‚c‚dentes des cubes *) mat.tab(i1,j1,k1).val:=val; mat.tab(i2,j2,k2).val:=val; mat.tab(i3,j3,k3).val:=val; (* On fait afficher en alternance image1 et image2 *) for l:=1 to 7 do call move(0,0); call putmap(image1); for k:=1 to 100 do k:=k+1 od; call move(0,0); call putmap(image2); for k:=1 to 100 do k:=k+1 od; od; (* On restitue l'‚cran tel qu'il ‚tait avant le clignotement des 3 *) (* cubes *) call move(0,0); call putmap(image1); end affic_3_alignes; (*------------------- DESSIN DE BOUTON ET MESSAGE D'ERREUR -----------------*) (* Affichage d'un bouton *) unit bouton:procedure(x1,y1,x2,y2,x3,y3 : integer;chaine : string; couleur_fond,couleur1,couleur2,couleur3 : integer); begin call patern(x1,y1,x2,y2,couleur_fond,1); call color(couleur1); call move(x1,y1); call draw(x2,y1); call move(x1,y1); call draw(x1,y2); call move(x1+1,y1+1); call draw(x2-1,y1+1); call move(x1+1,y1+2); call draw(x2-2,y1+2); call move(x1+1,y1+1); call draw(x1+1,y2-1); call move(x1+2,y1+2); call draw(x1+2,y2-2); call color(couleur2); call move(x1,y2); call draw(x2,y2); call move(x1+1,y2-1); call draw(x2-1,y2-1); call move(x1+2,y2-2); call draw(x2-2,y2-2); call move(x2,y2); call draw(x2,y1); call move(x2-1,y2-1); call draw(x2-1,y1+1); call move(x2-2,y2-2); call draw(x2-2,y1+2); call outstring(x3,y3,chaine,couleur3,couleur_fond); end bouton; (* Cette proc‚dure affiche un message d'erreur *) unit message_erreur:procedure(x1,y1,x2,y2,x3,y3:integer;chaine1:string; x7:integer;chaine2:string;x4,y4,x5,y5,x6,y6:integer); var i : integer; var tab:arrayof integer; begin array tab dim(1:100); call move(x1,y1); tab:=getmap(x2,y2); call bouton(x1,y1,x2,y2,x3,y3,chaine1,12,15,6,14); call outstring(x7,y3+30,chaine2,14,0); call patern(x4-4,y4-4,x5+4,y5+4,0,1); call bouton(x4,y4,x5,y5,x6,y6,"OK",9,11,1,15); do d:=getpress(v,p,h,l,r,c); if c = 1 and (v>=x4 and v<=x5) and (p>=y4 and p<=y5) then exit; fi; od; call bouton(x4,y4,x5,y5,x6,y6,"OK",1,9,11,7); for i:=1 to 5000 do i := i + 1 od; call bouton(x4,y4,x5,y5,x6,y6,"OK",9,11,1,15); for i:=1 to 5500 do i := i + 1 od; call move(x1,y1); call putmap(tab); end message_erreur; (* Affiche le cadre d'un bouton *) unit cadre_bouton:procedure(x1,y1,x2,y2 : integer); begin call patern(x1-4,y1-4,x2+4,y2+4,0,1); end cadre_bouton; (*-- AFFICHAGE DE LA MATRICE PAR LES TOUCHES (haut, bas, droite, gauche) ---*) (* Copie un ‚l‚ment de la matrice dans un ‚l‚ment d'une autre matrice *) unit copy_elem:procedure(inout B:mat_3d;lb,cb,j:integer; A:mat_3d;la,ca,i:integer); begin B.tab(lb,cb,j).val := A.tab(la,ca,i).val; B.tab(lb,cb,j).marque := A.tab(la,ca,i).marque; end copy_elem; (* Affiche le contenu de la matrice vers le haut *) unit haut:procedure; var i,j:integer; var aux:mat_3d; begin aux := new mat_3d(3,3,3); call init_mat(aux); for j:=1 to 3 do for i:=1 to 3 do call copy_elem(aux,1,j,i,mat,j,3,i); od; for i:=1 to 3 do call copy_elem(aux,2,j,i,mat,j,2,i); od; for i:=1 to 3 do call copy_elem(aux,3,j,i,mat,j,1,i); od; od; mat := none; mat := aux.copy_mat3d; call affic(25,20); end haut; (* Affiche le contenu de la matrice vers le bas *) unit bas:procedure; var i,j:integer; var aux:mat_3d; begin aux := new mat_3d(3,3,3); call init_mat(aux); for j:=1 to 3 do for i:=1 to 3 do call copy_elem(aux,j,3,i,mat,1,j,i); od; for i:=1 to 3 do call copy_elem(aux,j,2,i,mat,2,j,i); od; for i:=1 to 3 do call copy_elem(aux,j,1,i,mat,3,j,i); od; od; mat := none; mat := aux.copy_mat3d; call affic(25,20); end bas; (* Affiche le contenu de la matrice vers la droite *) unit droit:procedure; var i,j:integer; var aux:mat_3d; begin aux := new mat_3d(3,3,3); call init_mat(aux); for j:=1 to 3 do for i:=1 to 3 do call copy_elem(aux,j,3,i,mat,j,i,1); od; for i:=1 to 3 do call copy_elem(aux,j,2,i,mat,j,i,2); od; for i:=1 to 3 do call copy_elem(aux,j,1,i,mat,j,i,3); od; od; mat := none; mat := aux.copy_mat3d; call affic(25,20); end droit; (* Affiche le contenu de la matrice vers la gauche *) unit gauche:procedure; var i,j:integer; var aux:mat_3d; begin aux := new mat_3d(3,3,3); call init_mat(aux); for j:=1 to 3 do for i:=1 to 3 do call copy_elem(aux,j,i,1,mat,j,3,i); od; for i:=1 to 3 do call copy_elem(aux,j,i,2,mat,j,2,i); od; for i:=1 to 3 do call copy_elem(aux,j,i,3,mat,j,1,i); od; od; mat := none; mat := aux.copy_mat3d; call affic(25,20); end gauche; (*-------------------------------- AIDE ------------------------------------*) (* Cette proc‚dure affiche l'aide du jeu *) unit aide:procedure; var i : integer; var tab:arrayof integer; begin array tab dim(1:100); call move(0,0); tab:=getmap(640,480); call bouton(10,10,630,470,0,0,"",12,15,6,14); call cadre_bouton(270,410,370,440); call bouton(270,410,370,440,310,417,"OK",9,11,1,15); call outstring(30,20,"REGLES DU JEU :",14,12); call outstring(50,35, "-Il s'agit d'aligner 3 cases de la",15,12); call outstring(330,35,"mˆme couleur que ce soit en ligne,",15,12); call outstring(30,50, "colonne ou diagonale.",15,12); call outstring(50,65, "-Chaque joueur colorie une case … ",15,12); call outstring(320,65,"tour de r“le. ",15,12); call outstring(50,80, "-Si les 27 cases ont ‚t‚ colori‚es",15,12); call outstring(330,80,"et qu'il n'y a pas 3 cases de la",15,12); call outstring(30,95,"mˆme couleur align‚es alors la ",15,12); call outstring(280,95,"partie est nulle.",15,12); call outstring(30,125,"MENU ET SOUS-MENUS :",14,12); call outstring(50,140,"-Pour s‚lectionner une option,",15,12); call outstring(300,140,"cliquez dessus avec le bouton gauche",15,12); call outstring(30,155,"de la souris.",15,12); call outstring(50,170,"-Pour sortir d'un sous-menu,",15,12); call outstring(280,170,"appuyez sur le bouton droit de la souris.",15,12); call outstring(50,185,"-Pour jouer, cliquez sur 'JEU'",15,12); call outstring(300,185,"puis cliquez sur 'Nouvelle partie'.",15,12); call outstring(50,200,"-Pour sauvegarder votre partie,",15,12); call outstring(310,200,"cliquez sur 'JEU' puis cliquez sur",15,12); call outstring(30,215,"'Enregistrer la partie'.",15,12); call outstring(50,230,"-Pour continuer une partie enregistr‚e,",15,12); call outstring(370,230,"cliquez sur 'JEU' puis cliquez",15,12); call outstring(30,245,"sur 'Charger une partie'.",15,12); call outstring(30,275,"COLORIER UNE CASE :",14,12); call outstring(50,290,"-Pour colorier une case sans",15,12); call outstring(290,290,"que cette saisie soit prise en compte,",15,12); call outstring(30,305,"cliquez sur la case avec le bouton gauche",15,12); call outstring(370,305,"de la souris.",15,12); call outstring(50,320,"-Pour effacer le coloriage d'une",15,12); call outstring(320,320,"case dont la saisie n'a pas ‚t‚ prise",15,12); call outstring(30,335,"en compte, cliquez sur la case avec le",15,12); call outstring(340,335,"bouton droit de la souris.",15,12); call outstring(50,350,"-Pour colorier une case et que cette",15,12); call outstring(350,350,"saisie soit en prise en compte,",15,12); call outstring(30,365,"cliquez sur la case avec les boutons droit et",15,12); call outstring(400,365,"gauche de la souris.",15,12); do d:=getpress(v,p,h,l,r,c); if c = 1 and (v>=270 and v<=370) and (p>=410 and p<=440) then exit; fi; od; call bouton(270,410,370,440,310,417,"OK",1,9,11,7); for i:=1 to 5000 do i := i + 1 od; call bouton(270,410,370,440,310,417,"OK",9,11,1,15); for i:=1 to 5500 do i := i + 1 od; call move(0,0); call putmap(tab); end aide; (*--------------------------- ANIMATION GRAPHIQUE --------------------------*) (*--------------- Debut de l'animation du generique --------------------*) (*----------------------------------------------------------------------*) (* *) (* Cette procedure calcul les coefficients de transformation *) (* *) (*----------------------------------------------------------------------*) unit sin_cos:procedure(alpha,beta,gamma:real;output a,b,c,d,e,f,g,h,i:real); begin a:=cos(gamma)*cos(beta); b:=sin(gamma)*cos(beta); c:=-sin(beta); d:=-sin(gamma)*cos(alpha)+cos(gamma)*sin(beta)*sin(alpha); e:=cos(gamma)*cos(alpha)+sin(gamma)*sin(beta)*sin(alpha); f:=cos(beta)*sin(alpha); g:=sin(gamma)*sin(alpha)+cos(gamma)*sin(beta)*cos(alpha); h:=-cos(gamma)*sin(alpha)+sin(gamma)*sin(beta)*cos(alpha); i:=cos(beta)*cos(alpha); end sin_cos; (*----------------------------------------------------------------------*) (* *) (* Cette procedure calcul la transformation d'un point 3d en point 2d *) (* *) (*----------------------------------------------------------------------*) unit trois_d_vers_2d:procedure(a,b,c,d,e,f,g,h,i,xe,ye,ze,xdep, ydep,zdep:real;output xp,yp:real); var q,pt_fuite:real; begin pt_fuite:=-1000; q:=1-(c*xe+f*ye+i*ze+zdep)/pt_fuite; xp:=(a*xe+d*ye+g*ze+xdep)/q; yp:=(b*xe+e*ye+h*ze+ydep)/q; end trois_d_vers_2d; (*----------------------------------------------------------------------*) (* *) (* Cette procedure initialise les tableaux decrivant les objets *) (* *) (*----------------------------------------------------------------------*) unit init_obj:procedure(inout xe,ye,ze,tab_ligne:arrayof real); begin (* tableaux des points *) (* M *) xe(1):=-70; ye(1):=-25; ze(1):=0; xe(2):=-70; ye(2):=0; ze(2):=0; xe(3):=-65; ye(3):=-25; ze(3):=0; xe(4):=-65; ye(4):=-20; ze(4):=0; xe(5):=-65; ye(5):=0; ze(5):=0; xe(6):=-60; ye(6):=-20; ze(6):=0; xe(7):=-60; ye(7):=-15; ze(7):=0; xe(8):=-55; ye(8):=-25; ze(8):=0; xe(9):=-55; ye(9):=-20; ze(9):=0; xe(10):=-55; ye(10):=0; ze(10):=0; xe(11):=-50; ye(11):=-25; ze(11):=0; xe(12):=-50; ye(12):=0; ze(12):=0; (* O *) xe(13):=-45; ye(13):=-25; ze(13):=0; xe(14):=-45; ye(14):=0; ze(14):=0; xe(15):=-40; ye(15):=-20; ze(15):=0; xe(16):=-40; ye(16):=-5; ze(16):=0; xe(17):=-35; ye(17):=-20; ze(17):=0; xe(18):=-35; ye(18):=-5; ze(18):=0; xe(19):=-30; ye(19):=-25; ze(19):=0; xe(20):=-30; ye(20):=0; ze(20):=0; (* R *) xe(21):=-25; ye(21):=-25; ze(21):=0; xe(22):=-25; ye(22):=0; ze(22):=0; xe(23):=-20; ye(23):=-20; ze(23):=0; xe(24):=-20; ye(24):=-15; ze(24):=0; xe(25):=-20; ye(25):=-10; ze(25):=0; xe(26):=-20; ye(26):=0; ze(26):=0; xe(27):=-15; ye(27):=-20; ze(27):=0; xe(28):=-15; ye(28):=-15; ze(28):=0; xe(29):=-15; ye(29):=-10; ze(29):=0; xe(30):=-15; ye(30):=-5; ze(30):=0; xe(31):=-15; ye(31):=0; ze(31):=0; xe(32):=-10; ye(32):=-25; ze(32):=0; xe(33):=-10; ye(33):=-15; ze(33):=0; xe(34):=-10; ye(34):=-5; ze(34):=0; xe(35):=-10; ye(35):=0; ze(35):=0; (* P *) xe(36):=-5; ye(36):=-25; ze(36):=0; xe(37):=10; ye(37):=-25; ze(37):=0; xe(38):=10; ye(38):=-10; ze(38):=0; xe(39):=0; ye(39):=-10; ze(39):=0; xe(40):=0; ye(40):=0; ze(40):=0; xe(41):=-5; ye(41):=0; ze(41):=0; xe(42):=0; ye(42):=-20; ze(42):=0; xe(43):=5; ye(43):=-20; ze(43):=0; xe(44):=5; ye(44):=-15; ze(44):=0; xe(45):=0; ye(45):=-15; ze(45):=0; (* I *) xe(46):=15; ye(46):=-25; ze(46):=0; xe(47):=15; ye(47):=0; ze(47):=0; xe(48):=20; ye(48):=-25; ze(48):=0; xe(49):=20; ye(49):=0; ze(49):=0; (* O *) xe(50):=25; ye(50):=-25; ze(50):=0; xe(51):=25; ye(51):=0; ze(51):=0; xe(52):=30; ye(52):=-20; ze(52):=0; xe(53):=30; ye(53):=-5; ze(53):=0; xe(54):=35; ye(54):=-20; ze(54):=0; xe(55):=35; ye(55):=-5; ze(55):=0; xe(56):=40; ye(56):=-25; ze(56):=0; xe(57):=40; ye(57):=0; ze(57):=0; (* N *) xe(58):=45; ye(58):=-25; ze(58):=0; xe(59):=45; ye(59):=0; ze(59):=0; xe(60):=50; ye(60):=-25; ze(60):=0; xe(61):=50; ye(61):=-15; ze(61):=0; xe(62):=50; ye(62):=0; ze(62):=0; xe(63):=60; ye(63):=-25; ze(63):=0; xe(64):=60; ye(64):=-10; ze(64):=0; xe(65):=60; ye(65):=0; ze(65):=0; xe(66):=65; ye(66):=-25; ze(66):=0; xe(67):=65; ye(67):=0; ze(67):=0; (* 3 *) xe(68):=-15; ye(68):=5; ze(68):=0; xe(69):=-15; ye(69):=10; ze(69):=0; xe(70):=-15; ye(70):=25; ze(70):=0; xe(71):=-15; ye(71):=30; ze(71):=0; xe(72):=-10; ye(72):=15; ze(72):=0; xe(73):=-10; ye(73):=20; ze(73):=0; xe(74):=-5; ye(74):=10; ze(74):=0; xe(75):=-5; ye(75):=15; ze(75):=0; xe(76):=-5; ye(76):=20; ze(76):=0; xe(77):=-5; ye(77):=25; ze(77):=0; xe(78):=0; ye(78):=5; ze(78):=0; xe(79):=0; ye(79):=30; ze(79):=0; (* D *) xe(80):=5; ye(80):=5; ze(80):=0; xe(81):=5; ye(81):=30; ze(81):=0; xe(82):=10; ye(82):=10; ze(82):=0; xe(83):=10; ye(83):=25; ze(83):=0; xe(84):=15; ye(84):=10; ze(84):=0; xe(85):=15; ye(85):=25; ze(85):=0; xe(86):=20; ye(86):=5; ze(86):=0; xe(87):=20; ye(87):=15; ze(87):=0; xe(88):=20; ye(88):=20; ze(88):=0; xe(89):=20; ye(89):=30; ze(89):=0; xe(90):=25; ye(90):=10; ze(90):=0; xe(91):=25; ye(91):=25; ze(91):=0; (* tableau des lignes *) (* M *) tab_ligne(1):=1; tab_ligne(2):=2; tab_ligne(3):=2; tab_ligne(4):=5; tab_ligne(5):=5; tab_ligne(6):=4; tab_ligne(7):=4; tab_ligne(8):=7; tab_ligne(9):=7; tab_ligne(10):=9; tab_ligne(11):=9; tab_ligne(12):=10; tab_ligne(13):=10; tab_ligne(14):=12; tab_ligne(15):=12; tab_ligne(16):=11; tab_ligne(17):=11; tab_ligne(18):=8; tab_ligne(19):=8; tab_ligne(20):=6; tab_ligne(21):=6; tab_ligne(22):=3; tab_ligne(23):=3; tab_ligne(24):=1; (* O *) tab_ligne(25):=13; tab_ligne(26):=14; tab_ligne(27):=14; tab_ligne(28):=20; tab_ligne(29):=20; tab_ligne(30):=19; tab_ligne(31):=19; tab_ligne(32):=13; tab_ligne(33):=15; tab_ligne(34):=16; tab_ligne(35):=16; tab_ligne(36):=18; tab_ligne(37):=18; tab_ligne(38):=17; tab_ligne(39):=17; tab_ligne(40):=15; (* R *) tab_ligne(41):=21; tab_ligne(42):=22; tab_ligne(43):=22; tab_ligne(44):=26; tab_ligne(45):=26; tab_ligne(46):=25; tab_ligne(47):=25; tab_ligne(48):=30; tab_ligne(49):=30; tab_ligne(50):=31; tab_ligne(51):=31; tab_ligne(52):=35; tab_ligne(53):=35; tab_ligne(54):=34; tab_ligne(55):=34; tab_ligne(56):=29; tab_ligne(57):=29; tab_ligne(58):=33; tab_ligne(59):=33; tab_ligne(60):=32; tab_ligne(61):=32; tab_ligne(62):=21; tab_ligne(63):=23; tab_ligne(64):=24; tab_ligne(65):=24; tab_ligne(66):=28; tab_ligne(67):=28; tab_ligne(68):=27; tab_ligne(69):=27; tab_ligne(70):=23; (* P *) tab_ligne(71):=36; tab_ligne(72):=41; tab_ligne(73):=41; tab_ligne(74):=40; tab_ligne(75):=40; tab_ligne(76):=39; tab_ligne(77):=39; tab_ligne(78):=38; tab_ligne(79):=38; tab_ligne(80):=37; tab_ligne(81):=37; tab_ligne(82):=36; tab_ligne(83):=42; tab_ligne(84):=43; tab_ligne(85):=43; tab_ligne(86):=44; tab_ligne(87):=44; tab_ligne(88):=45; tab_ligne(89):=45; tab_ligne(90):=42; (* I *) tab_ligne(91):=46; tab_ligne(92):=47; tab_ligne(93):=47; tab_ligne(94):=49; tab_ligne(95):=49; tab_ligne(96):=48; tab_ligne(97):=48; tab_ligne(98):=46; (* O *) tab_ligne(99):=50; tab_ligne(100):=51; tab_ligne(101):=51; tab_ligne(102):=57; tab_ligne(103):=57; tab_ligne(104):=56; tab_ligne(105):=56; tab_ligne(106):=50; tab_ligne(107):=52; tab_ligne(108):=53; tab_ligne(109):=53; tab_ligne(110):=55; tab_ligne(111):=55; tab_ligne(112):=54; tab_ligne(113):=54; tab_ligne(114):=52; (* N *) tab_ligne(115):=58; tab_ligne(116):=59; tab_ligne(117):=59; tab_ligne(118):=62; tab_ligne(119):=62; tab_ligne(120):=61; tab_ligne(121):=61; tab_ligne(122):=65; tab_ligne(123):=65; tab_ligne(124):=67; tab_ligne(125):=67; tab_ligne(126):=66; tab_ligne(127):=66; tab_ligne(128):=63; tab_ligne(129):=63; tab_ligne(130):=64; tab_ligne(131):=64; tab_ligne(132):=60; tab_ligne(133):=60; tab_ligne(134):=58; (* 3 *) tab_ligne(135):=68; tab_ligne(136):=69; tab_ligne(137):=69; tab_ligne(138):=74; tab_ligne(139):=74; tab_ligne(140):=75; tab_ligne(141):=75; tab_ligne(142):=72; tab_ligne(143):=72; tab_ligne(144):=73; tab_ligne(145):=73; tab_ligne(146):=76; tab_ligne(147):=76; tab_ligne(148):=77; tab_ligne(149):=77; tab_ligne(150):=70; tab_ligne(151):=70; tab_ligne(152):=71; tab_ligne(153):=71; tab_ligne(154):=79; tab_ligne(155):=79; tab_ligne(156):=78; tab_ligne(157):=78; tab_ligne(158):=68; (* D *) tab_ligne(159):=80; tab_ligne(160):=81; tab_ligne(161):=81; tab_ligne(162):=89; tab_ligne(163):=89; tab_ligne(164):=91; tab_ligne(165):=91; tab_ligne(166):=90; tab_ligne(167):=90; tab_ligne(168):=86; tab_ligne(169):=86; tab_ligne(170):=80; tab_ligne(171):=82; tab_ligne(172):=83; tab_ligne(173):=83; tab_ligne(174):=85; tab_ligne(175):=85; tab_ligne(176):=88; tab_ligne(177):=88; tab_ligne(178):=87; tab_ligne(179):=87; tab_ligne(180):=84; tab_ligne(181):=84; tab_ligne(182):=82; end init_obj; (*----------------------------------------------------------------------*) (* *) (* Cette procedure calcul l'animation de l'objet dans l'espace *) (* *) (*----------------------------------------------------------------------*) unit ligne:procedure(x1,y1,x2,y2,c:integer); begin call color(c); call move(x1,y1); call draw(x2,y2); end ligne; (*----------------------------------------------------------------------*) (* *) (* Cette procedure affiche l'objet a l'ecran *) (* *) (*----------------------------------------------------------------------*) unit affiche_obj:procedure(x,y,tab_ligne:arrayof real;nb_ligne:integer); var i,j:integer; var x1,y1,x2,y2:real; begin i:=1; while i-500 do zdep:=zdep-100; call sin_cos(alpha,beta,gamma,a,b,c,d,e,f,g,h,i); for j:=1 to nb_pt do call trois_d_vers_2d(a,b,c,d,e,f,g,h,i,xe(j),ye(j), ze(j),xdep,ydep,zdep,x(j),y(j)); od; call move(0,0); call putmap(image); call affiche_obj(x,y,tab_ligne,nb_ligne); od; beta:=0; while beta<6.28 do beta:=beta+(30*3.1415927/180);(* on tourne de 30ø *) call sin_cos(alpha,beta,gamma,a,b,c,d,e,f,g,h,i); for j:=1 to nb_pt do call trois_d_vers_2d(a,b,c,d,e,f,g,h,i,xe(j),ye(j), ze(j),xdep,ydep,zdep,x(j),y(j)); od; call move(0,0); call putmap(image); call affiche_obj(x,y,tab_ligne,nb_ligne); od; call outstring(20,20,"FABIEN JOBIN",14,12); call outstring(500,20,"FREDERIC GAUTIER",14,12); call outstring(230,440,"LICENCE INFORMATIQUE 1995",14,12); touche:=inchar; end animation; (*------------------ fin de l'animation du generique -------------------*) (*--------------------------------------------------------------------------*) (* EXPLORATION DES 49 COMBINAISONS POSSIBLES *) (*--------------------------------------------------------------------------*) (* Cherche une ligne ayant nb cubes align‚s du mˆme joueur *) (* et les indices i,j,k d'un cube libre *) unit rech_ligne:procedure(i,val,nb:integer;output trouve:boolean; output j,k:integer); var som,num:integer; var jlibre,klibre:integer; begin som:=0; trouve:=false; j:=1; while j<= 3 and not trouve do som:=0; num:=0; k:=1; while k<= 3 and not trouve do som := som + mat.tab(i,j,k).val; if mat.tab(i,j,k).marque = 0 then jlibre:=j; klibre:=k; else if mat.tab(i,j,k).val = val then num:=num+1; fi; fi; k:=k+1; od; if som = nb*val and num = nb then trouve:=true; fi; j:=j+1; od; if trouve then (* Si on cherche 3 cubes align‚s on les affiche en clignotant *) if nb = 3 then call affic_3_alignes(i,j-1,1,i,j-1,2,i,j-1,3); fi; j:=jlibre; k:=klibre; fi; end rech_ligne; (* Cherche une colonne ayant nb cubes align‚s du mˆme joueur et *) (* et renvoie les coordonn‚es i,j,k d'un cube libre *) unit rech_col:procedure(i,val,nb:integer;output trouve:boolean; output j,k:integer); var som,num:integer; var jlibre,klibre:integer; begin som:=0; trouve:=false; k:=1; while k<= 3 and not trouve do som:=0; num:=0; j:=1; while j<= 3 and not trouve do som := som + mat.tab(i,j,k).val; if mat.tab(i,j,k).marque = 0 then jlibre:=j; klibre:=k; else if mat.tab(i,j,k).val = val then num:=num+1; fi; fi; j:=j+1; od; if som = nb*val and num = nb then trouve:=true; fi; k:=k+1; od; if trouve then (* Si on cherche 3 cubes align‚s on les affiche en clignotant *) if nb = 3 then call affic_3_alignes(i,1,k-1,i,2,k-1,i,3,k-1); fi; j:=jlibre; k:=klibre; fi; end rech_col; (* Cherche une diagonale ayant nb cubes align‚s du mˆme joueur *) (* et renvoie les coordonn‚es i,j,k d'un cube libre *) unit rech_diag:procedure(i,val,nb:integer;output trouve:boolean; output j,k:integer); var som,num:integer; var jlibre,klibre:integer; begin (* Diagonale haut gauche vers bas droit *) som:=0;num:=0; trouve:=false; k:=1; while k<= 3 and not trouve do som := som + mat.tab(i,k,k).val; if mat.tab(i,k,k).marque = 0 then klibre:=k; else if mat.tab(i,k,k).val = val then num:=num+1; fi; fi; k:=k+1; od; if som = nb*val and num = nb then if nb = 3 then call affic_3_alignes(i,1,1,i,2,2,i,3,3); fi; trouve:=true; j:=klibre; k:=klibre; else (* Diagonale haut droit vers bas gauche *) som := 0;num:=0; som := mat.tab(i,1,3).val + mat.tab(i,2,2).val + mat.tab(i,3,1).val; if mat.tab(i,1,3).marque = 0 then j:=1;k:=3; else if mat.tab(i,1,3).val = val then num := num + 1; fi; fi; if mat.tab(i,2,2).marque = 0 then j:=2;k:=2; else if mat.tab(i,2,2).val = val then num := num + 1; fi; fi; if mat.tab(i,3,1).marque = 0 then j:=3;k:=1; else if mat.tab(i,3,1).val = val then num := num + 1; fi; fi; if som = nb*val and num =nb then (* Si on cherche 3 cubes align‚s on les affiche en clignotant *) if nb = 3 then call affic_3_alignes(i,3,1,i,2,2,i,1,3); fi; trouve:=true; fi; fi; end rech_diag; (* Cherche une colonne 3d ayant nb cubes align‚s du mˆme joueur *) (* et renvoie les coordonn‚es i,j,k d'un cube libre. *) (* Par colonne 3d, il faut entendre qu'il s'agit d'une colonne *) (* qui passe par les 3 plans. *) unit rech_col_3d:procedure(val,nb,j,k:integer;output i:integer; output trouve:boolean); var som,num:integer; begin som := mat.tab(1,j,k).val+mat.tab(2,j,k).val+mat.tab(3,j,k).val; num:=0; if mat.tab(1,j,k).marque = 0 then i:=1; else if mat.tab(1,j,k).val = val then num := num + 1; fi; fi; if mat.tab(2,j,k).marque = 0 then i:=2; else if mat.tab(2,j,k).val = val then num := num + 1; fi; fi; if mat.tab(3,j,k).marque = 0 then i:=3; else if mat.tab(3,j,k).val = val then num := num + 1; fi; fi; if som = nb*val and num =nb then (* Si on cherche 3 cubes align‚s on les affiche en clignotant *) if nb = 3 then call affic_3_alignes(1,j,k,2,j,k,3,j,k); fi; trouve:=true; fi; end rech_col_3d; (* Cherche une diagonale 3d ayant nb cubes align‚s du mˆme joueur *) (* et renvoie les coordonn‚es i,j,k d'un cube libre. *) (* Par diagonale 3d, il faut entendre qu'il s'agit d'une diagonale *) (* qui passe par les 3 plans. *) unit rech_diag_3d:procedure(i1,j1,k1,i2,j2,k2,i3,j3,k3,val,nb:integer; output i,j,k:integer;output trouve:boolean); var som,num:integer; begin som := mat.tab(i1,j1,k1).val+mat.tab(i2,j2,k2).val+mat.tab(i3,j3,k3).val; num:=0; if mat.tab(i1,j1,k1).marque = 0 then i:=i1;j:=j1;k:=k1; else if mat.tab(i1,j1,k1).val = val then num:=num+1; fi; fi; if mat.tab(i2,j2,k2).marque = 0 then i:=i2;j:=j2;k:=k2; else if mat.tab(i2,j2,k2).val = val then num:=num+1; fi; fi; if mat.tab(i3,j3,k3).marque = 0 then i:=i3;j:=j3;k:=k3; else if mat.tab(i3,j3,k3).val = val then num:=num+1; fi; fi; if som = nb*val and num =nb then (* Si on cherche 3 cubes align‚s on les affiche en clignotant *) if nb = 3 then call affic_3_alignes(i1,j1,k1,i2,j2,k2,i3,j3,k3); fi; trouve:=true; fi; end rech_diag_3d; (* Cette proc‚dure cherche dans les 49 combinaisons possibles *) (* si il y a nb cubes align‚s du joueur qui marque les cubes *) (* par val. Si cette combinaison de cubes a ‚t‚ trouv‚e, les *) (* indices d'un cube libre appartenant … cette combinaison *) (* sont renvoy‚s. *) unit trouve_aligne:procedure(val,nb:integer;output i,j,k:integer; output trouve:boolean); begin trouve:=false; i:=1; (* i caract‚rise un plan *) while i<=3 and not trouve do call rech_ligne(i,val,nb,trouve,j,k); if not trouve then call rech_col(i,val,nb,trouve,j,k); if not trouve then call rech_diag(i,val,nb,trouve,j,k); fi; fi; i:=i+1; od; if not trouve then (* Parties communes (colonnes et diagonales) aux 3 plans *) (* Recherche dans les colonnes *) j:=1; while j<=3 and not trouve do k:=1; while k<=3 and not trouve do call rech_col_3d(val,nb,j,k,i,trouve); k:=k+1; od; j:=j+1; od; if trouve then k:=k-1;j:=j-1; else (* Recherche dans les diagonales *) call rech_diag_3d(1,2,1,2,2,2,3,2,3,val,nb,i,j,k,trouve); if not trouve then call rech_diag_3d(1,1,2,2,2,2,3,3,2,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,2,3,2,2,2,3,2,1,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,3,2,2,2,2,3,1,2,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,1,1,2,1,2,3,1,3,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,1,1,2,2,1,3,3,1,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,1,1,2,2,2,3,3,3,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,1,3,2,1,2,3,1,1,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,1,3,2,2,3,3,3,3,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,1,3,2,2,2,3,3,1,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,3,3,2,3,2,3,3,1,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,3,3,2,2,3,3,1,3,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,3,3,2,2,2,3,1,1,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,3,1,2,3,2,3,3,3,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,3,1,2,2,1,3,1,1,val,nb,i,j,k,trouve); fi; if not trouve then call rech_diag_3d(1,3,1,2,2,2,3,1,3,val,nb,i,j,k,trouve); fi; fi; else i:=i-1; fi; end trouve_aligne; (*--------------------------------------------------------------------------*) (* STRATEGIES ET UTILISATEUR *) (*--------------------------------------------------------------------------*) (*--------------------------------- STRATEGIE1 -----------------------------*) (* La strat‚gie1 joue : *) (* Le cube est marqu‚ par 2 et affich‚ *) unit jouer:procedure(i,j,k:integer); begin mat.tab(i,j,k).val:=2; mat.tab(i,j,k).marque:=1; call affic_elem(i,j,k,25,20); end jouer; (* Strat‚gie1 *) unit strategie1:class; unit virtual titre:procedure; begin end titre; unit virtual trouve_3_pions:procedure; begin end trouve_3_pions; unit virtual trouve_2_pions:procedure; begin end trouve_2_pions; unit virtual adversaire_joue:procedure; begin end adversaire_joue; unit virtual gagne:procedure; begin end gagne; unit virtual perdu:procedure; begin end perdu; var i,j,k:integer; var trouve:boolean; begin return; do call titre; inner; call outstring(430,120,"Coups jou‚s : ",14,3); call track(550,120,nb_coups,3,3); call track(550,120,nb_coups,3,14); (* La strat‚gie1 joue au centre *) if mat.tab(2,2,2).marque=0 then call jouer(2,2,2); nb_coups:=nb_coups+1; call adversaire_joue; else call trouve_3_pions; if trouve then (* Si l'utilisateur a 3 pions align‚s il a gagn‚ *) call gagne; attach(main); else call trouve_aligne(2,2,i,j,k,trouve); if trouve then (* Si la strat‚gie1 a 2 pions align‚s, elle rajoute *) (* le troisiŠme et elle gagne donc l'utilisateur perd *) call jouer(i,j,k); call track(550,120,nb_coups,3,3); nb_coups:=nb_coups+1; call track(550,120,nb_coups,3,14); call trouve_aligne(2,3,i,j,k,trouve); call perdu; attach(main); else (* Sinon la strat‚gie 1 bloque l'utilisateur si il a 2 *) (* pions align‚s *) call trouve_2_pions; if trouve then call jouer(i,j,k); else (* On cherche un pion de la strat‚gie1 et *) (* on aligne un pion de fa‡on … avoir 2 *) (* pions align‚s pour la strat‚gie1 *) call trouve_aligne(2,1,i,j,k,trouve); call jouer(i,j,k); fi; fi; fi; nb_coups:=nb_coups+1; call adversaire_joue; fi; od; end strategie1; (* Strat‚gie1 contre joueur *) unit strategie1_user1:strategie1 coroutine; unit virtual titre:procedure; begin call outstring(430,90,"L'utilisateur joue...",3,3); call outstring(430,90,"La strat‚gie1 joue...",10,3); end titre; unit virtual trouve_3_pions:procedure; begin call trouve_aligne(1,3,i,j,k,trouve); end trouve_3_pions; unit virtual trouve_2_pions:procedure; begin call trouve_aligne(1,2,i,j,k,trouve); end trouve_2_pions; unit virtual adversaire_joue:procedure; begin attach(user1); end adversaire_joue; unit virtual gagne:procedure; begin call message_erreur(105,200,535,280,255,209, "Vous avez gagn‚",125,"", 270,240,370,270,310,247); end gagne; unit virtual perdu:procedure; begin call message_erreur(105,200,535,280,255,209, "Vous avez perdu",125,"", 270,240,370,270,310,247); end perdu; begin end strategie1_user1; (* Strat‚gie1 contre strat‚gie2 *) unit strategie1_strat2:strategie1 coroutine; unit virtual titre:procedure; begin call outstring(430,90,"La strat‚gie2 joue...",3,3); call outstring(430,90,"La strat‚gie1 joue...",10,3); end titre; unit virtual trouve_3_pions:procedure; begin call trouve_aligne(3,3,i,j,k,trouve); end trouve_3_pions; unit virtual trouve_2_pions:procedure; begin call trouve_aligne(3,2,i,j,k,trouve); end trouve_2_pions; unit virtual adversaire_joue:procedure; begin attach(S22); end adversaire_joue; unit virtual gagne:procedure; begin call message_erreur(105,200,535,280,225,209, "La strat‚gie2 a gagn‚",125,"", 270,240,370,270,310,247); end gagne; unit virtual perdu:procedure; begin call message_erreur(105,200,535,280,225,209, "La strat‚gie1 a gagn‚",125,"", 270,240,370,270,310,247); end perdu; var cpt:integer; begin for cpt:=1 to 30000 do cpt:=cpt+1 od; if nb_coups=27 then call message_erreur(105,200,535,280,155,209, "Egalit‚ entre la strat‚gie1 et la strat‚gie2",125,"", 270,240,370,270,310,247); attach(main); fi; end strategie1_strat2; (*-------------------------------- STRATEGIE2 ------------------------------*) (* La strat‚gie2 joue : *) (* Le cube est marqu‚ par 3 et affich‚ *) unit jouer2:procedure(i,j,k:integer); begin mat.tab(i,j,k).val:=3; mat.tab(i,j,k).marque:=1; call affic_elem(i,j,k,25,20); end jouer2; (* Strat‚gie2 *) unit strategie2:class; unit virtual titre:procedure; begin end titre; unit virtual trouve_3_pions:procedure; begin end trouve_3_pions; unit virtual trouve_2_pions:procedure; begin end trouve_2_pions; unit virtual trouve_1_pion:procedure; begin end trouve_1_pion; unit virtual adversaire_joue:procedure; begin end adversaire_joue; unit virtual gagne:procedure; begin end gagne; unit virtual perdu:procedure; begin end perdu; var i,j,k:integer; var trouve:boolean; begin joue1:=false; joue2:=false; return; do call titre; call outstring(430,120,"Coups jou‚s : ",14,3); call track(550,120,nb_coups,3,3); call track(550,120,nb_coups,3,14); inner; if mat.tab(1,1,1).marque=0 then call jouer2(1,1,1); nb_coups:=nb_coups+1; call adversaire_joue; else if nb_coups = 2 then if mat.tab(1,1,3).marque=0 then call jouer2(1,1,3); joue1:=true; nb_coups:=nb_coups+1; call adversaire_joue; else if mat.tab(1,3,1).marque=0 then call jouer2(1,3,1); joue2:=true; nb_coups:=nb_coups+1; call adversaire_joue; fi; fi; else call trouve_3_pions; if trouve then (* Si l'utilisateur a 3 pions align‚s il a gagn‚ *) call gagne; attach(main); else call trouve_aligne(3,2,i,j,k,trouve); if trouve then (* Si la strat‚gie2 a 2 pions align‚s, elle rajoute *) (* le troisiŠme et elle gagne donc l'utilisateur perd *) call jouer2(i,j,k); call track(550,120,nb_coups,3,3); nb_coups:=nb_coups+1; call track(550,120,nb_coups,3,14); call trouve_aligne(3,3,i,j,k,trouve); call perdu; attach(main); else call trouve_2_pions; (* Sinon la strat‚gie2 bloque l'utilisateur si il a 2 *) (* pions align‚s *) if trouve then call jouer2(i,j,k); nb_coups:=nb_coups+1; call adversaire_joue; else if joue1 and mat.tab(2,1,2).marque = 0 then call jouer2(2,1,2); nb_coups:=nb_coups+1; joue1:=false; call adversaire_joue; else if joue2 and mat.tab(2,2,1).marque = 0 then call jouer2(2,2,1); nb_coups:=nb_coups+1; joue2:=false; call adversaire_joue; else (* La strat‚gie2 aligne un pion avec un pion *) (* de l'adversaire *) call trouve_1_pion; call jouer2(i,j,k); nb_coups:=nb_coups+1; call adversaire_joue; fi; fi; fi; fi; fi; fi; fi; od; end strategie2; (* Strat‚gie2 contre joueur *) unit strategie2_user2:strategie2 coroutine; unit virtual titre:procedure; begin call outstring(430,90,"L'utilisateur joue...",3,3); call outstring(430,90,"La strat‚gie2 joue...",9,3); end titre; unit virtual trouve_3_pions:procedure; begin call trouve_aligne(1,3,i,j,k,trouve); end trouve_3_pions; unit virtual trouve_2_pions:procedure; begin call trouve_aligne(1,2,i,j,k,trouve); end trouve_2_pions; unit virtual trouve_1_pion:procedure; begin call trouve_aligne(1,1,i,j,k,trouve); end trouve_1_pion; unit virtual adversaire_joue:procedure; begin attach(user2); end adversaire_joue; unit virtual gagne:procedure; begin call message_erreur(105,200,535,280,255,209, "Vous avez gagn‚",125,"", 270,240,370,270,310,247); end gagne; unit virtual perdu:procedure; begin call message_erreur(105,200,535,280,255,209, "Vous avez perdu",125,"", 270,240,370,270,310,247); end perdu; begin end strategie2_user2; (* Strat‚gie2 contre strat‚gie1 *) unit strategie2_strat1:strategie2 coroutine; unit virtual titre:procedure; begin call outstring(430,90,"La strat‚gie1 joue...",3,3); call outstring(430,90,"La strat‚gie2 joue...",9,3); end titre; unit virtual trouve_3_pions:procedure; begin call trouve_aligne(2,3,i,j,k,trouve); end trouve_3_pions; unit virtual trouve_2_pions:procedure; begin call trouve_aligne(2,2,i,j,k,trouve); end trouve_2_pions; unit virtual trouve_1_pion:procedure; begin call trouve_aligne(2,1,i,j,k,trouve); end trouve_1_pion; unit virtual adversaire_joue:procedure; begin attach(S12); end adversaire_joue; unit virtual gagne:procedure; begin call message_erreur(105,200,535,280,225,209, "La strat‚gie1 a gagn‚",125,"", 270,240,370,270,310,247); end gagne; unit virtual perdu:procedure; begin call message_erreur(105,200,535,280,225,209, "La strat‚gie2 a gagn‚",125,"", 270,240,370,270,310,247); end perdu; var cpt:integer; begin for cpt:=1 to 30000 do cpt:=cpt+1 od; end strategie2_strat1; (*-------------------------------- UTILISATEUR -----------------------------*) (* Utilisateur ou joueur *) unit utilisateur:class; unit virtual titre:procedure; end titre; unit virtual adversaire_joue:procedure; end adversaire_joue; unit virtual saisie_joueur:procedure; end saisie_joueur; unit virtual egalite:procedure; begin end egalite; var i:integer; begin return; do inner; call titre; call outstring(430,120,"Coups jou‚s : ",14,3); call track(550,120,nb_coups,3,3); call track(550,120,nb_coups,3,14); c:=0; joue:=false; (* On attend que le joueur colorie un cube et que cette saisie *) (* soit prise en compte. On attend donc que le joueur appuie *) (* sur les boutons gauche et droite de la souris pour colorier *) (* un cube. *) while c <> 3 or not(joue) do d:=getpress(v,p,h,l,r,c); if c=1 then (* Touches d'affichage de la matrice *) call gestion_touches(v,p,c); fi; if c=1 or c=2 or c=3 then (* Le joueur colorie ou efface le coloriage d'un cube *) (* ou il joue : le coloriage est pris en compte *) call saisie_joueur; fi; if c=1 then (* AccŠs au menu principal *) call gestion_menu(v,p,c); fi; od; nb_coups:=nb_coups+1; if nb_coups=27 then call egalite; attach(main); else call adversaire_joue; fi; od; end utilisateur; (* Joueur contre la strat‚gie1 *) unit utilisateur1:utilisateur coroutine; unit virtual titre:procedure; begin call outstring(430,90,"La strat‚gie1 joue...",3,3); call outstring(430,90,"L'utilisateur joue...",12,3); end titre; unit virtual adversaire_joue:procedure; begin attach(S11); end adversaire_joue; unit virtual saisie_joueur:procedure; begin call saisie(v,p,c,20,25,1); end saisie_joueur; unit virtual egalite:procedure; begin call message_erreur(105,200,535,280,155,209, "Egalit‚ entre le joueur et la strat‚gie1",125,"", 270,240,370,270,310,247); end egalite; begin end utilisateur1; (* Joueur contre la strat‚gie2 *) unit utilisateur2:utilisateur coroutine; unit virtual titre:procedure; begin call outstring(430,90,"La strat‚gie2 joue...",3,3); call outstring(430,90,"L'utilisateur joue...",12,3); end titre; unit virtual adversaire_joue:procedure; begin attach(S21); end adversaire_joue; unit virtual saisie_joueur:procedure; begin call saisie(v,p,c,20,25,1); end saisie_joueur; begin if nb_coups=27 then call message_erreur(105,200,535,280,155,209, "Egalit‚ entre le joueur et la strat‚gie2",125,"", 270,240,370,270,310,247); attach(main); fi; end utilisateur2; (* Joueur1 contre Joueur2 *) unit utilisateur3:utilisateur coroutine; unit virtual titre:procedure; begin call outstring(430,90,"Le joueur2 joue...",3,3); call outstring(430,90,"Le joueur1 joue...",12,3); end titre; unit virtual adversaire_joue:procedure; begin attach(user4); end adversaire_joue; unit virtual saisie_joueur:procedure; begin call saisie(v,p,c,20,25,1); end saisie_joueur; unit virtual egalite:procedure; begin call message_erreur(105,200,535,280,155,209, "Egalit‚ entre le joueur1 et le joueur2",125,"", 270,240,370,270,310,247); end egalite; var i,j,k:integer; var trouve:boolean; begin joueur:=1; call trouve_aligne(4,3,i,j,k,trouve); if trouve then call message_erreur(105,200,535,280,255,209, "Le joueur2 a gagn‚",125,"", 270,240,370,270,310,247); attach(main); fi; end utilisateur3; (* Joueur2 contre Joueur1 *) unit utilisateur4:utilisateur coroutine; unit virtual titre:procedure; begin call outstring(430,90,"Le joueur1 joue...",3,3); call outstring(430,90,"Le joueur2 joue...",9,3); end titre; unit virtual adversaire_joue:procedure; begin attach(user3); end adversaire_joue; unit virtual saisie_joueur:procedure; begin call saisie(v,p,c,20,25,2); end saisie_joueur; var i,j,k:integer; var trouve:boolean; begin joueur:=2; call trouve_aligne(1,3,i,j,k,trouve); if trouve then call message_erreur(105,200,535,280,255,209, "Le joueur1 a gagn‚",125,"", 270,240,370,270,310,247); attach(main); fi; end utilisateur4; (*--------------------------------------------------------------------------*) (* FICHIERS *) (*--------------------------------------------------------------------------*) (* Charger une matrice 3d … partir d'un fichier *) unit charger:procedure; var rep : arrayof char; var f : file; var i,j,k : integer; var trouve:boolean; begin call patern(400,30,630,150,3,1); call hidecursor; call init(0,0); call outstring(410,250,"Nom du fichier : ",15,3); rep:=hfont8(545,250,10,80,"Nom",3,15,15); open(f,integer,rep); call reset(f); get(f,mode); get(f,joueur); get(f,nb_coups); for i := 1 to 3 do for j := 1 to 3 do for k:= 1 to 3 do get(f,mat.tab(i,j,k).val); get(f,mat.tab(i,j,k).marque); get(f,mat.tab(i,j,k).x); get(f,mat.tab(i,j,k).y); od; od; od; kill(f); call patern(400,220,630,260,3,1); call init(1,0); call showcursor; call setposition(275,445); for j:=1 to 5 do call outstring(280,425,"Veuillez appuyer sur un des boutons",14,3); call outstring(280,445," de la souris",14,3); for i:=1 to 10000 do i:=i+1 od; call outstring(280,425,"Veuillez appuyer sur un des boutons",3,3); call outstring(280,445," de la souris",3,3); for i:=1 to 10000 do i:=i+1 od; od; (* Affichage de la matrice *) call affic(25,20); call outstring(410,275,"Chargement termin‚",15,3); for i:=1 to 10000 do i:=i+1 od; call outstring(410,275,"Chargement termin‚",3,3); call outstring(430,120,"Coups jou‚s : ",14,3); call track(550,120,nb_coups,3,14); case mode when 1: call outstring(400,60,"JOUEUR",12,3); call outstring(460,60,"CONTRE",0,3); call outstring(520,60,"STRATEGIE1",10,3); if nb_coups = 27 then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, et il y a ‚galit‚",125,"", 270,240,370,270,310,247); else call trouve_aligne(1,3,i,j,k,trouve); if trouve then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, le joueur a gagn‚",125,"", 270,240,370,270,310,247); else call trouve_aligne(2,3,i,j,k,trouve); if trouve then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, la strat‚gie1 a gagn‚",125,"", 270,240,370,270,310,247); else S11:=new strategie1_user1; user1:=new utilisateur1; attach(user1); kill(user1); kill(S11); fi; fi; fi; when 2: call outstring(400,60,"JOUEUR",12,3); call outstring(460,60,"CONTRE",0,3); call outstring(520,60,"STRATEGIE2",9,3); if nb_coups = 27 then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, et il y a ‚galit‚",125,"", 270,240,370,270,310,247); else call trouve_aligne(1,3,i,j,k,trouve); if trouve then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, le joueur a gagn‚",125,"", 270,240,370,270,310,247); else call trouve_aligne(3,3,i,j,k,trouve); if trouve then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, la strat‚gie2 a gagn‚",125,"", 270,240,370,270,310,247); else S21:=new strategie2_user2; user2:=new utilisateur2; attach(user2); kill(user2); kill(S21); fi; fi; fi; when 3: call outstring(400,60,"STRATEGIE1",10,3); call outstring(485,60,"CONTRE",0,3); call outstring(540,60,"STRATEGIE2",9,3); if nb_coups = 27 then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, et il y a ‚galit‚",125,"", 270,240,370,270,310,247); else call trouve_aligne(2,3,i,j,k,trouve); if trouve then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, la strat‚gie1 a gagn‚",125,"", 270,240,370,270,310,247); else call trouve_aligne(3,3,i,j,k,trouve); if trouve then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, la strat‚gie2 a gagn‚",125,"", 270,240,370,270,310,247); fi; fi; fi; when 4: call outstring(400,60,"JOUEUR1",12,3); call outstring(465,60,"CONTRE",0,3); call outstring(525,60,"JOUEUR2",9,3); if nb_coups = 27 then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, et il y a ‚galit‚",125,"", 270,240,370,270,310,247); else call trouve_aligne(1,3,i,j,k,trouve); if trouve then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, le joueur1 a gagn‚",125,"", 270,240,370,270,310,247); else call trouve_aligne(4,3,i,j,k,trouve); if trouve then call message_erreur(105,200,535,280,155,209, "La partie est termin‚e, le joueur2 a gagn‚",125,"", 270,240,370,270,310,247); else user3:=new utilisateur3; user4:=new utilisateur4; if joueur=1 then attach(user3); else if joueur=2 then attach(user4); fi; fi; kill(user3); kill(user4); fi; fi; fi; esac; end charger; (* Enregistrement de la matrice 3d dans un fichier *) unit enregistrer:procedure; var f : file; var i,j,k : integer; var rep : arrayof char; begin call hidecursor; call init(0,0); call outstring(410,250,"Nom du fichier : ",15,3); rep:=hfont8(545,250,10,80,"Nom",3,15,15); open(f,integer,rep); call rewrite(f); put(f,mode); put(f,joueur); put(f,nb_coups); for i := 1 to 3 do for j := 1 to 3 do for k:= 1 to 3 do put(f,mat.tab(i,j,k).val); put(f,mat.tab(i,j,k).marque); put(f,mat.tab(i,j,k).x); put(f,mat.tab(i,j,k).y); od; od; od; kill(f); call outstring(410,275,"Enregistrement termin‚",15,3); for i:=1 to 10000 do i:=i+1 od; call outstring(410,275,"Enregistrement termin‚",3,3); call patern(400,220,630,260,3,1); call init(1,0); call showcursor; call setposition(275,445); for j:=1 to 5 do call outstring(280,425,"Veuillez appuyer sur un des boutons",14,3); call outstring(280,445," de la souris",14,3); for i:=1 to 10000 do i:=i+1 od; call outstring(280,425,"Veuillez appuyer sur un des boutons",3,3); call outstring(280,445," de la souris",3,3); for i:=1 to 10000 do i:=i+1 od; od; end enregistrer; (*--------------------------------------------------------------------------*) (* MENU PRINCIPAL ET SOUS-MENUS *) (*--------------------------------------------------------------------------*) (* GŠre les touches (gauche,haut,droite,bas) de l'affichage *) (* du morpion 3d *) unit gestion_touches:procedure(xmouse,ymouse,bouton_mouse:integer); var tab : arrayof integer; var i : integer; begin array tab dim (1:100); (* Bouton du haut *) if (xmouse >= 110 and xmouse <= 145 and ymouse >= 360 and ymouse <= 390 and bouton_mouse = 1) then call move(110,360); tab := getmap(145,390); for i:=1 to 1000 do i := i + 1 od; call bouton(110,360,145,390,120,370,"/\",7,8,15,4); for i:=1 to 1000 do i := i + 1 od; call move(110,360); call putmap(tab); call haut; else (* Bouton du bas *) if (xmouse >= 110 and xmouse <= 145 and ymouse >= 410 and ymouse <= 440 and bouton_mouse = 1) then call move(110,410); tab := getmap(145,440); for i:=1 to 1000 do i := i + 1 od; call bouton(110,410,145,440,120,420,"\/",7,8,15,4); for i:=1 to 1000 do i := i + 1 od; call move(110,410); call putmap(tab); call bas; else (* Bouton droit *) if (xmouse >= 170 and xmouse <= 205 and ymouse >= 410 and ymouse <= 440 and bouton_mouse = 1) then call move(170,410); tab := getmap(205,440); for i:=1 to 1000 do i := i + 1 od; call bouton(170,410,205,440,180,420,">>",7,8,15,4); for i:=1 to 1000 do i := i + 1 od; call move(170,410); call putmap(tab); call droit; else (* Bouton gauche *) if (xmouse >= 50 and xmouse <= 85 and ymouse >= 410 and ymouse <= 440 and bouton_mouse = 1) then call move(50,410); tab := getmap(85,440); for i:=1 to 1000 do i := i + 1 od; call bouton(50,410,85,440,60,420,"<<",7,8,15,4); for i:=1 to 1000 do i := i + 1 od; call move(50,410); call putmap(tab); call gauche; fi; fi; fi; fi; end gestion_touches; (* Cette proc‚dure effectue les diff‚rents jeux possibles selon le *) (* choix de l'utilisateur *) unit gestion_mode_joueur:procedure(xmouse,ymouse,bouton_mouse:integer; tab2:arrayof integer); var tab : arrayof integer; var i:integer; begin if (xmouse>=195 and xmouse <= 445 and ymouse >= 140 and ymouse <= 180 and bouton_mouse =1) then mode:=1; call move(195,140); tab := getmap(445,180); for i:=1 to 1000 do i:=i+1; od; call bouton(195,140,445,180,225,152, "Joueur contre strat‚gie1",7,8,15,4); for i:=1 to 5000 do i:=i+1; od; call move(195,140); call putmap(tab); call move(186,110); call putmap(tab2); S11:=new strategie1_user1; user1:=new utilisateur1; call outstring(400,60,"JOUEUR",12,3); call outstring(460,60,"CONTRE",0,3); call outstring(520,60,"STRATEGIE1",10,3); attach(user1); kill(user1); kill(S11); c:=2; efface:=true; else if (xmouse>=195 and xmouse <= 445 and ymouse >= 190 and ymouse <= 230 and bouton_mouse=1) then mode:=2; call move(195,190); tab := getmap(445,230); for i:=1 to 1000 do i:=i+1; od; call bouton(195,190,445,230,225,202, "Joueur contre strat‚gie2",7,8,15,4); for i:=1 to 5000 do i:=i+1; od; call move(195,190); call putmap(tab); call move(186,110); call putmap(tab2); S21:=new strategie2_user2; user2:=new utilisateur2; call outstring(400,60,"JOUEUR",12,3); call outstring(460,60,"CONTRE",0,3); call outstring(520,60,"STRATEGIE2",9,3); attach(S21); kill(user2); kill(S21); c:=2; efface:=true; else if (xmouse>=195 and xmouse <= 445 and ymouse >= 240 and ymouse <= 280 and bouton_mouse=1) then mode:=3; call move(195,240); tab := getmap(445,280); for i:=1 to 1000 do i:=i+1; od; call bouton(195,240,445,280,210,252, "Strat‚gie1 contre strat‚gie2",7,8,15,4); for i:=1 to 5000 do i:=i+1; od; call move(195,240); call putmap(tab); call move(186,110); call putmap(tab2); S12:=new strategie1_strat2; S22:=new strategie2_strat1; call outstring(400,60,"STRATEGIE1",10,3); call outstring(485,60,"CONTRE",0,3); call outstring(540,60,"STRATEGIE2",9,3); attach(S22); kill(S12); kill(S22); c:=2; efface:=true; else if (xmouse>=195 and xmouse <= 445 and ymouse >= 290 and ymouse <= 330 and bouton_mouse=1) then mode:=4; call move(195,290); tab := getmap(445,330); for i:=1 to 1000 do i:=i+1; od; call bouton(195,290,445,330,230,302, "Joueur1 contre Joueur2",7,8,15,4); for i:=1 to 5000 do i:=i+1; od; call move(195,290); call putmap(tab); call move(186,110); call putmap(tab2); efface:=true; user3:=new utilisateur3; user4:=new utilisateur4; call outstring(400,60,"JOUEUR1",12,3); call outstring(465,60,"CONTRE",0,3); call outstring(525,60,"JOUEUR2",9,3); attach(user3); kill(user3); kill(user4); c:=2; fi; fi; fi; fi; end gestion_mode_joueur; (* Affiche le sous-menu mode joueur *) unit mode_joueur:procedure(xmouse,ymouse,bouton_mouse:integer); var tab : arrayof integer; begin call patern(400,30,630,150,3,1); call init_mat(mat); call affic(25,20); nb_coups:=0; mode:=0;joueur:=0; array tab dim (1:100); call move(186,110); tab := getmap(453,337); call bouton(186,110,453,337,210,117, "Choisissez votre mode de jeu",12,15,6,15); call cadre_bouton(195,140,445,180); call bouton(195,140,445,180,225,152, "Joueur contre strat‚gie1",7,15,8,14); call cadre_bouton(195,190,445,230); call bouton(195,190,445,230,225,202, "Joueur contre strat‚gie2",7,15,8,14); call cadre_bouton(195,240,445,280); call bouton(195,240,445,280,210,252, "Strat‚gie1 contre strat‚gie2",7,15,8,14); call cadre_bouton(195,290,445,330); call bouton(195,290,445,330,230,302, "Joueur1 contre Joueur2",7,15,8,14); efface:=false; do d:=getpress(v,p,h,l,r,c); call gestion_mode_joueur(v,p,c,tab); if c = 2 then exit fi; od; if not efface then call move(186,110); call putmap(tab); fi; end mode_joueur; (* GŠre le sous-menu comprenant : *) (* - une nouvelle partie *) (* - le chargement d'une partie *) (* - l'enregistrement de la partie *) unit gestion_sous_menu:procedure(xmouse,ymouse,bouton_mouse:integer; tab:arrayof integer); var i:integer; begin if (xmouse>=30 and xmouse <= 202 and ymouse >= 32 and ymouse <= 42 and bouton_mouse=1) then call outstring(30,30,"Nouvelle partie ",12,8); for i:= 1 to 10000 do i:=i+1 od; call move(20,20); call putmap(tab); call outstring(20,3,"Jeu",14,7); call mode_joueur(xmouse,ymouse,bouton_mouse); else if (xmouse>=30 and xmouse <= 202 and ymouse >= 52 and ymouse <= 62 and bouton_mouse=1) then call outstring(30,50,"Charger une partie ",12,8); for i:= 1 to 10000 do i:=i+1 od; call outstring(30,50,"Charger une partie ",14,7); call move(20,20); call putmap(tab); call outstring(20,3,"Jeu",14,7); call charger; c:=2; else if (xmouse>=30 and xmouse <= 202 and ymouse >= 72 and ymouse <= 82 and bouton_mouse=1) then call outstring(30,70,"Enregistrer la partie ",12,8); for i:= 1 to 10000 do i:=i+1 od; call outstring(30,70,"Enregistrer la partie ",14,7); call move(20,20); call putmap(tab); call outstring(20,3,"Jeu",14,7); call enregistrer; c:=2; fi; fi; fi; end gestion_sous_menu; (* Affiche le sous-menu de l 'option "JEU" du menu principal *) unit sous_menu:procedure; var tab : arrayof integer; begin array tab dim (1:100); call move(20,20); tab := getmap(210,95); call bouton(20,20,210,95,0,0,"",7,15,8,14); call outstring(30,30,"Nouvelle partie ",14,7); call outstring(30,50,"Charger une partie ",14,7); call outstring(30,70,"Enregistrer la partie ",14,7); do d:=getpress(v,p,h,l,r,c); call gestion_sous_menu(v,p,c,tab); if c = 2 then exit fi; od; call move(20,20); call putmap(tab); end sous_menu; (* Cette proc‚dure gŠre le menu principal *) unit gestion_menu:procedure(xmouse,ymouse,bouton_mouse:integer); var i:integer; begin if (xmouse>=20 and xmouse <= 42 and ymouse >= 3 and ymouse <= 15 and bouton_mouse=1) then call outstring(20,3,"Jeu",12,8); call sous_menu; call outstring(20,3,"Jeu",14,7); else if (xmouse>=90 and xmouse <= 122 and ymouse >= 3 and ymouse <= 15 and bouton_mouse = 1) then call outstring(90,3,"Aide",12,8); call aide; call outstring(90,3,"Aide",14,7); else if (xmouse>=160 and xmouse <= 215 and ymouse >= 3 and ymouse <= 15 and bouton_mouse=1) then call outstring(160,3,"Quitter",12,8); call groff; call endrun; fi; fi; fi; end gestion_menu; (* Menu principal *) unit menu:procedure; begin call bouton(0,0,640,20,0,0,"",7,15,8,14); call outstring(20,3,"Jeu",14,7); call outstring(90,3,"Aide",14,7); call outstring(160,3,"Quitter",14,7); do d:=getpress(v,p,h,l,r,c); if c=1 then call gestion_touches(v,p,c); fi; call gestion_menu(v,p,c); od; end menu; (*--------------------------------------------------------------------------*) (* PROGRAMME PRINCIPAL *) (*--------------------------------------------------------------------------*) var user1:utilisateur1; (* Joueur contre strat‚gie1 *) var user2:utilisateur2; (* Joueur contre strat‚gie2 *) var user3:utilisateur3; (* Joueur1 contre joueur2 *) var user4:utilisateur4; (* Joueur2 contre joueur1 *) var S11:strategie1_user1; (* Strat‚gie1 contre joueur *) var S12:strategie1_strat2; (* Strat‚gie1 contre strat‚gie2 *) var S21:strategie2_user2; (* Strat‚gie2 contre joueur *) var S22: strategie2_strat1; (* Strat‚gie2 contre strat‚gie1 *) var v,p,h,l,r,c:integer; (* Variables utilis‚es pour la souris : *) var d:boolean; (* v : position x du pointeur de la souris *) (* p : position y du pointeur de la souris *) (* c : bouton appuy‚ de la souris : *) (* 1 : bouton gauche appuy‚ *) (* 2 : bouton droit appuy‚ *) (* 3 : boutons droit et gauche appuy‚s *) var mat:mat_3d; (* Matrice 3d repr‚sentant le morpion 3d *) var nb_coups:integer; (* Nombre de coups jou‚s pour une partie *) var joue:boolean; (* indique si l'utilisateur a jou‚ *) var joue1:boolean; (* servent … la strat‚gie2 pour savoir si elle a *) var joue2:boolean; (* jou‚ son coup d'attaque *) var efface : boolean; (* indique que l'image que contenait tab2 a ‚t‚ *) (* restitu‚e *) var mode:integer; (* indique le mode de jeu choisi par l'utilisateur *) var joueur:integer; (* indique pour le mode de jeu 4 (joueur1 contre *) (* joueur2) si le joueur1 joue (joueur=1) ou le *) (* joueur2 (joueur=2). De cette fa‡on, lorqu'on *) (* reprend une partie sauvegard‚e sur fichier, *) (* on sait si c'est … partir du joueur1 ou du *) (* joueur2 que la partie a ‚t‚ enregistr‚e. *) begin (* Cr‚ation et initialisation de la matrice 3d *) mat := new mat_3d(3,3,3); call init_mat(mat); nb_coups:=0; call gron(0); call animation; (* Affichage du fond *) call bouton(0,22,640,480,100,100,"",3,11,8,10); call bouton(3,25,637,477,100,100,"",3,11,8,10); (* Affichage des boutons de visualisation du morpion 3d *) call cadre_bouton(110,360,145,390); call bouton(110,360,145,390,120,370,"/\",7,15,8,14); call cadre_bouton(50,410,85,440); call bouton(50,410,85,440,60,420,"<<",7,15,8,14); call cadre_bouton(110,410,145,440); call bouton(110,410,145,440,120,420,"\/",7,15,8,14); call cadre_bouton(170,410,205,440); call bouton(170,410,205,440,180,420,">>",7,15,8,14); (* affichage des bordures de la matrice morpion 3d *) call des_mat_3d(292,100,25,20,11); (* Affichage du contenu de la matrice morpion 3d *) call affic(25,20); (* initialisation de la souris *) call init(1,0); call showcursor; call getmovement(1,1); call menu; call groff; end end end.