Rules

There are 256 rules in total, they all have small errors1. Some of the rules are shown here, others are insignificant.

rule_022.png

rule_022.png



rule_024.png

rule_024.png



rule_026.png

rule_026.png



rule_029.png

rule_029.png



rule_030.png

rule_030.png



rule_033.png

rule_033.png



rule_034.png

rule_034.png



rule_035.png

rule_035.png



rule_036.png

rule_036.png



rule_037.png

rule_037.png



rule_041.png

rule_041.png



rule_045.png

rule_045.png



rule_049.png

rule_049.png



rule_054.png

rule_054.png



rule_057.png

rule_057.png



rule_059.png

rule_059.png



rule_060.png

rule_060.png



rule_061.png

rule_061.png



rule_062.png

rule_062.png



rule_063.png

rule_063.png



rule_065.png

rule_065.png



rule_066.png

rule_066.png



rule_073.png

rule_073.png



rule_074.png

rule_074.png



rule_075.png

rule_075.png



rule_076.png

rule_076.png



rule_080.png

rule_080.png



rule_081.png

rule_081.png



rule_082.png

rule_082.png



rule_083.png

rule_083.png



rule_084.png

rule_084.png



rule_085.png

rule_085.png



rule_086.png

rule_086.png



rule_089.png

rule_089.png



rule_090.png

rule_090.png



rule_091.png

rule_091.png



rule_094.png

rule_094.png



rule_095.png

rule_095.png



rule_097.png

rule_097.png



rule_099.png

rule_099.png



rule_101.png

rule_101.png



rule_102.png

rule_102.png



rule_103.png

rule_103.png



rule_105.png

rule_105.png



rule_106.png

rule_106.png



rule_107.png

rule_107.png



rule_109.png

rule_109.png



rule_110.png

rule_110.png



rule_111.png

rule_111.png



rule_115.png

rule_115.png



rule_118.png

rule_118.png



rule_120.png

rule_120.png



rule_121.png

rule_121.png



rule_122.png

rule_122.png



rule_123.png

rule_123.png



rule_124.png

rule_124.png



rule_125.png

rule_125.png



rule_126.png

rule_126.png



rule_129.png

rule_129.png



rule_131.png

rule_131.png



rule_135.png

rule_135.png



rule_137.png

rule_137.png



rule_138.png

rule_138.png



rule_145.png

rule_145.png



rule_146.png

rule_146.png



rule_147.png

rule_147.png



rule_149.png

rule_149.png



rule_150.png

rule_150.png



rule_151.png

rule_151.png



rule_153.png

rule_153.png



rule_154.png

rule_154.png



rule_155.png

rule_155.png



rule_158.png

rule_158.png



rule_159.png

rule_159.png



rule_161.png

rule_161.png



rule_163.png

rule_163.png



rule_164.png

rule_164.png



rule_165.png

rule_165.png



rule_166.png

rule_166.png



rule_167.png

rule_167.png



rule_169.png

rule_169.png



rule_175.png

rule_175.png



rule_180.png

rule_180.png



rule_181.png

rule_181.png



rule_182.png

rule_182.png



rule_183.png

rule_183.png



rule_184.png

rule_184.png



rule_185.png

rule_185.png



rule_186.png

rule_186.png



rule_191.png

rule_191.png



rule_193.png

rule_193.png



rule_195.png

rule_195.png



rule_196.png

rule_196.png



rule_202.png

rule_202.png



rule_203.png

rule_203.png



rule_207.png

rule_207.png



rule_210.png

rule_210.png



rule_214.png

rule_214.png



rule_217.png

rule_217.png



rule_219.png

rule_219.png



rule_221.png

rule_221.png



rule_225.png

rule_225.png



rule_227.png

rule_227.png



rule_228.png

rule_228.png



rule_229.png

rule_229.png



rule_230.png

rule_230.png



rule_231.png

rule_231.png



rule_236.png

rule_236.png



rule_240.png

rule_240.png



rule_241.png

rule_241.png



rule_244.png

rule_244.png



Camera position

camera position

