Uses a grid of cells and looks at each cell and the state (ex: on/off) of each of the surrounding neighbor cells and changes the state of the current cell according to a set of rules based on the neighbor cells’ states.

References

Implementations

  • 1
    
    # TODO: Implement in Python
    
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    
    const gridSize = 10;
    const generations = 4;
    const fillChance = 0.55;
    
    const G = [];
    const nextG = [];
    for (let i = 0; i < gridSize; i++) {
      G[i] = [];
      nextG[i] = [];
      for (let j = 0; j < gridSize; j++) {
        if (Math.random() < fillChance || i === 0 || j === 0 || i === gridSize - 1 || j === gridSize - 1) {
          G[i][j] = '#';
        } else {
          G[i][j] = '.';
        }
        nextG[i][j] = '#';
      }
    }
    
    function CellularAutomata(fillShape, emptyShape) {
      const nextGrid = [];
    
      for (let i = 0; i < G.length; i++) {
        nextGrid[i] = [];
        for (let j = 0; j < G[i].length; j++) {
          let adjCount = 0;
          let twoAwayCount = 0;
          // look at the states of the neighboring cells
          for (let x = -2; x <= 2; x++) {
            for (let y = -2; y <= 2; y++) {
              if ((i + x >= 0 && i + x < G.length) && (j + y >= 0 && j + y < G[i].length)) {
                if (!(x !== 0 && y !== 0) && G[i + x][j + y] === emptyShape) {
                  if (x === -2 || x === 2 || y === -2 || y === 2) {
                    twoAwayCount++;
                  } else {
                    adjCount++;
                  }
                }
              }
            }
          }
          // change the current cell's state according to these rules
          if ((adjCount >= 5)) {
            nextGrid[i][j] = fillShape;
          } else if (adjCount <= 1) {
            if (twoAwayCount < 3) {
              nextGrid[i][j] = fillShape;
            } else {
              nextGrid[i][j] = emptyShape;
            }
          } else {
            nextGrid[i][j] = emptyShape;
          }
        }
      }
    
      for (let i = 0; i < nextGrid.length; i++) {
        for (let j = 0; j < nextGrid[i].length; j++) {
          
          G[i][j] = nextGrid[i][j];
          
        }
      }
    }
    
    for (let iter = 0; iter < generations; iter++) {
      CellularAutomata('#', '.');
    }