CS010 Introduction to Computer Science I
Term Project
Deliverable One

Celluar Automata:
Building Blocks
(last updated 3/25/2007)

Update:

For the first deliverable uf our project, you will become familiar with cellular automata (CA) and implement the building blocks for future deliverables.  You can find many others, but here is a description of cellular automata.  The two most important ideas for CA are the notion of a cell and its state.  Just as our bodies are made of cells, a cellular automaton is made up of a configuration of cells.  Each cell has a state; for our initial purposes, a state is either living or dead, which we will represent as 1 or 0 respectively.

For our first deliverable, we will only consider one-dimensional CA.    That is, the configuration of cells is a single strand of cells, each cell (except the first and last) having a left and right neighbor.  If we think of a cellular automata as an organism, then from moment to moment its cells are changing state -- that is, living, dieing, and being reborn.  A cell's state will change according to a rule that considers the cell's current state and the state of its neighbors.  CA operating under different rules will exhibit different behaviors.

Once you understand the basics of cellular automata, we need come up with data definitions so we can implement them in Scheme.  We've already decided to represent a state as either 0 or 1.  But we also need a way to represent organisms and rules.  Since we're starting with one-dimensional CA, let's represent a given organism as a list of cells.  Next, we need to represent rules; that is, a way to determine the new state of a cell based on the pattern of its neighbors.  For each situation (i.e., combination of a cell's current state and the state of its left and right neighbors), we need to be able to specify the next state of the cell.  In our case, there are 8 possible situations -- 2 possible current states for the cell, 2 possible states for the left and 2 for the right.  By representing numbers in a binary format, we can capture a rule very compactly as a vector of 8 states (0 or 1).  A binary representation is like our normal base-10 representation, except instead of 1's, 10's, 100's, etc., it has places valued by powers of 2 -- 1's, 2's, 4's, 8's, etc.  Of course, the only digits are 0 and 1.  But when we count the from 0 to 7, we see every possible combination of three states.

 numeric value of state pattern as binary code state pattern (binary code) new state of center cell 0 000 0 1 001 1 2 010 0 3 011 1 4 100 1 5 101 0 6 110 1 7 111 0

Thus, we use the situation of left neighbor, given cell, right neighbor, as a numeric index into a vector.  Thus, a vector of 8 elements can represent a rule.  The table above specifies one particular rule.  Loosely, this rule says a cell (the center cell in a pattern) lives if it has exactly one neighbor, dies from crowding with two neighbors, and dies from loneliness with no neighbors.  This is just one rule; the astute reader will note there are 256 possible rules.  The content of an indexed vector-element will be the new value of the cell centered in the corresponding pattern.  For the example above, we would have the rule: (vector 0 1 0 1 1 0 1 0); and if we have a situation where a cell is dead and with both neighbors alive (101 -- binary for the number 5), then the cell's new value would be found in (vector-ref this-rule 5), or 0 in the case of our example (if we refer to our rule as "this-rule".)  Note: at either end of an organism, the cells do not have neighbors on one side or the other.  In those cases, you will have to write your code to provide a virtual neighbor with a 0 value.

With representations of states, rules and organisms in place, we want to develop a program that will consume a given organism and a rule, and will return a new organism that reflects the changes to states in the given organism according to the given rule.

Finally, we would like a way to visualize the changes in an organism over time.  We can do this by rendering a snapshot of the organism as a single horizontal line across the canvas.  The line will consist of dots wherever corresponding cells are alive.  We will render time as successive lines down the canvas, the top line will display the initial state, the second line its successor, and so on.

Putting this all together, I want you to write a function, simulate-life, that consumes three arguments: a rule (vectorof state), the number of generations to render or simulate (number), and an organism (listof states).  When I call this function with my arguments, I should see a canvas appear (of the appropriate dimensions based on the length of the organism and the number of generations) and then a picture develop that shows the evolution of the organism over time.
`;; a state is either 1 or 0;; an organism is a (listof state);; a rule is a (vectorof state);; simulate-life: rule number organism -> true`
I hope you will have fun with this project.