• fullscreen
  • Game.pde
  • LifeAttractor.pde
  • Printing.pde
  • static final int side = 8;
    static final char[][] lookup = makeLookup();
    
    // creates a lookup table mapping rows/columns to their sums
    static char[][] makeLookup() {
      char[][] lookup = new char[(int) pow(2, side)][side];
      for(int i = 0; i < lookup.length; i++) {
        char[] bits = new char[side];
        for(int b = 0; b < side; b++)
          bits[b] = (char) ((i & (1 << b)) != 0 ? 1 : 0);
        char[] sum = new char[side];
        for(int b = 0; b < side; b++) {
          sum[b] += bits[b == 0 ? side - 1 : b - 1]; // left
          sum[b] += bits[b]; // center
          sum[b] += bits[b == side - 1 ? 0 : b + 1]; // right
        }
        lookup[i] = sum;
      }
      return lookup;
    }
    
    class Game {
      // duplicate data
      boolean[][] board = new boolean[side][side];
       
      Game() {
        for(int x = 0; x < side; x++)
          for(int y = 0; y < side; y++)
            board[x][y] = random(1) > .5;
      }
      
      Game(long game) {
        for(int x = 0; x < side; x++)
          for(int y = 0; y < side; y++)
            board[x][y] = (game & ((long) 1 << (y * side + x))) != 0;
      }
      
      int totalSum;
      void step() {
        // make rows for lookup
        char[] rows = new char[side];
        for(int x = 0; x < side; x++)
          for(int y = 0; y < side; y++)
            if(board[x][y])
              rows[y] |= 1 << x;
          
        // lookup sums for rows
        char[][] rowSums = new char[side][side];
        for(int i = 0; i < side; i++)
          rowSums[i] = lookup[rows[i]];
            
        // recalculate life
        char curSum;
        boolean cur;
        totalSum = 0;
        for(int x = 0; x < side; x++) {
          for(int y = 0; y < side; y++) {
            curSum = rowSums[y == 0 ? side - 1 : y - 1][x];
            curSum += rowSums[y][x];
            curSum += rowSums[y == side - 1 ? 0 : y + 1][x];
            cur = board[x][y];
            if(cur) {
              // self is counted, so 3/4 instead of 2/3
              if(curSum < 3 || curSum > 4)
                board[x][y] = false;
            } else {
              if(curSum == 3)
                board[x][y] = true;
            }
            totalSum += curSum; // non-essential
          }
        }
      }
      
      int size() {
        int size = 0;
        for(int x = 0; x < side; x++)
          for(int y = 0; y < side; y++)
            if(board[x][y])
              size++;
        return size;
      }
       
      void draw(float rectSize) {
        for(int x = 0; x < side; x++)
          for(int y = 0; y < side; y++)
            if(board[x][y])
              rect(rectSize * x, rectSize * y, rectSize, rectSize);
      }
    }
    
    int[] samplePoints = {3, 3, 3};
    
    int zoom = 4;
    float offsetStep;
    
    int zoomLevel, systemZoom;
    
    void setup() {
      size(640, 360, P3D);
      frameRate(1);
      colorMode(RGB, 256);
    }
    
    void draw() {
      background(0);
      noStroke();
      
      offsetStep = random(8, 128);
      zoomLevel = (int) random(10, 50);
      systemZoom = 1 << zoomLevel;
      for(int i = 0; i < 3; i++)
        samplePoints[i] = (int) random(1, 5);
      println("zoomLevel: " + zoomLevel);
      println(samplePoints);
    
      int xOffset = 1;
      int yOffset = 1;
      for(int x = 0; x < width / zoom; x++) {
        for(int y = 0; y < height / zoom; y++) {
          color curColor = getPoint(xOffset * systemZoom, yOffset * systemZoom);
          fill(curColor);
          rect(x * zoom, y * zoom, zoom, zoom);
          float offAngle = brightness(curColor);
          xOffset += cos(offAngle) * offsetStep;
          yOffset += sin(offAngle) * offsetStep;
        }
      }
    }
    
    color getPoint(int x, int y) {
      long interlaced = interlace(x, y);
      Game game = new Game(interlaced);
      float[] rgb = new float[3];
      for(int i = 0; i < 3; i++) {
        for(int step = 0; step < samplePoints[i]; step++) {
          game.step();
          //rgb[i] += game.size();
          rgb[i] += game.totalSum;
        }
        rgb[i] /= samplePoints[i];
      }
      return color(rgb[0], rgb[1], rgb[2]); 
    }
    
    long interlace(int x, int y) {
      long interlaced = 0;
      for(int i = 0; i < 32; i++) {
        int curPosition = i * 2;
        if(isSet(x, i))
          interlaced |= 1 << curPosition;
        if(isSet(y, i))
          interlaced |= 1 << (curPosition + 1);
      }
      return interlaced;
    }
    
    boolean isSet(int x, int position) {
      return (x & (1 << position)) != 0;
    }
    
    void keyPressed() {
      if(key == 's') {
        saveFrame("add attractor density " + samplePoints[0] + " " + samplePoints[1] + " " + samplePoints[2] + " zoom " + zoomLevel + ".png");
      }
    }
    
    static public void println(char[] chars) {
      println(join(strings(chars), ' '));
    }
    
    static public void println(boolean[] bits) {
      println(join(strings(bits), ' '));
    }
    
    static public String[] strings(char[] chars) {
      String[] strings = new String[chars.length];
      for(int i = 0; i < chars.length; i++)
        strings[i] = ((int) chars[i]) + "";
      return strings;
    }
    
    static public String[] strings(boolean[] bits) {
      String[] strings = new String[bits.length];
      for(int i = 0; i < bits.length; i++)
        strings[i] = bits[i] ? "1" : "0" + "";
      return strings;
    }
    
    static public String binary(long x) {
      String out = "";
      for(int i = 63; i >= 0; i--)
        out += ((x & ((long) 1 << i)) == 0) ? "0" : "1";
      return out;
    }
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Kyle McDonald

    Life Attractor

    Add to Faves Me Likey@! 10
    You must login/register to add this sketch to your favorites.

    Visualization of structure within the game of Life. The first top left point is mapped to the a game of life (an 8x8 = 64-dimension binary space) and run for a while. A color is returned representing its life cycle (red intensity for the amount of cells early in the game, green mid game, blue end game). The color is used to determine which game to pick for the next cell (top to bottom, left to right). Varying zooms are chosen.

    You need to login/register to comment.