Bitte warten

JavaScript: Conway′s Game of Life

Conway′s Game of Life (dt. Conways Spiel des Lebens) ist eine Visualisierung der Entwicklung von Strukturen in einer zweidimensionalen „Welt“ in der Zeit, ausgehend von einer zufälligen oder vorgegebenen Anfangsverteilung der elementaren Bestandteile dieser Strukturen, den „Zellen“. Dabei lässt sich die Bildung dieser Strukturen beobachten, die primitive Eigenschaften entwickeln. Sie können einen statischen oder oszillierenden Zustand annehmen, sie können ortsgebunden verharren oder sich fortbewegen und sie können ihrerseits neue Strukturen hervorbringen. Bei entsprechender Ausgangskonfiguration lassen sich sogar logische Schaltkreise und somit ein Computer simulieren, der theoretisch zu künstlicher Intelligenz fähig ist.

Dabei gelten lediglich drei Regeln:
• Eine tote Zelle mit genau drei Nachbarn erwacht zum Leben.
• Eine lebende Zelle mit zwei oder drei Nachbarn bleibt am Leben.
• Eine lebende Zelle mit weniger als zwei oder mehr als drei Nachbarn stirbt.


Hier der Code:

Code kopieren
    <div class='center'><canvas id='world'></canvas><br><button class='bigbutton' onclick='startAnim();'>Start</button></div>
    <script>
      // init
      ws = 600;  // world size in pixels
      n = 150;  // number of rows and columns
      u = ws / n;  // cell size
      p = 20;  // initial percentage of living cells
      
      // populate array
      g = 1;  // generation counter
      pad = 3;  // invisible peripheral rows/columns
      nn = n + 2 * pad;
      current = Array.from({length:nn}, () => Array.from({length:nn}, () => 0));
      c = 0;
      while (c < n * n / 100 * p) {
        x = Math.floor(Math.random() * n);
        y = Math.floor(Math.random() * n);
        if (!current[x][y]) { current[x + pad][y + pad] = 1; c++; }
      }
      next = structuredClone(current);
      
      world = document.getElementById('world');
      world.width  = ws;
      world.height = ws;
      
      function updateWorld() {
        cx = world.getContext('2d');
        cx.clearRect(0, 0, ws, ws);
        
        for (y = 1; y < nn - 1; y++) {
          for (x = 1; x < nn - 1; x++) {
            // draw living cell
            if (next[x][y]) {
              cx.fillStyle = 'hsl(45,85%,50%)';
              cx.beginPath();
              xpos = u / 2 + u * (x - pad);
              ypos = u / 2 + u * (y - pad);
              r = u / 2;
              cx.arc(xpos,ypos, r, 0,2 * Math.PI);
              cx.fill();
            }
            
            // count neighbors
            a = current[x - 1][y - 1] + current[x][y - 1] + current[x + 1][y - 1] +
                current[x - 1][y]     +                     current[x + 1][y]     +
                current[x - 1][y + 1] + current[x][y + 1] + current[x + 1][y + 1];
            
            // live or die
            if (!current[x][y]) {
              if (a == 3)         next[x][y] = 1;
            } else {
              if (a < 2 || a > 3) next[x][y] = 0;
            }
          }
        }
        gen = "Generation " + g;
        cx.fillStyle = 'white';
        cx.font = 'bold 20px DejaVu Sans Mono,monospace';
        cx.fillText(gen, 10,ws - 10);
        
        current = structuredClone(next);
        g++;
      }
      updateWorld();
      function startAnim() {
        document.getElementsByTagName("button")[0].outerHTML = "<button class='bigbutton' onclick='window.location.reload();'>zurück zum Anfang</button>";
        setInterval(updateWorld, 200);
      }
    </script>