Code snapshots

  // Cellular automatons

  TBitArray = class
  private
    FData     : array of Byte;
    FBitCount : Integer;
  private
    function    GetBit( anIndex: Integer): Integer;
    procedure   SetBit( anIndex: Integer; aValue: Integer);
  public
    procedure   Clear;
  public
    property    Bit[ anIndex: Integer] : Integer read GetBit    write SetBit;
    property    BitCount               : Integer read FBitCount;
  end;

  PBitArray = ^ TBitArray;

  // Elementary Cellular Automaton, catalogued by FRule

  TElementaryCA = class
  private
    FBits1         : TBitArray;
    FBits2         : TBitArray;
    FBitsO         : PBitArray;
    FBitsN         : PBitArray;
    FRule          : Byte;
    FHasRandomSeed : Integer;
    FFaultRate     : TSignal;
  private
    function    GetBit( anIndex: Integer) : Integer;
    function    GetBitCount               : Integer;
    procedure   SwapON;
  public
    constructor Create;
    destructor  Destroy;                               override;
    procedure   Clear;
    procedure   Execute;
    procedure   SetRandomSeed( aBitCount: Integer);
  public
    property    Bit[ anIndex: Integer]: Integer read GetBit;
    property    BitCount              : Integer read GetBitCount;
    property    Rule                  : Byte    read FRule          write FRule;
    property    FaultRate             : TSignal read FFaultRate     write FFaultRate;
  end;


  // /////////////////////////////////////////////////////////////////////////////////////////
  // /////////////////////////////////////////////////////////////////////////////////////////


  function  MathIntMod( X, Y: Integer): Integer; inline;
  begin
    Result := ( X mod Y + Y) mod Y;
  end;


  function  MathIntDiv( X, Y: Integer): Integer; inline;
  begin
    Result := Floor( X / Y);
  end;


{ ========
  TBitArray = class
  private
    FData     : array of Byte;
    FBitCount : Integer;
  public
    property    Bit[ anIndex: Integer] : Integer read GetBit    write SetBit;
    property    BitCount               : Integer read FBitCount;
  private
}

    function    TBitArray.GetBit( anIndex: Integer): Integer;
    var
      i : Integer;
      b : Integer;
    begin
      i := MathIntDiv( anIndex, 8);

      if ( i >= 0) and ( anIndex < FBitCount)
      then begin
        b := MathIntMod( anIndex, 8);

        if ( FData[ i] and ( 1 shl b)) <> 0
        then Result := 1
        else Result := 0;
      end
      else Result := 0;
    end;


    procedure   TBitArray.SetBit( anIndex: Integer; aValue: Integer);
    var
      i : Integer;
      b : Integer;
    begin
      i := MathIntDiv( anIndex, 8);

      if i >= 0
      then begin
        b := MathIntMod( anIndex, 8);

        if i >= Length( FData)
        then SetLength( FData, i + 1);

        if anIndex >= FBitCount
        then FBitCount := anIndex + 1;

        if aValue <> 0
        then FData[ i] := FData[ i] or        ( 1 shl b)
        else FData[ i] := FData[ i] and ( not ( 1 shl b));
      end;
    end;


//  public

    procedure   TBitArray.Clear;
    begin
      FBitCount := 0;
      SetLength( FData, 0);;
    end;


{ ========
  TElementaryCA = class
  private
    FBits1         : TBitArray;
    FBits2         : TBitArray;
    FBitsO         : PBitArray;
    FBitsN         : PBitArray;
    FRule          : Byte;
    FHasRandomSeed : Integer;
    FFaultRate     : TSignal;
  public
    property    Bit[ anIndex: Integer]: Integer read GetBit;
    property    BitCount              : Integer read GetBitCount;
    property    Rule                  : Byte    read FRule          write FRule;
    property    FaultRate             : TSignal read FFaultRate     write FFaultRate;
  private
}

    function    TElementaryCA.GetBit( anIndex: Integer): Integer;
    begin
      if Assigned( FBitsO)
      then Result := FBitsO^.Bit[ anIndex]
      else Result := 0;
    end;


    function    TElementaryCA.GetBitCount: Integer;
    begin
      if Assigned( FBitsO)
      then Result := FBitsO^.BitCount
      else Result := 0;
    end;


    procedure   TElementaryCA.SwapON;
    var
      aTmp: PBitArray;
    begin
      aTmp   := FBitsO;
      FBitsO := FBitsN;
      FBitsN := aTmp;
    end;


