Betekintés a sejtautomaták világába Processing segítségével - 2+1 dimenziós őrület

2 ^ 512 szabály

Térjünk vissza az 1-es szomszédsághoz, de most a dimenziók számát növeljük meg eggyel!

Ekkor egy sejtet 8 másik vesz körbe + maga a sejt: 9 elem

Két állapot sejtenként: 0 vagy 1

=> 2^9 = 512 esetre kell megadnunk, hogy a következő generációban a vizsgált sejt helyén 0-s vagy 1-es legyen, így esetenként megint 2-2 opciónk van.

(2^9)^2 = 2^512 =
134078079299425970995740249982058461274793
658205923933777235614437217640300735469768
018742981669034276900318581864860508537538
82811946569946433649006084096

2 Dimenzió, 1-es szomszédság

Mostmár végképp elszállt a szabályok száma, már mondhatni lehetetlen felfogni a lehetőségek terét.

A Processing képes 3D-s alakzatokat is megjeleníteni, azonban az egyszerűség kedvéért most kényelmesebb lesz mozgó képet készíteni a szimulációból.

Így 2 tér(x,y) + 1 idő(képkockák) dimenziót kapunk:


  import java.util.Random;
        
  final int cellCount = 400;
  int[][] cells;                 // a cellák 0 vagy 1 értékkel
  boolean[] RULE;
  float side;
      
  Random rand = new Random();
      
  void setup() {
    size(1000,1000, P2D); // Ablak mérete, legyen négyzet
          
    // Inicializásió
    cells = new int[cellCount][cellCount];
    side = 1.0 * width / cellCount;
    RULE = new boolean[512];
        
      
    generateNewRuleAndInitialise();
        
    // A képernyő kitöltése
    drawCells();
  }
      
  void generateNewRuleAndInitialise() {
    println("\nNew RULES");
    for (int i = 0; i < 512; i++) {
      RULE[i] = rand.nextBoolean();
      print(RULE[i] + " ");
    }
        
    RULE[511] = RULE[0]; // epilepszia gátló, kikommentelni csak saját felelősségre :)
        
    println();
        
    for (int i = 0; i < cellCount; i++) {
      for (int j = 0; j < cellCount; j++) {
        cells[i][j] = 0;
      }
    }
        
    cells[cellCount/2][cellCount/2] = 1; // Egy aktív cella középen
  }
      
      
  void iterate() { // A következő generáció, a szélek fixek, csupa nulláknak vesszük őket.
    int[][] cells2 = new int[cellCount][cellCount];
        
    for (int i = 1; i < cellCount-1; i++) {
      for (int j = 1; j < cellCount-1; j++) {
        
        // Szomszédsági szabály
        int value = 0;
        int multiplyer = 0;
        
        for (int y = -1; y < 2; y++) {
          for (int x = -1; x < 2; x++) {
            value += cells[i + y][j + x] << multiplyer;
            multiplyer++;
          }
        }
        
      
    // Értékadás a szábály alapján
        if (RULE[value])
          cells2[i][j] = 1;
        else
          cells2[i][j] = 0;
        
      }
    }
        
        
    for (int i = 0; i < cellCount; i++) {
      for (int j = 0; j < cellCount; j++) {
        cells[i][j] = cells2[i][j];
      }
    }
  
  }
      
      
  void drawCells() { // Felrajzol egy generációt
    noStroke();
    for (int i = 0; i < cellCount; i++) {
      for (int j = 0; j < cellCount; j++) {
        
          if (cells[i][j] == 1) fill(0);
          else fill(255);
          
          rect(j * side, side * i, side, side);
      }
    }
  }
      
  void draw() {
    iterate();
    drawCells();
    
    //delay(1);
  }
      
  void keyPressed() {
    if (key == 'r' || key == 'R') {
      generateNewRuleAndInitialise();
    }
  }
  

Az 512 esetre 512 boolean értékkel adok meg egy szabályt.

A szélső cellákat fixnek veszem a fenti kódban. Ennek némely szabály esetén a szélekről a középpont felé haladó zaj lesz az eredménye. Egy másik opció lenne, hogy összekötöm az ellentétes oldalon lévő cellákat egy tóruszt alkotva.

A program ténylegesen csak 2^511-en szabály tud megjeleníteni a következő sor és ok miatt:

RULE[511] = RULE[0];

A RULE[0] a csupa nullás állapotért, a RULE[511] pedig a csupes 1-es állapotért felelős, ha ez a kettő logikai érték nem egyezik, akkor minden iterációban gyorsan és zavaróan váltakozó fekete és fehér részek lesznek. Érthető okokból ezt lehet nem kéne engedélyezni.

Conway's Game of Life

A Conway's Game of Life egy nulla játékosos sejtautomata, amelyet John Conway matematikus alkotott meg 1970-ben. Egy végtelen rácson elhelyezkedő sejtekből áll, amelyek két állapotban lehetnek: élő vagy halott.

A sejtek sorsa egyszerű szabályok alapján dől el minden generációban:

  • Egy élő sejt életben marad, ha 2 vagy 3 élő szomszédja van.
  • Egy élő sejt elpusztul (magány vagy túlnépesedés miatt), ha kevesebb mint 2 vagy több mint 3 élő szomszédja van.
  • Egy halott sejt újjászületik, ha pontosan 3 élő szomszédja van.

A játék determinisztikus, de már egyszerű kezdeti állapotokból is bonyolult és kaotikus mintázatok fejlődhetnek ki, például oszcillátorok, állandó alakzatok és mozgó struktúrák (pl. "gliderek"). A Game of Life népszerű példája az önszerveződő rendszereknek, és fontos szerepet játszik a komplexitáselméletben és a mesterséges élet kutatásában.

Mit lehet így létrehozni?

Szimuláljunk benne egy számítógépet!