CS 201 - Computer Science I - Fall 2003
Project 4


Loyola College > Department of Computer Science > CS 201 > Projects > Project 4

Due

Wednesday, December 10th at 11:59pm. Projects will be accepted one day late without penalty. Projects two days late will be assessed a 40% penalty. Each additional day late brings an additional 20% penalty. Projects will not be accepted more than four days late.

Objectives

Reading

David Eck of Hobart and William Smith Colleges has a fine Introduction to One-Dimensional Cellular Automata.

Introduction

We will be working with two-state one-dimensional cellular automata for this project. A one-dimensional automaton is a row of cells. In a two-state automaton each cell can be filled or unfilled (or equivalently, blue or black or perhaps 1 or 0).

Each automaton produces a new one when a set of rules is applied to it. The rules determine which cells in the new automaton are filled. The rules are based on the state of the cell and its two neighbors in the original automaton. For example, a rule might say that if a cell and its right neighbor are filled in the original automaton but its left neighbor is not filled, then in the new automaton the cell will be filled.

The applet below allows you to select the state of the original automaton and the rules that will be applied to it. It will show you the result of applying those rules to the original automaton, to the automaton that results from that first step, to the automaton that results from that second step, and so on.


Configure the initial state of the automaton by clicking on the first row.
Select the rules that determine when a cell is filled by clicking the boxes on the right.
Click "Run" to display the results.
Inferior browsers may have trouble with Java applets. If you have an inferior browser, try Mozilla, Opera, or Netscape.

As an example, select the first, fourth, and fifth rules along the right side of the applet. Fill the second, third, fifth, seventh, and tenth cells in the original automaton by clicking the boxes in the top row. Click "Run" to see the results. The second and eighth cells in the second row should now be filled.

The first cell in the second row is not filled because we did not select the rule that would have filled it. In the original automaton the first cell was empty, its left neighbor was empty (we are treating all cells that are off the edges of the display as empty), and its right neighbor was filled. The rule that would have applied is the second rule. If you check the box for the second rule and click "Run" again, the first cell in the second row will be filled (try it and then put things back the way they were).

The second cell in the second row is filled because we did select the rule that says it should be filled. That rule is the one that says that if a cell is filled in the original automaton and its right neighbor is filled but its left neighbor is not, then the cell is filled in the resulting automaton (this rule is the fourth one in the list).

All the other cells in the second row are filled or are left unfilled according to the rules we selected in the same manner: first, we examine the cell and its two neighbors in the original automaton; if the corresponding rule was selected then the cell is filled. The process is repeated for the third row, but for that row we examine the cells in the second row. For the fourth row we examine the cells in the third row, and so on.

Assignment

There will be three classes that make up this program. One, Rule will model the individual rules that specify when cells in the next generation are turned on. The second, RuleSet is a set of rules (like Dictionary is a set of Strings). The third, Automaton1D models the one-dimensional automata.

Rule should have the following.

The Rule class should work with the following test driver.

    public static void main(String[] args)
    {
	Rule r1 = new Rule("000");
	Rule r2 = new Rule("101");
	Rule r3 = new Rule("110");
	Rule r4 = new Rule("000");

	System.out.println(r1.getCell(-1)); // displays 0
	System.out.println(r2.getCell(-1)); // 1
	System.out.println(r3.getCell(1)); // 0

	System.out.println(r1); // 000
	System.out.println(r3); // 110

	System.out.println(r1.equals(r2)); // false
	System.out.println(r4.equals(r1)); // true
    }

RuleSet should contain the following.

RuleSet should work with the following test driver.
    public static void main(String[] args)
    {
	RuleSet s = new RuleSet();

	Rule r1 = new Rule("011");
	Rule r2 = new Rule("101");
	Rule r3 = new Rule("110");

	System.out.println(s.contains(r1)); // should display false
	
	s.add(r1);
	s.add(r2);
	s.add(r1);

	System.out.println(s.size()); // 2

	System.out.println(s.contains(r1)); // true
	System.out.println(s.contains(r2)); // true
	System.out.println(s.contains(r3)); // false
    }
Automaton1D should have the following.

Automaton1D should work with the following test driver.

    public static void main(String[] args)
    {
	RuleSet s = new RuleSet();

	Rule r1 = new Rule("000");
	Rule r2 = new Rule("110");
	Rule r3 = new Rule("001");

	s.add(r1);
	s.add(r2);
	s.add(r3);

	Automaton1D a = new Automaton1D(10);

	System.out.println(a); // should display ..........
	System.out.println(a.getCell(3)); // 0

	a.setCell(2);
	a.setCell(4);
	a.setCell(7);
	a.setCell(8);

	System.out.println(a); // ..*.*..**.

	System.out.println(a.hasMatch(s, 0)); // true (the rule 000 matches)
	System.out.println(a.hasMatch(s, 1)); // true (001)
	System.out.println(a.hasMatch(s, 2)); // false

	System.out.println(a.applyRules(s)); // **....*.*.

	// should display
	// 
	// ..*.*..**.
	// **....*.*.
	// .*.***....
	// *....*.***

	int[][] grid = a.runGenerations(s, 3);

	for (int r = 0; r < grid.length; r++)
	    {
		for (int c = 0; c < grid[r].length; c++)
		    if (grid[r][c] == 0)
			System.out.print('.');
		    else
			System.out.print('*');
		System.out.println();
	    }
    }

Advice

If you assign the character '0' to an int variable, the variable gets the value 48 because that is the position of '0' in the ordering of characters. To convert digit characters to their proper numeric values you can use the Character.getNumericValue method.

If you are stuck on Rule, start with RuleSet. RuleSet will be very much like Dictionary from lab 7. You do, however, need a working Rule class in order to test RuleSet. If you do not have one you can use my Rule.class which is the compiled version of my Rule.java. In order to use this, first move your own Rule.java (if you have one) to a different directory. Then save Rule.class to the directory where you are saving the rest of your Project 4 source code. Then, when you try to compile RuleSet and run RuleSetTest the compiler will automatically use Rule.class.

If you can't figure out how to avoid an ArrayIndexOutOfBoundsException when hasMatch is called on the left or right end of an automaton, then modify applyRules so it skips those ends (and comment out the first test of hasMatch in RuleSetTest). If applyRules is otherwise correct, it should give the correct results except at the ends.

Grading

Submissions

Submit the source code (.java files) for your Rule, RuleSet, and Automaton1D classes.