I was eager to write my own program for generating a cellular automaton by the time that I learned imperative programming, having enthusiastically read Stephen Wolfram's A New Kind Of Science in High School. In the middle of the semester, and before I had even learned the basics of classes and objects within the COP 2931 Programming I course using C++, I initiated my own personal project to create that program. Just as the Hello World program is the archetypical first program for every programmer, the Rule 30 cellular automata was the obvious choice when deciding which rule set to implement.
For the sake of preventing overflow within the Xcode Debug area when outputting many iterations, I fixed the width of the resulting 'ribbon' to 25 characters and set the loop calculating the next line to retrieve cell values from the given line as if the line was unbounded (the value at index 0 was retrieved following the value at index 24 of the same line). This modification prevented the occurrence of 'border interactions' which would have almost assuredly contaminated the resulting data. However, in making this modification the automaton was prevented from experiencing the unrestricted growth that would have resulted in the usual Rule 30 output. The new consequence of this configuration is that the once predictable edges of expansion now collide with each other resulting in an inevitable end in growth, but a continuation in automaton development with each iteration.
Input a string of 1s and 0s, 25 digits long, to construct first line. 1 for black, 0 white. 0000000000001000000000000 Input how many iterations are sought: 50 O OOO OO O OO OOOO OO O O OO OOOO OOO OO O O O OO OOOO OOOOOO OO O OOO O OO OOOO OO O OOO OO O O OOOO OO O OO OOOO OO O O OOOO OO O OOO OO OO O O OOOO OO OOO OOO OO OO OOO O OOO O OOO O O O OO O O OOOOO OOO OOOOOOO OOOO O OOO O OOO OO OO O O O OO O OO OOO OOO O OO OO OOOOOO O O O O OOO O OOOO OOO OO O O OOOO OO O O OO OOOO O OO O OOO OOO O O OO O OOOO O OOO OO O OOOO O OOO OO O OOOO O OO O O O O OOOOO O OO O OOOO O O O O OO O OOOO OO O OO OO O OOOO O O O O OOO OOOO O OOOO OOO O O OOO O OO O OO O OOOO O OO O OO O O OO O OOO O OOOO OO O O OO OO OOOO O OO OOOO O O OO O OOO O O OOO O O O OOOOO OOOOOO OO O O O O O O O O OO O O OO OO OO OO O O O O O OOO O O OO O OOOO O O O OO OOOO OOO O O O OOOO OO O OO OO O O O O O OOO OO OOO O OO OO O OOOO O O OOO O O OO O O OOOOOOOO OOOOO OO OO O O OO OO O OO OO O O OO OOOOOO O OO O OO OO O OO OO OOO O O O OOOO OO O O O O
// main.cpp
// CA Ribbon
//
// Created by Julien Kuzniarek on 10/21/13.
//
// Elementary cellular automaton, ribbon, unbounded, rule 30
#include <cstdlib>
#include <iostream>
#include <string>
// black = true = 1;
// white = false = 0;
using namespace std;
bool rule30(bool, bool, bool );
bool setcell();
void printcell(bool);
int main()
{
#define linelength 25
string firstline = "";
bool repcheck[linelength] = {0};
unsigned long ribbonwidth = 0;
int ribbonlength = 0;
//input starting line
cout << "Input a string of 1s and 0s, " << linelength << " digits long,";
cout << " to construct first line." << endl << "1 for black, 0 white. " << endl;
cin >> firstline;
ribbonwidth = firstline.length();
bool line [linelength] = {0};
bool nextline [linelength] = {0};
for (int count = 0; count < ribbonwidth; count++)
{
if (firstline[count] == '1')
{
line[count] = true;
}
if (firstline[count] == '0')
{
line[count] = false;
}
}
//main loop
cout << endl << "Input how many iterations are sought: ";
cin >> ribbonlength;
cout << endl;
for (int count1 = 0; count1 < ribbonlength; count1++)
{
//calculate next line from line
nextline[0] = rule30(line[ribbonwidth-1], line[0], line[1]);
for(int num = 1; num < ribbonwidth; num++)
{
nextline[num] = rule30(line[num-1], line[num], line[num+1]);
}
nextline[ribbonwidth-1] = rule30(line[ribbonwidth-2], line[ribbonwidth-1], line[0]);
//print cells then update line with values from next line
for (int count2 = 0; count2 < ribbonwidth; count2++)
{
printcell(line[count2]);
line[count2] = nextline[count2];
}
cout << endl;
for (int count = 0; (count < linelength); count++)
{
if (line[count] == repcheck[count] and count == linelength)
{
ribbonlength = count1;
}
else
{
count = linelength;
}
}
}
}
void printcell(bool cell)
{
if (cell == true)
{
cout << "O";
}
if (cell == false)
{
cout << " ";
}
}
//define rule30 function
bool rule30( bool cellL, bool cellC, bool cellR )
{
bool returnvalue = true;
//true = black
//false = white
if (cellL == true and cellC == true and cellR == true)
{
returnvalue = false;
}
if (cellL == true and cellC == true and cellR == false)
{
returnvalue = false;
}
if (cellL == true and cellC == false and cellR == true)
{
returnvalue = false;
}
if (cellL == true and cellC == false and cellR == false)
{
returnvalue = true;
}
if (cellL == false and cellC == true and cellR == true)
{
returnvalue = true;
}
if (cellL == false and cellC == true and cellR == false)
{
returnvalue = true;
}
if (cellL == false and cellC == false and cellR == true)
{
returnvalue = true;
}
if (cellL == false and cellC == false and cellR == false)
{
returnvalue = false;
}
return returnvalue;
}