CS010
Introduction to Computer Science I

Term Project

Deliverable One

Celluar Automata:

Building Blocks

(last updated 3/25/2007)

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 0I hope you will have fun with this project.

;; an organism is a (listof state)

;; a rule is a (vectorof state)

;; simulate-life: rule number organism -> true