Langtonův mravenec

Je příkladem jednoduchého celularního automatu. "Mravenec" žije na "čtvečkovaném papíře". Pro svůj "život" má jednoduchá pravidla:

Tato jednoduchá pravidla vedou, překvapivě k "cílevědomému" počínání.

Langtonův mravenec za pomoci Javascript

  1. Nejprve vytvoříme pro mravence "svět" tj. mřížku 200x200 čtverečků
    (čísla řádků jsou přidána pro přehlednost)
    1.  <script language=JavaScript>
    2.  document.write("<table border=1>");
    3.  for (r=0;r<200;r++){
    4.    document.write("<tr>");
    5.    for (s=0;s<200;s++){
    6.      document.write("<td></td>");
    7.    }
    8.    document.write("</tr>");
    9.  }
    10. document.write("</table");
    11. </script>
    


  2. Každé buňce dáme speciální identifikátor tj. id řádek 5.
    (každá buňka ma id např. a1_10 používáme funkci přiřazenou k číslu tj. r.toString())
    6.  document.write("<td id=\"a"+r.toString()+"_"+s.toString()+"\"></td>");
    


  3. Připravíme si funkci obarvi(r,s,barva), která obarví políčko r,s příslušnou barvou
    function obarvi(r,s,barva){
      if (barva==1){
        document.getElementById("a"+r.toString()+"_"+s.toString()).style.backgroundColor="red";
      }else{
        document.getElementById("a"+r.toString()+"_"+s.toString()).style.backgroundColor="white";
      }
    }
    
  4. Obarvíme úhlopříčku - cyklus
    for (i=0;i<200;i++){
      obarvi(i,i,1);
    }
    


  5. V rámci "výroby" tabulky vyplníme dvourozměrné pole policka, zatím vyplníme nulami. Zároveň upravíme funkci obarvi() tak, aby se příslušným způsobem změnila i hodnota v poli policka[][]
    <script language=JavaScript>
    var policka=Array();
    document.write("<table border=1>");
    for (r=0;r<200;r++){
      document.write("<tr>");
      policka[r]=Array();
      for (s=0;s<200;s++){
        policka[r][s]=0;
        document.write("<td></td>");
      }
      document.write("</tr>");
    }
    document.write("</table");
    </script>
    


    function obarvi(r,s,barva){
      if (barva==1){
        document.getElementById("a"+r.toString()+"_"+s.toString()).style.backgroundColor="red";
        policka[r][s]=1;
      }else{
        document.getElementById("a"+r.toString()+"_"+s.toString()).style.backgroundColor="white";
        policka[r][s]=0;
      }
    }
    


  6. Potřebuji "znát" výchozí směr, proto si zadefinuji proměnné r0,s0;r1,s1
    var r0=100;
    var s0=110;
    var r1=101;
    var s1=110;
    


    tj. směr pohybu dr=r1-r0;ds=s1-s0

  7. Co znamená v mřížce zahnout doleva/doprava?
    Protože to není souhlasné tj. v prvním případě index odečítám v druhém přičítám, tak změníme "sloupcový směr" tj. ds=s0-s1

  8. Funkce krok() vstoupil jsem z políčka 0 na políčko 1. Podíváme se na jaké políčko jsme vstoupili - podle toho upravíme směr dalšího posunu. Když vstoupíme na obarvené políčko zatočíme doleva tj. "změníme" směr a políčko přebarvíme. Přeznačíme políčka r0,s0;r1,s1 (to co bylo 1 se stane 0 a podle směru posunu určíme novou polohu tj. r1,s1).
    function krok(){
      dr=r1-r0;
      ds=s0-s1;
      if (policka[r1][s1]==1){
        smer=-1;
        obarvi(r1,s1,0);
      }else{
        smer=1;
        obarvi(r1,s1,1);
      }
      r0=r1;
      s0=s1;
      r1=r1+smer*ds;
      s1=s1+smer*dr;
    }
    


  9. Změníme cyklus ve kterém jsme obarvovali úhlopříčku:
    for (i=0;i<200;i++){
     krok(); 
    }
    


Celý skript by měl vypadat takto:
<script language=JavaScript>
var policka=Array();
document.write("<table border=1>");
for (r=0;r<200;r++){
  document.write("<tr>");
  policka[r]=Array();
  for (s=0;s<200;s++){
    document.write("<td id=\"a"+r.toString()+"_"+s.toString()+"\"></td>");
    policka[r][s]=0;
  }
  document.write("</tr>");
}
document.write("</table>");

function obarvi(r,s,barva){
  if (barva==1){
    document.getElementById("a"+r.toString()+"_"+s.toString()).style.backgroundColor="red";
    policka[r][s]=1;
  }else{
    document.getElementById("a"+r.toString()+"_"+s.toString()).style.backgroundColor="white";
    policka[r][s]=0;
  }
}
var r0=100;
var s0=110;
var r1=101;
var s1=110
function krok(){
  dr=r1-r0;
  ds=s0-s1;
  if (policka[r1][s1]==1){
    smer=-1;
    obarvi(r1,s1,0);
  }else{
    smer=1;
    obarvi(r1,s1,1);
  }
  r0=r1;
  s0=s1;
  r1=r1+smer*ds;
  s1=s1+smer*dr;
}
for (i=0;i<15000;i++){
  krok();
}
</script>