(*****************************************************************)
(*  Paul Koop M.A. Zellulaerer Automat Januar 1995               *)
(* Die Simulation wurde ursprunglich entwickelt,                 *)
(* um die Verwendbarkeit von Zellularautomaten                   *)
(* fuer die Algorithmisch Rekursive Sequanzanalyse               *)
(* zu ueberpruefen							     *)
(* Modellcharakter hat allein der Quelltext. Eine Compilierung   *)
(* dient nur als Falsifikationsversuch                           *)
(*****************************************************************)
 PROGRAM zellulaerer_automat (INPUT,OUTPUT);
 USES dos,crt;
 CONST
  koop      ='Paul Koop: zellul„rer Automat (vgl. VARELA, F.J. 1990 S.63ff) ENDE=TASTE';
  tot       = char(4);
  lebendig  = char(1);
  c1        =  1;
  c80       = 80;

(*----------- Datentypen -------------------------------------------------*)
 TYPE
  zeiger  = ^zelle;
  zelle   = RECORD
             lebendig  :boolean;
             vorgaenger,
             nachfolger:zeiger;
            END;

(*----------- Variablen --------------------------------------------------*)
  VAR
   neu,
   a,
   aa,
   b,
   ab : zeiger;
   ch : char;

(*----------- Prozeduren -------------------------------------------------*)
   PROCEDURE aufbau;
    VAR
     zaehler,
     zahl    : integer;
    BEGIN
     clrscr;
     textbackground(red);
     textcolor(white);
     window(1,1,80,1);
     clrscr;
     write(koop);
     window(1,2,80,25);
     textbackground(black);
     clrscr;
     zaehler := c1;
     new(a);
     new(b);
     aa := a;
     ab := b;
     REPEAT
      zaehler := zaehler + c1;
      new(neu);
      a^.nachfolger := neu;
      neu^.vorgaenger := a;
      a := neu;
      zahl := random(2);
      IF zahl = c1 THEN a^.lebendig := true
                   ELSE a^.lebendig := false;
      new(neu);
      b^.nachfolger := neu;
      neu^.vorgaenger := b;
      b := neu;
     UNTIL zaehler = c80;
     b^.nachfolger := ab;
     ab^.vorgaenger := b;
     a^.nachfolger := aa;
     aa^.vorgaenger := a;
    END;

    PROCEDURE abbau(a,aa,b,ab:zeiger);
     BEGIN
      IF a^.nachfolger <> aa
         THEN abbau(a^.nachfolger,aa,b^.nachfolger,ab);
      dispose(a);
      dispose(b);
      window(1,1,80,25);
      textcolor(white);
      textbackground(black);
      clrscr;
     END;

    PROCEDURE zeige (VAR wurzel,aktuell: zeiger);
     BEGIN
      aktuell := wurzel;
      REPEAT
       IF aktuell^.lebendig THEN BEGIN textcolor(red); write(lebendig) END
                            ELSE BEGIN textcolor(yellow); write(tot) END;
       aktuell := aktuell^.nachfolger
      UNTIL aktuell = wurzel;
     END;

    PROCEDURE zeittakt (VAR von,avon,nach,anach: zeiger);
     BEGIN
      avon := von;
      anach:= nach;
      REPEAT
       IF((avon^.vorgaenger^.lebendig)
          xor
          (avon^.nachfolger^.lebendig))
       THEN anach^.lebendig := true
       ELSE anach^.lebendig := false;
       avon :=  avon^.nachfolger;
       anach:= anach^.nachfolger
      UNTIL avon = von
     END;

(************ Hauptprogramm ***********************************************)
 BEGIN
 checkbreak := false;
 clrscr;
 randomize;
 aufbau;

(*----------------------------------- zellulaerer Automat ----*)
 REPEAT
  zeige(a,aa);
  zeittakt(a,aa,b,ab);
  zeige(b,ab);
  zeittakt(b,ab,a,aa);
 UNTIL keypressed;
(*------------------------------------------------------------*)

 REPEAT
  ch := readkey;
 UNTIL not(keypressed);
 a := aa;
 b := ab;
 abbau(a,aa,b,ab);
 clrscr;
 checkbreak := true;
 END.
(************ Ende ********************************************************)

