program operation_embouteillage;

{$I "include:intuition/intuition.i"}
{$I "include:utils/crt.i"}
{$I "include:libraries/dos.i"}

const
    win : newwindow = (0,0,640,150,-1,-1,closewindow_f,windowdepth + windowdrag + activate + windowticked,
                       nil,nil,"Opération embouteillage",nil,nil,-1,-1,-1,-1,WBENCHSCREEN_f);

{ Constante de couleur des feux }
    vert   : integer = 2;
    orange : integer = 3;
    rouge  : integer = 1;

{ Texte des feux de l'onde verte }
    vert1_tx   : string = "vv";
    orange1_tx : string = "oo";
    rouge1_tx  : string = "rr";

{ Texte des feux des croisements }
    vert2_tx   : string = "V";
    orange2_tx : string = "O";
    rouge2_tx  : string = "R";

{ Temps des feux de l'onde verte }
    vert1_tp   : integer = 45;
    orange1_tp : integer = 15;
    rouge1_tp  : integer = 75;

{ Temps des feux des croisements }
    vert2_tp   : integer = 30;
    orange2_tp : integer = 15;
    rouge2_tp  : integer = 90;

type
    feu = record
       x     : integer;                       { position en x à l'écran }
       y     : integer;                       { position en y à l'écran }
       temps : byte;       { nombre de seconde qu'il reste dans un etat }
       etat  : byte;              { etat du feu : rouge, vert ou orange }
       texte : string;  { Texte qui sera affiché pour signifier un état }
    end;

var
    i,j : integer;
    t : array[1..4,1..3] of feu;
            { ^    ^
              |    +- 1 : onde verte / 2 et 3 : rue transversales
              +------ 1,2,3 et 4 representent les croisements }
    a : address;
    w : windowptr;

procedure affiche(fire:feu);
begin
 with fire do
 begin
  gotoxy(a,x,y);
  textcolor(a,etat);
  writestring(a,texte);
 end;
end;

procedure init;
begin
 w := openwindow(@win);            { On ouvre la fenêtre }
 a := attachconsole(w);            { On recupére l'adresse }
 cursoff(a);                       { On eteint le curseur }

 t[1,1].temps := 15;
 t[1,1].etat  := rouge;
 t[1,1].texte := rouge1_tx;
 t[1,1].x     := 12;
 t[1,1].y     := 15;

 t[1,2].temps := 90;
 t[1,2].etat  := rouge;
 t[1,2].texte := rouge2_tx;
 t[1,2].x     := 13;
 t[1,2].y     := 11;

 t[1,3].temps := 90;
 t[1,3].etat  := rouge;
 t[1,3].texte := rouge2_tx;
 t[1,3].x     := 21;
 t[1,3].y     := 15;

 t[2,1].temps := 6;
 t[2,1].etat  := VERT;
 t[2,1].texte := vert1_tx;
 t[2,1].x     := 31;
 t[2,1].y     := 15;

 t[2,2].temps := 36;
 t[2,2].etat  := ROUGE;
 t[2,2].texte := rouge2_tx;
 t[2,2].x     := 32;
 t[2,2].y     := 11;

 t[2,3].temps := 36;
 t[2,3].etat  := ROUGE;
 t[2,3].texte := rouge2_tx;
 t[2,3].x     := 40;
 t[2,3].y     := 15;

 t[3,1].temps := 63;
 t[3,1].etat  := ROUGE;
 t[3,1].texte := rouge1_tx;
 t[3,1].x     := 51;
 t[3,1].y     := 15;

 t[3,2].temps := 3;
 t[3,2].etat  := ROUGE;
 t[3,2].texte := rouge2_tx;
 t[3,2].x     := 52;
 t[3,2].y     := 11;

 t[3,3].temps := 3;
 t[3,3].etat  := ROUGE;
 t[3,3].texte := rouge2_tx;
 t[3,3].x     := 60;
 t[3,3].y     := 15;

 t[4,1].temps := 45;
 t[4,1].etat  := ROUGE;
 t[4,1].texte := rouge1_tx;
 t[4,1].x     := 71;
 t[4,1].y     := 15;

 t[4,2].temps := 15;
 t[4,2].etat  := VERT;
 t[4,2].texte := vert2_tx;
 t[4,2].x     := 72;
 t[4,2].y     := 11;

 t[4,3].temps := 15;
 t[4,3].etat  := VERT;
 t[4,3].texte := vert2_tx;
 t[4,3].x     := 72;
 t[4,3].y     := 11;

end;

procedure graphique;
begin
 writestring(a,"                        Opération embouteillage v1.1\n");
 writestring(a,"                     Copyright © 1993 by Michel TOURNAY\n");
 writestring(a,"           Premiére version developpée en TurboPascal 5.5 sur PC\n");
 writestring(a,"                    Appuyez sur une touche pour terminer\n");
 gotoxy(a,1,11);
 textcolor(a,2);

{ pour afficher '\', il faut, dans les commandes write, writeln et writestring,
  en placer deux à la suite }

 writestring(a,"|             | | |              | | |               | | |               | |   ");
 writestring(a,"\\-------------/ | \\--------------/ | \\---------------/ | \\---------------/ |   ");
 writestring(a,"----------------+------------------+-------------------+-------------------+-  ");
 writestring(a,"/-------------\\ | /--------------\\ | /---------------\\ | /---------------\ \ |   ");
 writestring(a,"|             | | |              | | |               | | |               | |   ");
 for i := 1 to 4 do
  for j := 1 to 3 do
   affiche(t[i,j]);
end;

procedure change_etat(i,j : integer);
begin
 with t[i,j] do
 begin
  if etat = rouge then    { si le feu est rouge}
  begin
   etat  := vert;         { il devient vert }
   if (j = 1) then        { si j = 1 alors onde verte }
   begin
    texte := vert1_tx;    { un certain texte }
    temps := vert1_tp;    { un certain temps }
   end
   else                   { sinon feu d'une rue transversale }
   begin
    texte := vert2_tx;    { un autre texte }
    temps := vert2_tp;    { un autre temps }
   end;
  end
  else                    { sinon }
  if etat = vert then     { si il est vert }
  begin
   etat  := orange;       { il devient orange }
   if (j = 1) then
   begin
    texte := orange1_tx;
    temps := orange1_tp;
   end
   else
   begin
    texte := orange2_tx;
    temps := orange2_tp;
   end;
  end
  else                    { sinon }
  begin
   etat  := rouge;        { il devient rouge car il n'etait ni rouge ni vert }
   if (j = 1) then
   begin
    texte := rouge1_tx;
    temps := rouge1_tp;
   end
   else
   begin
    texte := rouge2_tx;
    temps := rouge2_tp;
   end;
  end;
 end;
 affiche(t[i,j]);
end;

begin
 init;
 graphique;
 while not keypressed(a) do
 begin
  delay(40);                  { Si on n'attend pas un peu, cela va trop vite }
  for i := 1 to 4 do
   for j := 1 to 3 do
   begin
    t[i,j].temps := t[i,j].temps - 1;
    if t[i,j].temps = 0 then change_etat(i,j);
   end;
 end;
 clrscr(a);
 detachconsole(a);
 closewindow(w);
end.
