There are 256 rules in total, they all have small errors1. Some of the rules are shown here, others are insignificant.
![]() rule_026.png |
![]() rule_236.png |
![]() rule_227.png |
![]() rule_060.png |
![]() rule_186.png |
![]() rule_122.png |
![]() rule_059.png |
![]() rule_103.png |
![]() rule_219.png |
![]() rule_231.png |
![]() rule_107.png |
![]() rule_126.png |
![]() rule_065.png |
![]() rule_244.png |
![]() rule_159.png |
![]() rule_180.png |
![]() rule_166.png |
![]() rule_082.png |
![]() rule_138.png |
![]() rule_229.png |
![]() rule_099.png |
![]() rule_175.png |
![]() rule_167.png |
![]() rule_210.png |
![]() rule_145.png |
![]() rule_115.png |
![]() rule_193.png |
![]() rule_049.png |
![]() rule_150.png |
![]() rule_111.png |
![]() rule_076.png |
![]() rule_073.png |
![]() rule_155.png |
![]() rule_129.png |
![]() rule_169.png |
![]() rule_191.png |
![]() rule_121.png |
![]() rule_033.png |
![]() rule_110.png |
![]() rule_151.png |
![]() rule_202.png |
![]() rule_240.png |
![]() rule_097.png |
![]() rule_066.png |
![]() rule_086.png |
![]() rule_131.png |
![]() rule_135.png |
![]() rule_125.png |
![]() rule_037.png |
![]() rule_034.png |
![]() rule_221.png |
![]() rule_074.png |
![]() rule_203.png |
![]() rule_075.png |
![]() rule_158.png |
![]() rule_161.png |
![]() rule_054.png |
![]() rule_181.png |
![]() rule_153.png |
![]() rule_124.png |
![]() rule_214.png |
![]() rule_080.png |
![]() rule_024.png |
![]() rule_182.png |
![]() rule_165.png |
![]() rule_225.png |
![]() rule_241.png |
![]() rule_063.png |
![]() rule_029.png |
![]() rule_045.png |
![]() rule_084.png |
![]() rule_091.png |
![]() rule_089.png |
![]() rule_057.png |
![]() rule_228.png |
![]() rule_184.png |
![]() rule_036.png |
![]() rule_123.png |
![]() rule_095.png |
![]() rule_146.png |
![]() rule_094.png |
![]() rule_101.png |
![]() rule_109.png |
![]() rule_090.png |
![]() rule_120.png |
![]() rule_185.png |
![]() rule_062.png |
![]() rule_035.png |
![]() rule_163.png |
![]() rule_106.png |
![]() rule_183.png |
![]() rule_102.png |
![]() rule_196.png |
![]() rule_022.png |
![]() rule_041.png |
![]() rule_085.png |
![]() rule_105.png |
![]() rule_217.png |
![]() rule_149.png |
![]() rule_083.png |
![]() rule_137.png |
![]() rule_081.png |
![]() rule_154.png |
![]() rule_230.png |
![]() rule_147.png |
![]() rule_195.png |
![]() rule_061.png |
![]() rule_118.png |
![]() rule_207.png |
![]() rule_030.png |
![]() rule_164.png |
// 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;