(************************** PRESENTATION DU PROGRAMME ********************** )
(
(* Dans ce jeu, des pieces de toutes formes tombent du haut de l'ecran.
(* Vous pouvez tourner ces pieces dans le sens horaire avec la barre d'espace
(  et dans le sens anti-horaire avec la touche Z.
(* Vous pouvez tasser une piece vers la gauche ou la droite en appuyant sur la
(  fleche de gauche ou de droite
(* Vous pouvez accelerer la chute d'une piece en appuyant sur la fleche
(  du bas. Cette action vous ajoute un point par fois ou vous accelerez la
(  piece. Pour faire tomber instantanement la piece jusqu'en bas, vous pouvez
(  appuyer sur la fleche du haut. Cela vous donnera deux points par ligne
(  descendue.
(* Si vous reussissez a creer une rangee pleine de blocs avec aucun trou, vous
(  etes recompense de 100 points. Un petit son recompense alors votre exploit.
(  Si vous remplissez deux lignes d'un seul coup vous faites alors 300 points.
(  Trois lignes donnent 500 points, quatre lignes 800 points et 5 lignes 1200.
(* Lorsque vous remplissez une ligne, cette ligne s'efface et toutes les
(  lignes qui sont au-dessus descendent.
(* Les pieces suivantes sont affichees a la gauche de l'aire de jeu.
(* Lorsque le tas de bloc atteint le haut de l'ecran, la partie est terminee
(  et si le joueur fait partie des high score, son nom lui est demande.     *)
program pentatris;

uses graph,crt;
type dessin_p= array[1..12,1..4] of byte;  (* dessin_ servent a creer les *)
     dessin_e= array[1..13,1..4] of byte;  (* constantes pour les lettres *)
     dessin_n= array[1..17,1..4] of byte;  (*  qui tombent au tout debut  *)
     dessin_t1= array[1..9,1..4] of byte;
     dessin_a= array[1..15,1..4] of byte;
     dessin_t2= array[1..10,1..4] of byte;
     dessin_r= array[1..15,1..4] of byte;
     dessin_i= array[1..15,1..4] of byte;
     dessin_s= array[1..12,1..4] of byte;
     limite= array[1..5] of byte;        {tableaux pour les limites a gauche droite en en bas}
     dessin_niv= array[1..22,1..4] of byte;         (*pour l'ecriture de*)
     dessin_chiffre= array[1..10,1..8,1..4] of byte;    (*NIVEAU*)
     dessin_regle= array[1..21,1..4] of byte;           (*REGLES*)
     dessin_gameover= array[1..32,1..4] of byte;       (*GAME OVER*)
     dessin_highscore= array[1..31,1..4] of byte;      (*HIGHSCORE*)

const bloc= 13; {grosseur petit bloc}
      multiplicateur_vitesse=3; {facteur par lequel est multiplie la vitesse de chute des blocs}
      blocjeu= 20;  {grosseur gros bloc dans le jeu}
      ajustx=(480-(480 div blocjeu+1)*blocjeu) div 2; (*    ajuste la grille en    *)
      ajusty=(640-(640 div blocjeu+1)*blocjeu) div 2; (* x et en y pour esthetisme *)
      jeux= (640-10*blocjeu) div 2+ajustx;              (* coordonnees x et y de *)
      jeuy= (480-20*blocjeu) div 2+ajusty+2*blocjeu;    (*    l'espace de jeu    *)
      pentax= (640-(5*8+4*2)*bloc) div 2;    {ou commence en x le PENTA}
      trisx= (640-(4*8+3*2)*bloc) div 2;    {ou commence en x le TRIS}
      pentatrisy= 1;        {ou commence en y le PENTA et le TRIS}
      chute= 2;          {vitesse de chute des lettres de l'animation PENTATRIS}
      a: array[1..4] of byte = (5,13,26,39);  {coordonnes en x des options du menu}
      (*nom des high score par defaut si personne n'a joue*)
      hsinitial: array[1..10] of string=
      ('Jacques','10000','Claudette','7500','Eugene','5000','Roger','2000','Gertrude','1000');
      (*vitesse a laquelle tombent les blocs dans le jeu selon le niveau*)
      vitesse: array[1..10] of longint= (5000000,4180000,3500000,2920000,2450000,2040000,1710000,1430000,1200000,10000000);
      (*matrices qui donnent la position en x,y, quel bloc dessiner et dans quel angle lors de l'animation*)
      drawp: dessin_p= ((13,0,20,4),(11,0,10,2),(9,0,23,1),(9,2,17,3),(8,4,8,3),(5,0,12,2),(6,6,11,2),(5,1,13,4),
                       (4,5,6,2),(4,3,9,2),(4,0,3,1),(5,6,1,2));
      drawe: dessin_e= ((13,10,21,3),(14,14,15,3),(14,16,2,1),(14,13,4,1),(12,10,27,2),(9,10,28,2),(9,12,19,1),(7,10,17,4),
                       (5,10,8,4),(5,12,5,1),(4,10,16,1),(4,14,17,1),(4,17,1,1));
      drawn: dessin_n= ((15,26,2,1),(12,20,14,4),(13,21,2,2),(12,25,25,3),(10,26,15,2),(10,24,2,2),(8,23,2,2),(10,20,10,2),
                       (9,26,7,2),(9,20,4,2),(8,20,1,1),(6,26,20,4),(6,20,29,3),(5,20,9,1),(4,26,8,2),(4,26,1,1),(4,20,2,1));
      drawt1: dessin_t1= ((14,33,9,1),(12,33,4,4),(11,34,2,2),(9,33,3,2),(7,33,16,2),(5,31,21,1),(4,30,6,3),(4,35,20,3),
			 (4,33,22,1));
      drawa: dessin_a= ((15,46,2,1),(13,40,3,2),(12,40,14,2),(12,46,3,2),(11,46,14,2),(9,45,24,3),(9,41,29,1),(9,43,4,2),
			(9,40,7,2),(6,46,17,2),(7,40,4,4),(5,40,23,1),(5,44,25,1),(4,42,10,1),(5,46,1,1));
      drawt2: dessin_t2= ((29,3,1,1),(27,3,8,2),(25,3,11,2),(23,3,8,4),(21,3,10,2),(19,1,7,3),(18,0,6,3),(19,4,21,4),
			  (18,6,4,2),(18,3,3,1));
      drawr: dessin_r= ((28,16,4,3),(27,15,9,1),(25,10,12,2),(27,11,3,2),(25,13,28,3),(24,11,21,4),(23,14,25,4),
                        (23,10,14,1),(23,14,1,1),(21,15,10,1),(21,10,9,1),(19,15,19,3),(18,13,10,1),(18,11,25,4),(18,10,7,2));
      drawi: dessin_i= ((29,20,12,1),(28,20,2,1),(29,25,2,1),(28,26,4,2),(27,24,4,4),(26,22,26,2),(24,23,9,1),(23,24,1,1),
                        (20,23,17,2),(21,23,1,1),(19,22,16,1),(18,20,10,1),(18,25,19,1),(18,23,2,1),(18,20,1,1));
      draws: dessin_s= ((29,30,12,1),(28,30,5,1),(28,36,1,1),(27,34,18,1),(24,35,29,4),(23,33,8,3),(22,31,8,3),
                        (20,30,20,2),(19,31,16,1),(18,34,11,1),(18,33,1,1),(18,36,4,2));
      (*coordonnees en x et y de l'ecriture de niveau,score,piece suivante,etc.*)
      niveaux= (640-32*bloc) div 2;
      niveauy= (jeuy-5*bloc) div 2;
      reglex=  (640-24*bloc) div 2+ajustx;
      regley=  (jeuy-5*bloc) div 2;
      gmoverx= (640-35*bloc) div 2;
      gmovery= (480-5*bloc) div 2;
      highscorex= (640-37*bloc) div 2;
      highscorey= (jeuy-5*bloc) div 2;
      scorex= 431;
      scorey= 130;
      piece_suivantex= 50;
      piece_suivantey= jeuy+2*blocjeu;
      lignes_par_niveau= 5; {nombre de lignes pour changer de niveau}
      (*matrices qui donnent la position des bloc dans les ecritures de meme que leur angle et leur numero de bloc*)
      (*x,y,numerobloc,rotation*)
      drawniv: dessin_niv= ((0,0,4,4),(0,2,3,2),(2,2,1,1),(3,3,4,2),(4,0,3,2),(6,0,22,1),(6,3,8,3),(10,0,3,2),(11,3,1,1),
                           (12,4,1,1),(13,3,1,1),(14,0,3,2),(16,0,6,3),(16,2,2,1),(16,3,7,1),(20,1,24,3),(21,0,1,1),
                           (20,3,2,2),(22,3,2,2),(24,0,5,2),(25,4,2,1),(27,0,5,2));

      drawchiffre: dessin_chiffre=
    ( ((3,0,0,0),(29,0,16,2),(29,4,3,1),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)) ,
      ((5,0,0,0),(29,1,1,1),(29,3,8,3),(30,0,1,1),(31,1,2,2),(0,0,0,0),(0,0,0,0),(0,0,0,0)) ,
      ((6,0,0,0),(29,0,2,1),(29,2,2,1),(29,4,2,1),(31,1,1,1),(31,3,1,1),(0,0,0,0),(0,0,0,0)) ,
      ((3,0,0,0),(29,0,6,2),(31,1,5,2),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)) ,
      ((5,0,0,0),(29,0,24,4),(29,4,2,1),(31,0,1,1),(31,3,1,1),(0,0,0,0),(0,0,0,0),(0,0,0,0)) ,
      ((5,0,0,0),(29,1,8,4),(30,0,2,1),(30,4,1,1),(31,3,1,1),(0,0,0,0),(0,0,0,0),(0,0,0,0)) ,
      ((4,0,0,0),(29,0,7,3),(30,2,2,2),(29,4,1,1),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)) ,
      ((8,0,0,0),(29,1,1,1),(29,3,1,1),(30,0,1,1),(30,2,1,1),(30,4,1,1),(31,1,1,1),(31,3,1,1)) ,
      ((5,0,0,0),(29,1,1,1),(30,0,1,1),(30,1,8,2),(29,4,2,1),(0,0,0,0),(0,0,0,0),(0,0,0,0)) ,
      ((6,0,0,0),(29,0,2,2),(29,3,2,2),(30,2,1,1),(31,0,2,2),(31,3,2,2),(0,0,0,0),(0,0,0,0)) );

      drawregle: dessin_regle= ((0,1,24,4),(0,4,2,2),(2,4,2,2),(2,2,1,1),(4,1,6,3),(4,3,2,1),(4,4,7,1),
                                (8,2,3,2),(9,1,3,1),(9,5,2,1),(10,3,4,2),(13,1,2,2),(13,3,21,3),(17,1,6,3),
                                (17,3,2,1),(17,4,7,1),(21,2,1,1),(21,5,2,1),(22,3,1,1),(22,1,2,1),(23,4,1,1));
      drawgo: dessin_gameover= ((0,1,3,2),(1,0,3,1),(1,4,2,1),(2,2,4,2),(5,1,24,3),(5,3,2,2),(6,0,1,1),(7,3,2,2),
                                (9,0,1,1),(10,1,1,1),(11,0,1,1),(9,1,5,2),(11,1,5,2),(13,0,6,3),(13,2,2,1),(13,3,7,1),
                                (18,1,3,2),(19,0,1,1),(19,4,1,1),(20,1,3,2),(22,0,3,2),(23,3,1,1),(24,4,1,1),
                                (25,3,1,1),(26,0,3,2),(28,0,6,3),(28,2,2,1),(28,3,7,1),(32,0,24,4),(32,3,2,2),(34,1,1,1),
                                (34,3,2,2));
      drawhs: dessin_highscore= ((0,0,12,2),(1,2,1,1),(2,0,12,2),(4,0,22,1),(4,3,8,3),(8,1,3,2),(9,0,3,1),(9,4,2,1),
                                 (10,2,4,2),(13,0,12,12),(14,2,1,1),(15,0,12,12),(18,1,1,1),(18,4,2,1),(19,0,2,1),(19,2,1,1),
                                 (20,3,1,1),(22,1,3,2),(23,0,2,1),(23,4,2,1),(26,1,3,2),(27,0,1,1),(27,4,1,1),(28,1,3,2),
                                 (30,0,24,4),(30,3,2,2),(32,3,2,2),(32,1,1,1),(34,0,6,3),(34,3,7,1),(34,2,2,1));

var pilote,mode: integer;   {initialiser le mode graphique}
    spacebar,i,j,k,x1,y1:integer;  (*i,j,k boucles x1,y1 coordonnes du bloc dans le jeu*)
    niveau,niveau_precedent: byte;   {variables pour les niveaux}
    (*spacebar donne la rotation de la piece, grosseurbloc quel constante de bloc utiliser*)
    (*option pour les options dans les menus et utilite=1 pour ne pas dessiner un bloc mais*)
    (*seulement fixer ses limites et ligne compte le nombre de lignes completees*)
    option,grosseurbloc,utilite,lignes: word;
    numerobloc: byte;   {le numero du bloc en jeu}
    numero_next: array[1..3] of byte;   {celui du prochain}
    compteur: longint;  (*variable pour un delai fait maison*)
    key,key_nom: char;  {pour les touches pesees par l'utilisateur}
    couleur: boolean;   {couleur=false pour effacer un bloc}
    grille: array[1..10,1..20] of byte;   {bloc dans la grille de jeu}
    limy,limg,limd: limite;  {collisions gauche droite et bas}
    coordbloc: array[1..5,1..5] of byte;  {cases occup‚es pour un bloc}
    score: longint;       (*pointage du joueur*)
    scorestring: string;  (*pointage en string*)
    premier_menu: boolean; (*vrai seulement au lancement du programme pour faire l'animation*)
    hsfile: file of string; (*cree un fichier externe contenant les highscore*)
    hsmodifie: array[1..10] of string; (*contient les noms et les points du highscore*)
    b: byte;  {pour les boucles et usages multiples}
    S: string;  {pour des conversions integer en string}
    nom: string[10];  {pour le nom a enregistrer dans le highscore max 10 caract.}
    code: integer;  {pour tester si la conversion string a integer sest bien deroulee}

function max(liste: limite):word;
(* donne le max d'une variable de type limite (array[1..5]) *)
var l,maximum: word;
begin
maximum:= liste[1];
for l:=2 to 5 do
     if liste[l]>maximum then
          maximum:= liste[l];
max:= maximum;
end;

function min(liste: limite):word;
(* donne le min d'une variable de type limite (array[1..5]) *)
var l,minimum: word;
begin
minimum:= liste[1];
for l:=2 to 5 do
     if liste[l]<minimum then
          minimum:= liste[l];
min:= minimum;
end;

procedure dessin_bloc(x,y,numero,orientation:word);
(*Dessine un bloc en x,y ou teste les collisions selon utilite*)
(*si utilite=0 dessine si utilite=1 teste collisions*)
(*Le numero donne quel bloc dessiner*)

(*Voici les bloc selon le numero:
(*  X 1   XX 2  XXX 3 XX 4 XXXX 5   X 6  X   7 XXX 8  XX 9   XX 10 XX  11 XXXXX 12 XXXX 13 XXXX 14 XXXX 15 XXXX 16
(*                    X           XXX    XXX    X     XX    XX      XX                X    X         X      X
(*
(*  XXX  17  XXX 18 XXX 19 XXX 20 XXX    XXX     X     XXX 24 XX     X        X     X      X
(*    XX    XX       XX    XX       X 21  X  22 XXX 23 X X     XX 25 XXX 26 XXX 27 XXX 28 XXX 29
(*                                  X     X      X              X      X    X        X    X      *)

(*orientation 1= 0 degre
(*            2= 90 degres
(*            3= 180 degres
(*            4= 270 degres *)

var blc,vraibloc:integer;
{blc est une abreviation pour 4*numero-4+orientation}
begin
(*remets la valeur d'entr‚e entre 1 et 4*)
orientation:= orientation mod 4;
if orientation=0 then
   orientation:=4;

blc:= 4*numero-4+orientation;  {donne un numero de 1 … 116 pour chaque bloc}
setfillstyle(1,0);             {mets le bloc noir}
if couleur then                         {remets de la couleur si}
   setfillstyle(1,numero mod 15+1);     {la variable couleur = true}

vraibloc:=blocjeu;             {dessine un gros bloc a moins que}
if grosseurbloc=0 then         {l'on soit encore dans l'animation ou que}
     vraibloc:=bloc;           {l'on ecrive ''niveau'' ou ''game over'' etc.}

for k:=1 to 5 do
(*reinitialise les variables pour les collisions*)
(*puisque le bloc a bouge et a peut-etre tourne*)
begin
     limy[k]:=0;
     limd[k]:=0;
     limg[k]:=0;
     coordbloc[1,k]:=0; coordbloc[2,k]:=0; coordbloc[3,k]:=0;
     coordbloc[4,k]:=0; coordbloc[5,k]:=0;
end;

(*entre accolades est le numero y,x de la case a dessiner*)
(*a condition que blc soit dans la plage inscrite*)
{1,1}
case blc of
1..14,16..20,22..27,29,32..36,38,40,41,43,45..49,51..54,56,57,
60,61,64,65,67,70,72,73,75..78,80,81,83..85,88,93..97,99,101,103,106,108,111,114:
begin
     if utilite=0 then bar(x,y,x+vraibloc-2,y+vraibloc-2);
     limy[1]:=1;
     limd[1]:=1;
     limg[1]:=1;
     coordbloc[1,1]:= numero mod 15+1;
end;
end;
{1,2}
case blc of
5,7,9,11,13..15,17,19,23,24,26..31,33..37,39,41..45,47,49,50,52..54,57..59,
61,62,65..69,73..79,81,84,85,87,89..94,96,97,100,102,104,106,108,109,110,112..114,116:
begin
     if utilite=0 then bar(x+vraibloc,y,x+2*vraibloc-2,y+vraibloc-2);
     limy[2]:=1;
     limd[1]:=2;
     if limg[1]=0 then
	limg[1]:=2;
     coordbloc[2,1]:= numero mod 15+1;
end;
end;
{1,3}
case blc of
9,11,17,19,21,23,27,29,37,39,45,47,49,53,57,
61,63,65,69,71,73,77,79,81,82,84,85,86,93,95,98,100,102,104,105,107,112,115:
begin
     if utilite=0 then bar(x+2*vraibloc,y,x+3*vraibloc-2,y+vraibloc-2);
     limy[3]:=1;
     limd[1]:=3;
     if limg[1]=0 then
	limg[1]:=3;
     coordbloc[3,1]:= numero mod 15+1;
end;
end;
{1,4}
case blc of
17,19,45,47,49,53,55,57,61,69,71:
begin
     if utilite=0 then bar(x+3*vraibloc,y,x+4*vraibloc-2,y+vraibloc-2);
     limy[4]:=1;
     limd[1]:=4;
     if limg[1]=0 then
	limg[1]:=4;
     coordbloc[4,1]:= numero mod 15+1;
end;
end;
{1,5}
case blc of
45,47:begin
     if utilite=0 then bar(x+4*vraibloc,y,x+5*vraibloc-2,y+vraibloc-2);
     limy[5]:=1;
     limd[1]:=5;
     if limg[1]=0 then
	limg[1]:=5;
     coordbloc[5,1]:= numero mod 15+1;
end;
end;
{2,1}
case blc of
6,8,10,12,13,15,16,18,20..23,25,26,30..40,42,44,46,48,51..53,55,56,59,
60,62..64,68..72,74..80,83,84,86,88..93,95,96,99,100,101,103,105,107,109,111..113,115,116:
begin
     if utilite=0 then bar(x,y+vraibloc,x+vraibloc-2,y+2*vraibloc-2);
     limy[1]:=2;
     limd[2]:=1;
     limg[2]:=1;
     coordbloc[1,2]:= numero mod 15+1;
end;
end;
{2,2}
case blc of
14..16,21,24,25,28..44,50,51,54,55,58..63,66..71,73..80,85..92,94,95,97..116:
begin
     if utilite=0 then bar(x+vraibloc,y+vraibloc,x+2*vraibloc-2,y+2*vraibloc-2);
     limy[2]:=2;
     limd[2]:=2;
     if limg[2]=0 then
	limg[2]:=2;
     coordbloc[2,2]:= numero mod 15+1;
end;
end;
{2,3}
case blc of
21,25,27,31,41,43,51,55,57,59,63,65,67,71,73,75,79,
81,82,86,88..93,95,97,98,101,103,105,107,109..111,113..115:
begin
     if utilite=0 then bar(x+2*vraibloc,y+vraibloc,x+3*vraibloc-2,y+2*vraibloc-2);
     limy[3]:=2;
     limd[2]:=3;
     if limg[2]=0 then
	limg[2]:=3;
     coordbloc[3,2]:= numero mod 15+1;
end;
end;
{2,4}
case blc of
49,51,55,59,63,65,67: begin
     if utilite=0 then bar(x+3*vraibloc,y+vraibloc,x+4*vraibloc-2,y+2*vraibloc-2);
     limy[4]:=2;
     limd[2]:=4;
     if limg[2]=0 then
	limg[2]:=4;
     coordbloc[4,2]:= numero mod 15+1;
end;
end;
{3,1}
case blc of
10,12,18,20,22,26,28,32,42,44,46,48,52,56,58,60,64,66,68,72,74,76,
80,82..84,87,88,94,96,98,100,102,104,105,107,110,113:
begin
     if utilite=0 then bar(x,y+2*vraibloc,x+vraibloc-2,y+3*vraibloc-2);
     limy[1]:=3;
     limd[3]:=1;
     limg[3]:=1;
     coordbloc[1,3]:= numero mod 15+1;
end;
end;
{3,2}
case blc of
22,24,28,30,38,40,50,54,58,62,64,66,70,72,74,78,
80,82,83,85,87,89..92,94,96,98,99,102,104,106,108,110..112,114..116:
begin
     if utilite=0 then bar(x+vraibloc,y+2*vraibloc,x+2*vraibloc-2,y+3*vraibloc-2);
     limy[2]:=3;
     limd[3]:=2;
     if limg[3]=0 then
	limg[3]:=2;
     coordbloc[2,3]:= numero mod 15+1;
end;
end;
{3,3}
case blc of
81,82,83,86,87,97,99,101,103,106,108,109,116:
begin
     if utilite=0 then bar(x+2*vraibloc,y+2*vraibloc,x+3*vraibloc-2,y+3*vraibloc-2);
     limy[3]:=3;
     limd[3]:=3;
     if limg[3]=0 then
	limg[3]:=2;
     coordbloc[3,3]:= numero mod 15+1;
end;
end;
{4,1}
case blc of
18,20,46,48,50,52,56,60,64,66,68: begin
     if utilite=0 then bar(x,y+3*vraibloc,x+vraibloc-2,y+4*vraibloc-2);
     limy[1]:=4;
     limd[4]:=1;
     limg[4]:=1;
     coordbloc[1,4]:= numero mod 15+1;
end;
end;
{4,2}
case blc of
50,54,56,58,62,70,72: begin
     if utilite=0 then bar(x+vraibloc,y+3*vraibloc,x+2*vraibloc-2,y+4*vraibloc-2);
     limy[2]:=4;
     limd[4]:=2;
     if limg[4]=0 then
	limg[4]:=2;
     coordbloc[2,4]:= numero mod 15+1;
end;
end;
{5,1}
case blc of
46,48: begin
     if utilite=0 then bar(x,y+4*vraibloc,x+vraibloc-2,y+5*vraibloc-2);
     limy[1]:=5;
     limd[5]:=1;
     limg[5]:=1;
     coordbloc[1,5]:= numero mod 15+1;
end;
end;

end;

procedure ecrire_niveau;
(*ecrit NIVEAU avec des petits blocs et a laide des constantes*)
begin
grosseurbloc:=0;  {petits blocs}
setfillstyle(1,black);
bar(niveaux-2,0,niveaux+32*bloc,niveauy+5*bloc); {efface le quadrillage}
for i:=1 to 22 do             {niveau}
    dessin_bloc(niveaux+drawniv[i,1]*bloc,niveauy+drawniv[i,2]*bloc,drawniv[i,3],drawniv[i,4]);

for i:=2 to drawchiffre[niveau,1,1] do  {rajoute le chiffre}
    dessin_bloc(niveaux+drawchiffre[niveau,i,1]*bloc,niveauy+drawchiffre[niveau,i,2]*bloc,
               drawchiffre[niveau,i,3],drawchiffre[niveau,i,4]);

grosseurbloc:=1;    {remets les bloc gros}
end;

procedure ecrire_reglements;
(*ecrit REGLEMENTS avec des petits blocs et a laide des constantes*)
begin
grosseurbloc:=0;     {petits blocs}
for i:=1 to 21 do             {reglements}
    dessin_bloc(reglex+drawregle[i,1]*bloc,regley+(drawregle[i,2]-1)*bloc,drawregle[i,3],drawregle[i,4]);
end;

procedure ecrire_highscore;
(*ecrit HIGHSCORE avec des petits blocs et a laide des constantes*)
begin
grosseurbloc:=0;  {petits blocs}
for i:=1 to 31 do            {highscore}
    dessin_bloc(highscorex+drawhs[i,1]*bloc,highscorey+(drawhs[i,2]+3)*bloc,drawhs[i,3],drawhs[i,4]);
end;

procedure animation_debut;
(*Cette procedure cr‚e le PENTA TRIS qui tombe du ciel*)
begin
grosseurbloc:=0; {petits blocs}

if premier_menu then
   delay(2000); {etre certain que l'animation ne debute pas avant que l'ecran s'ouvre}

for j:=1 to 17 do
begin
{}   (*P*)
{}   if j<=12 then
{}      if premier_menu then
{}         (*blocs tombent un a un*)
{}         for i:=0 to drawp[j,1] do
{}         begin
{exemple}       dessin_bloc(pentax+drawp[j,2]*bloc,(i-4+pentatrisy)*bloc,drawp[j,3],drawp[j,4]);
{typique d'une} delay(chute);    {ecrit un morceau de la lettre et attend un delai}
{lettre qui}    if i<drawp[j,1] then {si le morceau n'est pas a sa place finale}
{tombe}            couleur:= false;  {enleve la couleur}
{les autres}    dessin_bloc(pentax+drawp[j,2]*bloc,(i-4+pentatrisy)*bloc,drawp[j,3],drawp[j,4]);
{lettres}       couleur:= true;     {efface le bloc et remets de la couleur pour le prochain morceau ou bout de chute}
{suivent}  end
{la meme}  (*dessine directement sans chute si ce n'est pas la premiere fois que l'on voit le menu*)
{logique}else
{}          dessin_bloc(pentax+drawp[j,2]*bloc,(drawp[j,1]-4+pentatrisy)*bloc,drawp[j,3],drawp[j,4]);
     (*E*)
     if j<=13 then
        if premier_menu then
           for i:=0 to drawe[j,1] do
           begin
                dessin_bloc(pentax+drawe[j,2]*bloc,(i-4+pentatrisy)*bloc,drawe[j,3],drawe[j,4]);
                delay(chute);
                if i<drawe[j,1] then
                   couleur:= false;
                dessin_bloc(pentax+drawe[j,2]*bloc,(i-4+pentatrisy)*bloc,drawe[j,3],drawe[j,4]);
                couleur:= true;
           end
        else
            dessin_bloc(pentax+drawe[j,2]*bloc,(drawe[j,1]-4+pentatrisy)*bloc,drawe[j,3],drawe[j,4]);

     (*N*)
     if j<=17 then
        if premier_menu then
           for i:=0 to drawn[j,1] do
           begin
                dessin_bloc(pentax+drawn[j,2]*bloc,(i-4+pentatrisy)*bloc,drawn[j,3],drawn[j,4]);
                delay(chute);
                if i<drawn[j,1] then
                   couleur:= false;
                dessin_bloc(pentax+drawn[j,2]*bloc,(i-4+pentatrisy)*bloc,drawn[j,3],drawn[j,4]);
                couleur:= true;
           end
        else
            dessin_bloc(pentax+drawn[j,2]*bloc,(drawn[j,1]-4+pentatrisy)*bloc,drawn[j,3],drawn[j,4]);
     (*T*)
     if j<=9 then
        if premier_menu then
           for i:=0 to drawt1[j,1] do
           begin
                dessin_bloc(pentax+drawt1[j,2]*bloc,(i-4+pentatrisy)*bloc,drawt1[j,3],drawt1[j,4]);
                delay(chute);
                if i<drawt1[j,1] then
                   couleur:= false;
                dessin_bloc(pentax+drawt1[j,2]*bloc,(i-4+pentatrisy)*bloc,drawt1[j,3],drawt1[j,4]);
                couleur:= true;
           end
        else
            dessin_bloc(pentax+drawt1[j,2]*bloc,(drawt1[j,1]-4+pentatrisy)*bloc,drawt1[j,3],drawt1[j,4]);
     (*A*)
     if j<=15 then
        if premier_menu then
           for i:=0 to drawa[j,1] do
           begin
                dessin_bloc(pentax+drawa[j,2]*bloc,(i-4+pentatrisy)*bloc,drawa[j,3],drawa[j,4]);
                delay(chute);
                if i<drawa[j,1] then
                   couleur:= false;
                dessin_bloc(pentax+drawa[j,2]*bloc,(i-4+pentatrisy)*bloc,drawa[j,3],drawa[j,4]);
                couleur:= true;
           end
        else
            dessin_bloc(pentax+drawa[j,2]*bloc,(drawa[j,1]-4+pentatrisy)*bloc,drawa[j,3],drawa[j,4]);
     (*T*)
     if j<=10 then
        if premier_menu then
           for i:=16 to drawt2[j,1] do
           begin
                dessin_bloc(trisx+drawt2[j,2]*bloc,(i-4+pentatrisy)*bloc,drawt2[j,3],drawt2[j,4]);
                delay(chute);
                if i<drawt2[j,1] then
                   couleur:= false;
                dessin_bloc(trisx+drawt2[j,2]*bloc,(i-4+pentatrisy)*bloc,drawt2[j,3],drawt2[j,4]);
                couleur:= true;
           end
        else
            dessin_bloc(trisx+drawt2[j,2]*bloc,(drawt2[j,1]-4+pentatrisy)*bloc,drawt2[j,3],drawt2[j,4]);
     (*R*)
     if j<=15 then
        if premier_menu then
           for i:=16 to drawr[j,1] do
           begin
                dessin_bloc(trisx+drawr[j,2]*bloc,(i-4+pentatrisy)*bloc,drawr[j,3],drawr[j,4]);
                delay(chute);
                if i<drawr[j,1] then
                   couleur:= false;
                dessin_bloc(trisx+drawr[j,2]*bloc,(i-4+pentatrisy)*bloc,drawr[j,3],drawr[j,4]);
                couleur:= true;
           end
        else
            dessin_bloc(trisx+drawr[j,2]*bloc,(drawr[j,1]-4+pentatrisy)*bloc,drawr[j,3],drawr[j,4]);
     (*I*)
     if j<=15 then
        if premier_menu then
           for i:=16 to drawi[j,1] do
           begin
                dessin_bloc(trisx+drawi[j,2]*bloc,(i-4+pentatrisy)*bloc,drawi[j,3],drawi[j,4]);
                delay(chute);
                if i<drawi[j,1] then
                   couleur:= false;
                dessin_bloc(trisx+drawi[j,2]*bloc,(i-4+pentatrisy)*bloc,drawi[j,3],drawi[j,4]);
                couleur:= true;
           end
        else
            dessin_bloc(trisx+drawi[j,2]*bloc,(drawi[j,1]-4+pentatrisy)*bloc,drawi[j,3],drawi[j,4]);
     (*S*)
     if j<=12 then
        if premier_menu then
           for i:=16 to draws[j,1] do
           begin
                dessin_bloc(trisx+draws[j,2]*bloc,(i-4+pentatrisy)*bloc,draws[j,3],draws[j,4]);
                delay(chute);
                if i<draws[j,1] then
                   couleur:= false;
                dessin_bloc(trisx+draws[j,2]*bloc,(i-4+pentatrisy)*bloc,draws[j,3],draws[j,4]);
                couleur:= true;
           end
        else
            dessin_bloc(trisx+draws[j,2]*bloc,(draws[j,1]-4+pentatrisy)*bloc,draws[j,3],draws[j,4]);
end;

end;

procedure dessin_aire_jeu;
(*dessine le quadrillage dans l'aire de jeu*)
var moitie: word;
begin
cleardevice;  {efface l'ecran}
(*choisit la couleur selon le niveau actuel*)
case niveau of
     1: setcolor(white);
     2: setcolor(yellow);
     3: setcolor(lightred);
     4: setcolor(red);
     5: setcolor(brown);
     6: setcolor(lightcyan);
     7: setcolor(blue);
     8: setcolor(lightmagenta);
     9: setcolor(magenta);
     10: setcolor(darkgray);
end;
(*dessine les lignes verticales*)
moitie:=0;
for k:=0 to (getmaxy div blocjeu+1) do
begin
    if k>(getmaxy div blocjeu+1) div 2 then
         moitie:=1;
    line(0,k*blocjeu-1+ajustx+moitie,getmaxx,k*blocjeu-1+ajustx+moitie);
    line(0,k*blocjeu-2+ajustx+moitie,getmaxx,k*blocjeu-2+ajustx+moitie);
end;
(*dessine les lignes horizontales*)
moitie:=0;
for k:=0 to (getmaxx div blocjeu+1) do
begin
    if k>(getmaxx div blocjeu+1) div 2 then
         moitie:=1;
    line(k*blocjeu-1+ajusty+moitie,0,k*blocjeu-1+ajusty+moitie,getmaxy);
    line(k*blocjeu-2+ajusty+moitie,0,k*blocjeu-2+ajusty+moitie,getmaxy);
end;
setfillstyle(1,black);
(*efface les lignes dans la zone de jeu*)
bar(jeux,jeuy,jeux+10*blocjeu-2,jeuy+20*blocjeu-2);
(*efface l'endroit reserve au pointage*)
bar(scorex,scorey,scorex+10*blocjeu-3,scorey+2*blocjeu-3);
outtextxy(scorex,scorey,' Points:');
(*efface le bas pour ecrire R-recommencer et Q-quitter*)
bar(jeux,jeuy+20*blocjeu+1,jeux+10*blocjeu-2,getmaxy);
settextstyle(0,horizdir,0);
settextjustify(lefttext,toptext);
outtextxy(jeux+1,jeuy+20*blocjeu+2,'R-recommencer');
settextjustify(righttext,toptext);
outtextxy(jeux+10*blocjeu-1,jeuy+20*blocjeu+2,'Q-quitter');
end;

procedure dessin_grille;
(*dessine carr‚ par carr‚ ce qu'il y a a l'interieur de la variable grille*)
begin
for i:=1 to 10 do
    for j:=1 to 20 do
        if grille[i,j]<>0 then
        begin
             setfillstyle(1,grille[i,j]);  {choisit la couleur}
             (*dessine le bloc*)
             bar((i-1)*blocjeu+jeux,(j-1)*blocjeu+jeuy,i*blocjeu+jeux-2,j*blocjeu+jeuy-2);
        end;

end;

procedure son_rangee(nombre:byte);
(*fais un son pour une rangee completee, deux sons consecutifs
  pour un combo de 2 rangees, trois sons pour 3 rangees, etc.*)
begin
for i:=1 to nombre do
begin
    sound(350+i*150);  {son de plus en plus aigu avec les repetitions}
    delay(150);        {le son dure 150 millisecondes}
    nosound;           {et arrete}
end;
end;

procedure fixerbloc;
(*Cette procedure inscrit les coordonnees du bloc dans la grille*)
var rangee_pleine: boolean;
    rangees: array[1..5] of byte;
    nombre_rangees: byte;
begin
(*inscrit dans la grille un bloc*)
for i:=1 to max(limd) do
    for j:=1 to max(limy) do
        if coordbloc[i,j]<>0 then
           grille[x1-1+i,y1-1+j]:=coordbloc[i,j];

(*initialise rangees*)
for i:=1 to 5 do
    rangees[i]:=0;

(*determine pour les 20 lignes si elles sont pleines*)
for j:=1 to 20 do
begin
    rangee_pleine:= true;
    for i:=1 to 10 do
        if grille[i,j]=0 then
           rangee_pleine:=false;
    if rangee_pleine then
       if rangees[1]=0 then
          rangees[1]:=j
          else if rangees[2]=0 then
                  rangees[2]:=j
                  else if rangees[3]=0 then
                          rangees[3]:=j
                          else if rangees[4]=0 then
                                  rangees[4]:=j
                                  else rangees[5]:=j;
end;

nombre_rangees:=0;

(*determine le nombre de rangees pleines*)
for i:=1 to 5 do
    if rangees[i]<>0 then
       inc(nombre_rangees);
inc(lignes,nombre_rangees); {augmente la variable ligne pour savoir quand changer de niveau}
(*ajoute le nombre de points en consequence*)
case nombre_rangees of
     1: inc(score,100*((niveau+1) div 3+1));
     2: inc(score,300*((niveau+1) div 3+1));
     3: inc(score,500*((niveau+1) div 3+1));
     4: inc(score,800*((niveau+1) div 3+1));
     5: inc(score,1200*((niveau+1) div 3+1));
end;

if nombre_rangees<>0 then
begin
(*fais un son pour celebrer*)
son_rangee(nombre_rangees);
(*fais tomber les blocs au dessus*)
    for k:=1 to nombre_rangees do
        for j:=rangees[k] downto 1 do
            for i:=1 to 10 do
                if j>1 then
                    grille[i,j]:= grille[i,j-1]
                else
                    grille[i,1]:= 0;
    (*redessine une nouvelle grille*)
    setfillstyle(1,black);
    bar(jeux,jeuy,jeux+10*blocjeu-2,jeuy+20*blocjeu-2);
    dessin_grille;
end;
end;

function collision(sorte: byte): boolean;
(*Renvoie true si une collision aurait lieu*)
var superposition: word;
    xyfictif: byte;
    collision_temporaire: boolean;
begin
collision:=false;
superposition:=0;
case sorte of
     (*test pour un deplacement vers la gauche*)
     75:if x1=1 then
           collision:=true
        else begin
           dec(x1);
           utilite:=1;
           dessin_bloc(1,1,numerobloc,spacebar);
           utilite:=0;
           for i:=1 to max(limd) do
               for j:=1 to max(limy) do
                   inc(superposition,coordbloc[i,j]*grille[x1-1+i,y1-1+j]);
           if superposition<>0 then
              collision:=true;
           inc(x1);
        end;
     (*test pour un deplacement vers la droite*)
     77:if x1+max(limd)-1=10 then
           collision:=true
        else begin
             inc(x1);
             utilite:=1;
             dessin_bloc(1,1,numerobloc,spacebar);
             utilite:=0;
             for i:=1 to max(limd) do
                 for j:=1 to max(limy) do
                     inc(superposition,coordbloc[i,j]*grille[x1-1+i,y1-1+j]);
             if superposition<>0 then
                collision:=true;
             dec(x1);
        end;
     (*test pour un deplacement vers le bas*)
     80:if y1+max(limy)-1=20 then
           collision:=true
        else begin
             inc(y1);
             utilite:=1;
             dessin_bloc(1,1,numerobloc,spacebar);
             utilite:=0;
             for i:=1 to max(limd) do
                 for j:=1 to max(limy) do
                     inc(superposition,coordbloc[i,j]*grille[x1-1+i,y1-1+j]);
             if superposition<>0 then
                collision:=true;
             dec(y1);
        end;
     (*test pour une rotation*)
     0,26: begin
             if sorte=0 then
                inc(spacebar)
             else
                dec(spacebar);
             utilite:=1;
             dessin_bloc(1,1,numerobloc,spacebar);
             utilite:=0;
             if (x1+max(limd)-1>10) or (y1+max(limy)-1>20) then
                collision:=true
             else begin
                  for i:=1 to max(limd) do
                      for j:=1 to max(limy) do
                          inc(superposition,coordbloc[i,j]*grille[x1-1+i,y1-1+j]);
                  if superposition<>0 then
                     collision:=true;
             end;
             if sorte=0 then
                dec(spacebar)
             else
                inc(spacebar);
        end;
     (*test pour un nouveau bloc*)
     1: begin
             for i:=1 to max(limd) do
                 for j:=1 to max(limy) do
                     inc(superposition,coordbloc[i,j]*grille[x1-1+i,y1-1+j]);
             if superposition<>0 then
                collision:=true;
        end;
end;
end;

procedure cadre_piece;
(*creation graphique de la zone ou est affichee les prochaines pieces*)
begin
setfillstyle(1,black);
(*efface pour creer des carres noirs*)
bar(piece_suivantex,piece_suivantey,piece_suivantex+7*blocjeu-3,piece_suivantey+5*blocjeu-3);
bar(piece_suivantex,piece_suivantey-2*blocjeu,piece_suivantex+7*blocjeu-3,piece_suivantey-3);
bar(piece_suivantex,piece_suivantey+5*blocjeu,piece_suivantex+7*blocjeu-3,piece_suivantey+15*blocjeu-2);
(*dessine la prochaine piece au milieu*)
for i:=1 to 3 do
begin
     utilite:=1;
     dessin_bloc(1,1,numero_next[i],1);
     utilite:=0;
     dessin_bloc(piece_suivantex+(7-max(limd))*blocjeu div 2,piece_suivantey+(5-max(limy))*blocjeu div 2+5*blocjeu*(i-1),
            numero_next[i],1);
end;
(*ecrit Prochaine piece*)
settextjustify(lefttext,toptext);
settextstyle(sansseriffont,horizdir,1);
outtextxy(piece_suivantex+2,piece_suivantey-2*blocjeu+3,'Prochaine piece');
settextstyle(sansseriffont,horizdir,3);
end;

(*permet la declaration des procedures pour pouvoir passer d'un menu a l'autre*)
procedure menu_principal;
          forward;
procedure highscore;
          forward;

procedure ouvrir_highscore;
begin
{$I-}
reset(hsfile);  {ouvre le fichier hspenta}
{$I+}
if (ioresult<>0) then {si il y a une erreur cree le fichier par defaut}
begin
     rewrite(hsfile);
     seek(hsfile,0);
     for b:=1 to 10 do
         write(hsfile,hsinitial[b]);
     close(hsfile);
     reset(hsfile);
end;

(*enregistre  ce qu'il y a a l'interieur du fichier hspenta*)
for b:=1 to 10 do
    read(hsfile,hsmodifie[b]);
close(hsfile); {referme le fichier}

end;

procedure sauvegarder_hs;
(*reecrit dans le fichier selon les nouveaux records*)
begin
rewrite(hsfile);
seek(hsfile,0);
for i:=1 to 10 do
    write(hsfile,hsmodifie[i]);
close(hsfile);
end;

procedure recuperer_nom;
(*demande le nom lorsqu'il y a un nouveau record*)
begin
window(35,19,45,20);
read(nom);
end;

procedure fin_partie;
(*lorsque les bloc s'empilent trop la partie se termine*)
begin
(*fais une boite pour le GAME OVER*)
setfillstyle(1,black);
bar(gmoverx-2*bloc,gmovery-5*bloc,gmoverx+37*bloc,gmovery+8*bloc);
for j:=1 to 2 do
    for i:=0 to 1 do
    begin
         line(gmoverx-2*bloc-j,gmovery+(13*i-5)*bloc-j*(1-i)+j*i,gmoverx+37*bloc+j,gmovery+(13*i-5)*bloc-j*(1-i)+j*i);
         line(gmoverx+(39*i-2)*bloc-j*(1-i)+j*i,gmovery-5*bloc-j,gmoverx+(39*i-2)*bloc-j*(1-i)+j*i,gmovery+8*bloc+j);
    end;
(*ecrit GAME OVER*)
grosseurbloc:=0;
for i:=1 to 32 do
    dessin_bloc(gmoverx+drawgo[i,1]*bloc,gmovery+(drawgo[i,2]-4)*bloc,drawgo[i,3],drawgo[i,4]);

ouvrir_highscore; {ouvre les highscore}
b:=0;
delay(1000);
(*verifie si nous avons un nouveau record*)
for i:=5 downto 1 do
begin
    val(hsmodifie[2*i],j,code);
    if j<score then
       b:=i;
end;

if b<>0 then {si nous avons un nouveau record}
begin
     (*ecrit nouveau record et entrer votre nom*)
     settextjustify(centertext,centertext);
     outtextxy(gmoverx+35*bloc div 2,gmovery+3*bloc,'Nouveau record !');
     settextjustify(lefttext,toptext);
     outtextxy(gmoverx,gmovery+4*bloc,'Entrer votre nom (max. 10 caracteres):');
     (*enregistre le nom*)
     recuperer_nom;
     (*decale les record inferieurs*)
     if b<5 then
        for i:=5 downto b+1 do
        begin
             hsmodifie[2*i-1]:=hsmodifie[2*i-3];
             hsmodifie[2*i]:=hsmodifie[2*i-2];
        end;
     (*ecrit le nouveau record*)
     hsmodifie[2*b-1]:=nom;
     str(score,S);
     hsmodifie[2*b]:=S;
     sauvegarder_hs;
end;
(*ouvre la page des records*)
highscore;
end;

procedure nouveau_bloc;
(*cree un nouveau bloc au hasard et qui ira dans la fenetre prochain bloc*)
(*prend le bloc de la fenetre et l'amene dans la surface de jeu*)
begin
spacebar:=1; numerobloc:=numero_next[1];
numero_next[1]:=numero_next[2];
numero_next[2]:=numero_next[3];
numero_next[3]:= random(29)+1;
utilite:=1;
dessin_bloc(1,1,numerobloc,spacebar);
utilite:=0;
(*si la piece depasse a droite ramene la*)
if x1+max(limd)-1>10 then
   x1:=10-max(limd)+1;
(*si il y a empilade des pieces alors GAME OVER*)
if collision(1) then
   fin_partie;
cadre_piece;     {encadre la piece suivante}
end;

procedure jouer;
begin
(*remets les conditions initiales*)
niveau:=1; score:=0; lignes:=0;
for i:=1 to 10 do
    for j:=1 to 20 do
        grille[i,j]:=0;

settextjustify(lefttext,toptext);
dessin_aire_jeu; {dessine le quadrillage de l'aire de jeu}
ecrire_niveau;   {ajoute l'ecriture NIVEAU 1}
Randomize;       {initialise la fonction random}
x1:=4; y1:=1;    {le premier bloc sera en y=0 et x=4}
spacebar:=1; numerobloc:=random(29)+1;  {son orientation sera 1 et le choix du bloc est determine au hasard}
for i:=1 to 3 do
    numero_next[i]:=random(29)+1;
grosseurbloc:=1; {la grosseur de ces blocs sera egale a la constante blocjeu}
cadre_piece;     {encadre la piece suivante}

repeat
      (*verifie si nous avons change de niveau*)
      niveau_precedent:=niveau;
      niveau:=lignes div lignes_par_niveau+1;
	   if niveau>10 then
			niveau:=10;

      if niveau_precedent<>niveau then   {si oui,...}
      begin
           dessin_aire_jeu; {dessine le quadrillage de l'aire de jeu}
           ecrire_niveau;   {ajoute l'ecriture NIVEAU 1}
           cadre_piece;     {remets le cadre de la piece suivante}
      end;
      (*dessine le bloc en chute*)
      dessin_bloc((x1-1)*blocjeu+jeux,(y1-1)*blocjeu+jeuy,numerobloc,spacebar);
      dessin_grille;    {dessine les bloc fixes a l'interieur de la grille}
      (*efface l'ancien score*)
      setfillstyle(1,black);
      bar(scorex+4*blocjeu,scorey,scorex+10*blocjeu-3,scorey+2*blocjeu-3);
      (*ecrit le score*)
      str(score,scorestring);
      outtextxy(scorex+4*blocjeu+3,scorey,scorestring);

      repeat            {delai qui peut etre interrompu par une action}
      inc(compteur);
      until (keypressed) or (compteur=(vitesse[niveau] div multiplicateur_vitesse));

      couleur:=false;   {efface le bloc puisqu'il va probablement bouger}
      dessin_bloc((x1-1)*blocjeu+jeux,(y1-1)*blocjeu+jeuy,numerobloc,spacebar);
      couleur:=true;    {remets la couleur a ''on'' pour qu'il puisse se redessiner en temps et lieu}

      if compteur<(vitesse[niveau] div multiplicateur_vitesse) then
      (*dans le cas ou le delai a ete interrompu par une action*)
      begin
         key:=readkey;   {enregistre l'action}
         case upcase(key) of
                 (*si aucune collision n'est possible et que le bloc n'est pas accote sur le mur de gauche*)
{fleche gauche}  #75: if not(collision(75)) then dec(x1);
                 (*si aucune collision n'est possible et que le bloc n'est pas accote sur le mur de droite*)
{fleche droite}  #77: if not(collision(77)) then inc(x1);
                 (*si aucune collision n'est possible*)
{fleche bas}     #80: if not(collision(80)) then
                      begin
                           compteur:=0;  {reinitialise le compteur pour un nouveau delai}
                           inc(y1);
                           inc(score); {ajoute un point pour avoir pese la fleche vers le bas}
                      end
                 (*sinon c'est qu'il y a un bloc en dessous alors enregistre*)
                 (*ses coordonnees dans le tableau grille*)
                      else begin
                           compteur:=0;   {reinitialise le compteur pour un nouveau delai}
                           fixerbloc;
                           y1:=1;
                           nouveau_bloc;
                      end;
                 (*si il n'y a pas de collision en faisant tourner la piece*)
{barre d'espace} ' ': if not(collision(0)) then
                      begin
                           inc(spacebar);
                      end;
{touche Z}       'Z': if not(collision(26)) then
                      begin
                           dec(spacebar);
                      end;
                 'R': jouer;
                 #72: begin
         (*descend le bloc jusqu'a renconter le fond ou un autre bloc*)
                             while not(collision(80)) do
                             begin
                                  inc(score,2);
                                  inc(y1);
                             end;
                             compteur:=0;       {initialise le compteur}
                             fixerbloc;         {ajoute le bloc a la grille}
                             y1:=1;
                             nouveau_bloc;      {cree un nouveau bloc}
                      end;

         end;
      end
      (*dans le cas ou le delai est arrive a terme sans action de l'usager*)
      else
      begin
           compteur:=0;   {reinitialise le compteur pour un nouveau delai}
           if not(collision(80)) then
                inc(y1)
           else begin
                fixerbloc;
                y1:=1;
                nouveau_bloc;
           end;
      end;


until upcase(key)='Q';   {quitter si la touche pesee est Q}
end;

procedure instructions;
(*affiche la page d'instructions*)
begin
cleardevice;  {efface l'ecran}
ecrire_reglements; {ecrit REGLES dans le haut de l'ecran}
setcolor(white);
(*cree une fausse zone de jeu*)
for j:=0 to 1 do
    for i:=0 to 1 do
    begin
         line(jeux+10*i*blocjeu-j,jeuy,jeux+10*i*blocjeu-j,jeuy+20*blocjeu);
         line(jeux,jeuy+20*i*blocjeu-j,jeux+10*blocjeu,jeuy+20*i*blocjeu-j);
    end;
(*dessine des faux bloc pour un exemple*)
grosseurbloc:=1;
dessin_bloc(jeux+5*blocjeu,jeuy+4*blocjeu,28,4);
dessin_bloc(jeux,jeuy+18*blocjeu,13,3);
dessin_bloc(jeux+3*blocjeu,jeuy+18*blocjeu,8,3);
dessin_bloc(jeux+7*blocjeu,jeuy+18*blocjeu,20,3);
(*ecrit les options du menu: Jouer ou Retour et sousligne la 1re lettre*)
settextjustify(lefttext,toptext);
outtextxy(jeux+13*blocjeu,jeuy+33*blocjeu div 2+2,'Jouer');
outtextxy(jeux+13*blocjeu,jeuy+36*blocjeu div 2+2,'Retour');
line(jeux+13*blocjeu,jeuy+18*blocjeu,jeux+13*blocjeu+9,jeuy+18*blocjeu);
line(jeux+13*blocjeu,jeuy+39*blocjeu div 2,jeux+13*blocjeu+10,jeuy+39*blocjeu div 2);
(*Ecrit toutes les instructions et les lignes qui les accompagnes*)
settextjustify(centertext,centertext);
settextstyle(sansseriffont,horizdir,4);
outtextxy(jeux div 2,jeuy+blocjeu,'Points');
line(jeux-15*blocjeu div 2,jeuy+2*blocjeu,jeux-3*blocjeu,jeuy+2*blocjeu);

settextstyle(sansseriffont,horizdir,1);
settextjustify(lefttext,toptext);

line(jeux+15*blocjeu div 2,jeuy+6*blocjeu,jeux+12*blocjeu,jeuy+9*blocjeu div 2);
outtextxy(jeux+21*blocjeu div 2,jeuy,'Bloc en chute libre. Il');
outtextxy(jeux+21*blocjeu div 2,jeuy+blocjeu,'s''arrete lorsqu''il frappe');
outtextxy(jeux+21*blocjeu div 2,jeuy+2*blocjeu,'un bloc plus bas ou le');
outtextxy(jeux+21*blocjeu div 2,jeuy+3*blocjeu,'fond de la zone de jeu.');

outtextxy(jeux+21*blocjeu div 2,jeuy+5*blocjeu,'Les touches deplacent');
outtextxy(jeux+21*blocjeu div 2,jeuy+6*blocjeu,'le bloc en chute libre');
outtextxy(jeux+21*blocjeu div 2,jeuy+7*blocjeu,'vers la direction desiree.');
outtextxy(jeux+21*blocjeu div 2,jeuy+8*blocjeu,'La fleche du haut fait');
outtextxy(jeux+21*blocjeu div 2,jeuy+9*blocjeu,'tomber le bloc en bas.');
(*cree un petit exemple de touches du clavier*)
for i:=0 to 1 do
begin
    line(jeux+(15+2*i)*blocjeu-2,jeuy+21*blocjeu div 2-1,jeux+(15+2*i)*blocjeu-2,jeuy+25*blocjeu div 2-1);
    line(jeux+15*blocjeu-2,jeuy+(21+4*i)*blocjeu div 2-1,jeux+17*blocjeu-2,jeuy+(21+4*i)*blocjeu div 2-1);

end;
for j:=-1 to 1 do
    for i:=0 to 1 do
    begin
        line(jeux+(15+2*i+2*j)*blocjeu+2*j-2,jeuy+13*blocjeu-9,jeux+(15+2*i+2*j)*blocjeu+2*j-2,jeuy+15*blocjeu-9);
        line(jeux+(15+2*j)*blocjeu+2*j-2,jeuy+(13+2*i)*blocjeu-9,jeux+(17+2*j)*blocjeu+2*j-2,jeuy+(13+2*i)*blocjeu-9);
    end;

outtextxy(jeux+21*blocjeu div 2,jeuy+29*blocjeu div 2,'La barre d''espace et Z');
outtextxy(jeux+21*blocjeu div 2,jeuy+31*blocjeu div 2,'font tourner les pieces.');

line(jeux-blocjeu div 2,jeuy+39*blocjeu div 2,jeux-7*blocjeu div 2,jeuy+39*blocjeu div 2);
outtextxy(jeux-10*blocjeu,jeuy+15*blocjeu-3,'En remplissant une');
outtextxy(jeux-10*blocjeu,jeuy+16*blocjeu-3,'ligne completement,');
outtextxy(jeux-10*blocjeu,jeuy+17*blocjeu-3,'cette ligne s''efface');
outtextxy(jeux-10*blocjeu,jeuy+18*blocjeu-3,'et tous les bloc plus');
outtextxy(jeux-10*blocjeu,jeuy+19*blocjeu-3,'haut tombent.');

outtextxy(jeux-10*blocjeu,jeuy+2*blocjeu,'Combos:');
outtextxy(jeux-10*blocjeu,jeuy+3*blocjeu,'1 ligne......');
outtextxy(jeux-10*blocjeu,jeuy+4*blocjeu,'2 lignes....');
outtextxy(jeux-10*blocjeu,jeuy+5*blocjeu,'3 lignes....');
outtextxy(jeux-10*blocjeu,jeuy+6*blocjeu,'4 lignes....');
outtextxy(jeux-10*blocjeu,jeuy+7*blocjeu,'5 lignes..');
outtextxy(jeux-10*blocjeu,jeuy+9*blocjeu,'Multiplicateur:');
outtextxy(jeux-10*blocjeu,jeuy+10*blocjeu,'Niveaux 1.............');
outtextxy(jeux-10*blocjeu,jeuy+11*blocjeu,'Niveaux 2-4..........');
outtextxy(jeux-10*blocjeu,jeuy+12*blocjeu,'Niveaux 5-7..........');
outtextxy(jeux-10*blocjeu,jeuy+13*blocjeu,'Niveaux 8-X..........');

(*fais des fleches a l'interieur des touches*)
settextstyle(0,horizdir,3);
settextjustify(centertext,centertext);
outtextxy(jeux+16*blocjeu,jeuy+13*blocjeu+10+1,chr(25));
outtextxy(jeux+14*blocjeu-1,jeuy+13*blocjeu+10+1,chr(27));
outtextxy(jeux+18*blocjeu+1,jeuy+13*blocjeu+10+1,chr(26));
outtextxy(jeux+16*blocjeu,jeuy+11*blocjeu+10+1,chr(24));

settextstyle(sansseriffont,horizdir,1);
settextjustify(righttext,toptext);
outtextxy(jeux-4,jeuy+3*blocjeu,'100 points');
outtextxy(jeux-4,jeuy+4*blocjeu,'300 points');
outtextxy(jeux-4,jeuy+5*blocjeu,'500 points');
outtextxy(jeux-4,jeuy+6*blocjeu,'800 points');
outtextxy(jeux-4,jeuy+7*blocjeu,'1200 points');
outtextxy(jeux-7,jeuy+10*blocjeu,'1x');
outtextxy(jeux-7,jeuy+11*blocjeu,'2x');
outtextxy(jeux-7,jeuy+12*blocjeu,'3x');
outtextxy(jeux-7,jeuy+13*blocjeu,'4x');

(*fais bouger le curseur vert pour les options soit Jouer ou Retour*)
option:=1; grosseurbloc:=0;
repeat
      (*dessine le petit bloc*)
      dessin_bloc(jeux+12*blocjeu,jeuy+(31+3*option)*blocjeu div 2+3,1,1);
      key:=readkey; {attend une touche}
      (*efface le petit bloc puisqu'il va probablement bouger*)
      couleur:=false;
      dessin_bloc(jeux+12*blocjeu,jeuy+(31+3*option)*blocjeu div 2+3,1,1);
      couleur:=true;

      case upcase(key) of
           #72: if option=2 then dec(option);
           #80: if option=1 then inc(option);
           'J': jouer;
           'R': menu_principal;
           ' ': case option of
                     1:jouer;
                     2:menu_principal;
                end;
      end;
until upcase(key)='Q'; {si la personne veut quitter}

end;

procedure highscore;
(*cree la page avec les highscore*)
begin
cleardevice;    {efface l'ecran}
ecrire_highscore;  {ecrit HIGHSCORE}
ouvrir_highscore;  {ouvre le fichier hspenta}
(*ecrit les records*)
setcolor(white);
settextjustify(centertext,centertext);
settextstyle(sansseriffont,horizdir,3);
for j:=1 to 5 do
     outtextxy(getmaxx div 2,100+50*j,hsmodifie[2*j-1]+'.......'+hsmodifie[2*j]);
(*dessine de jolis petits blocs*)
dessin_bloc(155,134,19+length(hsmodifie[1]),random(3)+1);
dessin_bloc(435,184,19+length(hsmodifie[3]),random(3)+1);
dessin_bloc(155,234,19+length(hsmodifie[5]),random(3)+1);
dessin_bloc(435,284,19+length(hsmodifie[7]),random(3)+1);
dessin_bloc(155,334,19+length(hsmodifie[9]),random(3)+1);
(*cree les options soit Jouer or Retour*)
settextjustify(centertext,toptext);
outtextxy(getmaxx div 3,410,'Jouer');
outtextxy(2*getmaxx div 3,410,'Retour');

line(getmaxx div 3 -30,442,getmaxx div 3-20,442);  {ligne sous le J}
line(2*getmaxx div 3 -35,442,2*getmaxx div 3-25,442); {ligne sous le R}
(*deplace le petit curseur vert pour choisir une option*)
option:=1; grosseurbloc:=0;
repeat
      dessin_bloc(206*option-38,421,1,1); {dessine le petit bloc}
      key:=readkey;                    {attend une touche de l'usager}
      (*efface le petit bloc*)
      couleur:=false;
      dessin_bloc(206*option-38,421,1,1);
      couleur:=true;
      (*chosit l'option a executer*)
      case upcase(key) of
           #75: if option=2 then dec(option);
           #77: if option=1 then inc(option);
           'J': jouer;
           'R': menu_principal;
           ' ': case option of
                     1:jouer;
                     2:menu_principal;
                end;
      end;
until upcase(key)='Q';   {si la personne veut quitter}
end;

procedure menu_principal;
(*affiche le menu principal avec l'animation si c'est la 1re fois qu'il vient dans le menu*)
begin
cleardevice; {efface l'ecran}
animation_debut;   {fait l'animation}
premier_menu:=false;  {lui dit de ne plus faire l'animation a nouveau meme si le jouer revient au menu}
(*ecrit les options et les prgrammeurs*)
settextstyle(sansseriffont,horizdir,3);
settextjustify(centertext,toptext);
outtextxy(getmaxx div 2,28*bloc,'par Sebastien Dame et Julien Dufresne');
settextjustify(centertext,centertext);
outtextxy(getmaxx div 2,34*bloc,'    Jouer    Instructions    Highscore     Quitter');

line(78,35*bloc+4,88,35*bloc+4);  {ligne sous le J}
line(183,35*bloc+4,190,35*bloc+4);{ligne sous le I}
line(356,35*bloc+4,370,35*bloc+4);{ligne sous le H}
line(522,35*bloc+4,536,35*bloc+4);{ligne sous le Q}
(*fais deplacer le petit curseur pour choisir une option*)
option:=1; niveau:=1;
repeat
      dessin_bloc(a[option]*bloc,34*bloc,1,1); {dessine le petit bloc}
      key:=readkey;     {attend la touche de l'usager}
      (*efface le petit bloc*)
      couleur:= false;
      dessin_bloc(a[option]*bloc,34*bloc,1,1);
      couleur:= true;
      (*chosit l'action a faire*)
      case upcase(key) of
           #75: if option>1 then dec(option);
           #77: if option<4 then inc(option);
           'J': jouer;
           'I': instructions;
           'H': highscore;
           ' ': case option of
		     1: jouer;
		     2: instructions;
		     3: highscore;
		     4: key:='Q';
		end;
      end;

until upcase(key)='Q'; {quitte s'il a pese sur Q}
end;


begin
pilote:=detect;                       {determine le mode graphique de l'ecran}
initgraph(pilote,mode,'M:/BGI');      {intialise mode graphique}
assign(hsfile,'M:\hspenta.dat');      {assigne le fichier hspenta.dat a la variable hsfile}
premier_menu:=true;                   {mets l'animation a on}
menu_principal;                       {va dans le menu principal}
closegraph;                           {ferme le mode graphique}
Halt(1);                              {termine le programme avec la valeur 1 (pas d'erreur)}
end.