//  public

    constructor TElementaryCA.Create;
    var
      i : Integer;
    begin
      inherited Create;
      FRule  := 0;
      FBits1 := TBitArray.Create;
      FBits2 := TBitArray.Create;
      FBitsO := @ FBits1;
      FBitsN := @ FBits2;

      if FHasRandomSeed > 0
      then begin
        for i := 0 to FHasRandomSeed - 1
        do FBits1.Bit[ i] := Random( 2);
      end
      else FBits1.Bit[ 0] := 1;
    end;


    destructor  TElementaryCA.Destroy; // override;
    begin
      FBitsO := nil;
      FBitsN := nil;
      FBits1.DisposeOf;
      FBits2.DisposeOf;
      inherited;
    end;


    procedure   TElementaryCA.Clear;
    var
      i : Integer;
    begin
      FBits1.Clear;
      FBits2.Clear;
      FBitsO := @ FBits1;
      FBitsN := @ FBits2;

      if FHasRandomSeed > 0
      then begin
        for i := 0 to FHasRandomSeed - 1
        do FBits1.Bit[ i] := Random( 2);
      end
      else FBits1.Bit[ 0] := 1;
    end;


    procedure   TElementaryCA.Execute;
    var
      P : Byte;
      N : Byte;
      i : Integer;
      F : Integer;
    begin
      if Assigned( FBitsN)
      then begin
        for i := 0 to BitCount + 1
        do begin
          N := Bit[ i] + ( Bit[ i - 1] shl 1) + ( Bit[ i - 2] shl 2);
          P := 1 shl N;

          if Random < FFaultRate
          then F := 1
          else F := 0;

          if ( FRule and P) <> 0
          then FBitsN^.Bit[ i] := 1 xor F
          else FBitsN^.Bit[ i] := 0 xor F;
        end;

        SwapON;
      end;
    end;


    procedure   TElementaryCA.SetRandomSeed( aBitCount: Integer);
    begin
      FHasRandomSeed := aBitCount;
      Clear;
    end;


  // /////////////////////////////////////////////////////////////////////////////////////////
  // /////////////////////////////////////////////////////////////////////////////////////////


// User area

const

  BACK_COLOR = clSilver;
  FORE_COLOR = clNavy;


//  private

    procedure   TFormAutomaton.SetRule( aValue: Integer);
    begin
      if ( aValue >= 0) and ( aValue <= 255) and ( aValue <> FRule)
      then begin
        FRule         := aValue;
        EditRule.Text := IntToStr( FRule);
      end;
    end;


//  private

    procedure   TFormAutomaton.Clear;
    begin
      FLine := 0;
   // FAutomaton.SetRandomSeed( FBitmap.Width);
      FAutomaton.Clear;
      FAutomaton.Rule      := Rule;                         
      FAutomaton.FaultRate := 0.001;                        // ← [Note 1] error rate of 1 ‰
      FBitmap.Canvas.Pen  .Color := BACK_COLOR;
      FBitmap.Canvas.Brush.Color := BACK_COLOR;
      FBitmap.Canvas.Rectangle( 0, 0, FBitmap.Width, FBitmap.Height);
      PaintLine;
    end;


    procedure   TFormAutomaton.Run;
    var
      i : Integer;
    begin
      Clear;

      for i := 0 to FBitmap.Height - 1
      do Step;
    end;


    procedure   TFormAutomaton.Step;
    begin
      Inc( FLine);
      FAutomaton.Execute;
      PaintLine;
    end;


    procedure   TFormAutomaton.PaintLine;
    const
      Colors : array[ 0 .. 1] of TColor = ( BACK_COLOR, FORE_COLOR);
    var
      Mid : Integer;
      i   : Integer;
    begin
      Mid := FBitmap.Width div 2;

      for i := 0 to FAutomaton.BitCount - 1
      do FBitmap.Canvas.Pixels[ i - FLine + Mid, FLine] := Colors[ FAutomaton.Bit[ i]];

      PaintBox.Invalidate;
    end;


    procedure   TFormAutomaton.DoPaint;
    begin
      PaintBox.Canvas.Draw( 0, 0, FBitmap);
    end;

    
~ fin ~