{*************************************************************

         - - -   Le CyberZo‹de Qui Fr‚tille  - - -

                 .. le Web scientifique ..

  http://www.multimania.com/cyberzoide/info/turbo/turbo.htm
                 cyberzoide@multimania.com

***************************************************************

Il suffisait de rajouter VAR devant la d‚claration des tableaux 
dans la proc‚dure INITIALISATION }


program mai99;

uses crt;

const n=5;  {nombre de gares}

type tab1=array[1..n] of string;  {tableau des noms de gare}

type tab2=array[1..n] of integer;  {tableau des distances des gares / … Lyon}

procedure initialisation(var gares:tab1; var distances:tab2);
begin
gares[1]:='Lyon';
gares[2]:='Givors';
gares[3]:='Rive-de-Gier';
gares[4]:='Saint Chamond';
gares[5]:='Saint-Etienne';
distances[1]:=0;
distances[2]:=22;
distances[3]:=37;
distances[4]:=47;
distances[5]:=59;
end;

function arrondi(prix:real):integer;
begin
arrondi:=trunc(prix)+1;
end;

function prix(distances:tab2;depart,arrivee,classe,reduc:integer):integer;
var x:real;
    d:integer;
begin
d:=abs(distances[arrivee]-distances[depart]); {distance entre les 2 gares}
if d<30 then x:=10+0.5*d {calcul du prix pour la 2Š classe en fctø de la dist}
        else x:=15+0.33*d;
if classe=1 then x:=x*0.5+x; {calcul du prix pour la 1Šre classe}
case reduc of          {application des r‚ductions}
     20 : x:=x-x*0.2;
     50 : x:=x-x*0.5;
end;
prix:=arrondi(x);
end;

function choix(gares:tab1;ordre,deja:integer):integer;
var i,x:integer;
    test:boolean;
    s,plus:string;
begin
if (n>=1) and (ordre in [1..2]) then {en cas d'absurdit‚ pour "n" et "ordre"}
   begin
   case ordre of               {artifice d'affichage, pour faire mieux}
        1 : s:='de d‚part';
        2 : s:='d''arriv‚e';
   end;
   if (deja<>0) then         {mˆme chose}
      begin
      str(deja,plus);
      plus:=' et diff‚rent de '+plus;
      end
      else plus:='';
   repeat
   writeln('Choisissez une gare ',s,' en indiquant son num‚ro correspondant : ');
   for i:=1 to n do if (i<>deja) then writeln('Gare nø',i,': ',gares[i]);
   { À> affichage de tous les noms de gare sauf celle d‚ja choisie
        pour le d‚part si cela est d‚j… fait }
   write('Votre choix : ');
   readln(x);
   writeln;
   test:=(x in [1..n]) and (x<>deja); {test de la validit‚ du choix}
   if test then choix:=x
           else writeln('Erreur de saisie! Entrez un nombre compris dans [1,',n,']',plus,'.');
   until test;
   end
   else writeln('Aucune gare disponible!'); {en cas d'absurdit‚}
writeln;
end;

function euro(franc:integer):real;
begin
euro:=round((franc/6.55957)*100)/100;
{les facteurs "100" sont l… pour concerver les centimes qui sont derriŠre
la virgule}
end;

procedure paiement(prix:integer);
var reste,somme,arendre,i,j:integer;
    test:boolean;
    pieces:array[1..5] of integer;
begin
 {!-- initialisation d'un tableau temporaire pour les piŠces de monnaie}
 pieces[1]:=20;
 pieces[2]:=10;
 pieces[3]:=5;
 pieces[4]:=2;
 pieces[5]:=1;
 {--//}
reste:=prix;
arendre:=0;
while (reste>0) do  {tant qu'il reste quelque chose … payer}
      begin
        repeat
           writeln('Il vous reste … payer : ',reste,' F');
           write('Introduisez une piŠce ou un billet de 1, 2, 5, 10 ou 20 Francs : ');
           readln(somme);
           test:=(somme=1) or (somme=2) or (somme=5) or (somme=10) or (somme=20);
           if not test then writeln('Erreur de saisie! Entrez une somme valide. Les chŠques ne sont pas accept‚s.');
        until test;
      writeln('Vous avez entr‚ une piŠce de : ',somme,' F');
      reste:=reste-somme; {recalcul du reste … payer}
      if reste<0 then arendre:=-reste;
      { À> si le reste est n‚gatif, on rend la monnaie}
      if arendre<>0 then  {tant qu'on doit rendre de la monaie}
         begin
         writeln('Je vous rends :');
         i:=1;     {on commencera … rendre la piŠce de poids le plus fort}
           repeat
            j:=pieces[i];
            if arendre-j>=0 then  {on essaie du mieux que possible de rendre
            syst‚matiquement la piŠce de poids le plus fort}
               begin
               dec(arendre,j);
               writeln(' - une piŠce de ',j,' F');
               end
               else if i<5 then inc(i);
           until arendre<=0;
         end;
      end;
writeln('Merci, … bient“t!');  {on est des vendeurs aprŠs tout ! }
writeln;
end;

var depart,arrivee,reduc,classe,prixdubillet:integer;
    test:boolean;
    laclasse:string;
    gares:tab1;
    distances:tab2;

BEGIN
clrscr;
writeln('                 - SIMULATEUR DE BILLETERIE AUTOMATIQUE -');
writeln;
initialisation(gares,distances);
depart:=choix(gares,1,0);
arrivee:=choix(gares,2,depart);
repeat
write('Entrez votre pourcentage de r‚duction (0, 20 ou 50): ');
readln(reduc);
test:=(reduc=0) or (reduc=20) or (reduc=50);
if not test then writeln('Erreur de saisie! Entrez un pourcentage valide.');
writeln;
until test;
repeat
write('En quelle classe d‚sirez-vous voyager (1 ou 2): ');
readln(classe);
test:=classe in [1..2];
if not test then writeln('Erreur de saisie! Entrez une classe existante.');
writeln;
until test;
prixdubillet:=prix(distances,depart,arrivee,classe,reduc); {calcul du prix}
case classe of   {artifice d'afichage n‚cessaire pour repecter l'‚nonc‚}
     1 : laclasse:='1Šre';
     2 : laclasse:='2Šme';
end;
writeln('Vous avez demand‚ un billet de ',gares[depart],' … ',gares[arrivee],
        ' en ',laclasse,' classe, avec ',reduc,'% de r‚duction.');
writeln('Le prix du billet est de ',prixdubillet,' F, soit ',
         euro(prixdubillet):0:2,' euros.');
                           { À> formatage de la donn‚e … afficher }
writeln;
paiement(prixdubillet);
readln;
END.