PROGRAM Verkehr_CA;

{ Programm fr eine einfache Verkehrssimulation nach einem Modell in  }
{ A. Bachem, K. Nagel, M. Rickert: Ultraschnelle Mikroskopische       }
{ Verkehrssimulationen; verffentlicht in: Plieger R.,Grebe R.(Hrsg.) }
{ Parallele Datenverarbeitung aktuell: TAT '94, IOS Press, 1994.      }

{ Programm von Martin Schreck, Student der FH Mnchen am 1.6.95       }
{ fr Das Chaos- Seminar SS95 an der FHM                              }

USES
  graph,crt;

CONST
  XMAX = 700;
  DICHTE = 0.2;

TYPE
  car_t= array [0..XMAX] of shortint;

{ Erzeugen eines Arrays, das eine Strae darstellt }
{ Arrayelement = -1 : Leere Stelle      }
{              =  0 : Stehendes Auto    }
{              =  1..5 : Fahrendes Auto }


VAR
  i, x_max, y_max   : integer;
  farbe_max         : byte;
  car               : car_t;

{$I initgraf.inc}

PROCEDURE Geschw_Init (var car: car_t; x_max: integer);

{ Erzeugt eine zufllige Anfangkonfiguration }

VAR
  i  :integer;

BEGIN
  randomize;
  FOR i:=0 TO x_max+11 DO
    car [i]:=-1;
  i:=0;
  WHILE i <= x_max DO
  BEGIN
    IF random<DICHTE THEN
    BEGIN
      car[i]:=random(6);
      i:=i+car[i];
    END;
    i:=i+1;
  END;
END;

PROCEDURE Geschw_Update (var car: car_t; x_max: integer);

{ Berechnet den Zustand der Strae zu einem neuen Zeitpunkt }

VAR
  i      : integer;
  v, gap : byte;
  r      : real;

BEGIN
  gap:=0;                   { Erstes Element erzeugen }
  IF (car[0]= -1) AND (Random<DICHTE+0.2) THEN
  BEGIN
    WHILE (car[gap+1]= -1) AND (gap<10) DO
      gap:= gap+1;
    IF gap>4 THEN car[0]:=random(6)
    ELSE car[0]:=Random(gap+1);
  END;

  i:=0;                     { Update- Schleife }
  REPEAT
    IF car[i]<> -1 THEN
    BEGIN
      gap:=0;
      WHILE (car[i+gap+1]= -1) AND (gap<10) DO	{Abstand ermitteln}
        gap:=gap+1;
      v:=car[i];
      IF v>gap Then v:= gap			{Bremsen}
      ELSE IF (v<gap) AND (v<5) THEN v:=v+1;	{Beschleunigen}
      IF (Random<0.5) AND (v<>0) THEN v:=v-1;	{Randomisieren}
      IF (i+v)<x_max THEN car[i+v]:=v;		{Bewegung}
      IF v<>0 THEN car[i]:= -1;
      i:=i+v;
    END;
    i:=i+1;
  UNTIL i>=x_max;
END;

PROCEDURE Fahrspur_aus (car: car_t; x_max,y: integer; farbe_max: byte);

{ Graphische Ausgabe: Element= -1 : Leer, 0..5 : Auto }

VAR
  i  : integer;

BEGIN
  FOR i:=1 TO x_max DO
    IF car[i]>=0 THEN
      putpixel(i,y,farbe_max);
END;

BEGIN
  Grafik_Bildschirm (x_max,y_max,farbe_max);   {Procedure in initgraph.inc}
  Geschw_Init(car,x_max);
  Fahrspur_aus(car,x_max,0,farbe_max);
  FOR i:=1 TO y_max DO
  BEGIN
    Geschw_Update(car,x_max);
    Fahrspur_aus(car,x_max,i,farbe_max);	
  END;
  Readln;
  CloseGraph;
END.

