To create your own rule family you need a java compiler
and the source code of frank's java cellular automaton program.

You can download the java compiler at http://java.sun.com/j2se/1.4.2/download.html .
You can download the source code of frank's java cellular automaton program here .

Go find the file named rule_families.java in the same directory as cellauto.java
If you can not find it then you can try downloading the latest version here.
Open file named rulefamilies.java in any text editor.

Find the function named getrulefamily and add these lines inside that function.
if (name.equals("example")){
   return new example_rule_familyc(name);
}


Create a new file named example_rule_family.java in the same directory as cellauto.java.

Add these lines to the new file.
import java.lang.*;
import java.util.*;
import java.io.*;

class example_rule_familyc extends abstractcellautorulefamilyc {
   example_rule_familyc(String name) {
     super(name);
   }
   int getbordersize() {
     //return a 9x9 neighborhood size
     return 4;
   }
   int calcsq(cellautorulec c,boardc b,int x,int y,int t) {
     return 0;
   }
}

Now compile the program by typing
javac cellauto.java rule_families.java example_rule_family.java

Now run the program named frank's java cellular automaton program.
if the rule table is less than 13 entries wide then
make the rule table wider by going to edit->resize rule table.


create the file named example_rule_family.txt
you can choose 3 choices when you create the file example_rule_family.txt

1. you can go to file->save and name the file example_rule_family.txt,
open the file example_rule_family.txt in any text editor,
add this line to it
rulefamily,example
then reload the file example_rule_family.txt into frank's java cellular automaton program

2. you can go to view->show rule family browser to view the rule family browser,
select the rule named example then click on the "select rule family" button and save it
as example_rule_family.txt
note: if you want it to show up in the rule family browser then
you can add this line to the getrulefamilylist function in rule_families.java
v.add("example");

3. you can download the file example_rule_family.txt here
then load it into the program.




You should notice that every pattern in any rule disappears when space bar is pressed.
Thats because the function named calcsq in the class named example_rule_familyc
Ignores the rule table and always returns zero.

Add these lines in bold to the function named calcsq
int calcsq(cellautorulec c,boardc b,int x,int y,int t) {
   int sq = b.getsq(x,y);
   int pop = 0;
   for (int dx = -1;dx <= 1;dx++) {
     for (int dy = -1;dy <= 1;dy++) {
       pop = pop + b.getsq(x+dx,y+dy);
     }
   }
   pop = pop - sq;
   if (sq == 0) {
     if (pop == 3) {return 1;}
   }
   if (sq == 1) {
     if (pop == 2) {return 1;}
     if (pop == 3) {return 1;}
  }
  return 0;
}

Now compile and run it again.

Now open the file example_rule_family.txt
and notice that it always plays john conway's game of life.
Try changing the rule table and notice that it still plays life.
That's because the function named calcsq ignores the rule table.

What the calcsq function does, is that it calculates the cell's next state based
the cell's current state and it's neighbors.

You can program how your rule family calculates each cell's next state by
writing your own code in calcsq.
Change the code in the function named calcsq to
int calcsq(cellautorulec c,boardc b,int x,int y,int t) {
   int sq = b.getsq(x,y);

   pop = pop + c.cellvalue[b.getsq(x+1,y+1)];
   pop = pop + c.cellvalue[b.getsq(x-1,y+1)];
   pop = pop + c.cellvalue[b.getsq(x+1,y-1)];
   pop = pop + c.cellvalue[b.getsq(x-1,y-1)];

   pop = pop + c.cellvalue[b.getsq(x+1,y)];
   pop = pop + c.cellvalue[b.getsq(x-1,y)];
   pop = pop + c.cellvalue[b.getsq(x,y+1)];
   pop = pop + c.cellvalue[b.getsq(x,y-1)];

   pop = pop + c.cellvalue[b.getsq(x+2,y)];
   pop = pop + c.cellvalue[b.getsq(x-2,y)];
   pop = pop + c.cellvalue[b.getsq(x,y+2)];
   pop = pop + c.cellvalue[b.getsq(x,y-2)];

   return c.getlookuptable(pop,sq);

}

Here b.getsq gets the state of the cell's neighbor,
c.cellvalue is array containing the value of each state
and c.getlookuptable lookups the cell's new state in the rule table.
Tip: you can use c.getbordervalue(x,y) to get the neighborhood weights
and c.getbordersize() to get the neighborhood size.

Tip: you can get your rulefamily to return the current neighborhood size
by adding this code:
int getbordersize(){
  return cellautoapp.cellauto131.bordersize;
}


Now compile and run it again.

Now open the file example_rule_family.txt
and try changing the rule table.
Notice that each cell counts it's neighbors in the 12 cell extended von Neumann neighborhood
and uses that count as a index when it lookups it's new state in the rule table.

now we are going to make a new rule family that uses a dailog box.

Open file named rulefamilies.java in any text editor.

Find the function named getrulefamily and add these lines inside that function.
if (name.equals("example2")){
   return new example_cellautorulefamilyc(name);
}


Find the function named getrulefamilylist in rule_families.java
and add this line to this function.
v.add("example2");

Create a new file named example_rule_family2.java in the same directory as cellauto.java

Add these lines to the new file.
import java.lang.*;
import java.util.*;
import java.io.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class example_cellautorulefamilyc extends abstractcellautorulefamily {
  int number = 0;
  example_dialog_boxc example_dialog_box = null;
  example_cellautorulefamilyc(String name) {
    super(name);
  }
  int getbordersize(){
    return 1;
  }
  int calcsq(cellautorulec c,boardc b,int x,int y,int t){
    int sq = b.getsq(x,y);
    int a = 0;
    if (sq > 0) {a = number;}
    return a;
  }
}

Now we are going to add the dailog box.
The dailog box implements ActionListener
so It can update the variable called number when the ok button is clicked.

Add this class to example_rule_family2.java
class example_dialog_boxc extends JFrame implements ActionListener{
  example_cellautorulefamilyc example_cellautorulefamily = null;
  JLabel number_label;
  JTextField number_edit;
  JButton okbutton;
  JButton cancelbutton;
  example_dialog_boxc(String Title) {
    super(Title);
    GridBagLayout gl = new GridBagLayout();
    this.getContentPane().setLayout(gl);
    GridBagConstraints cc = new GridBagConstraints();

    cc.fill = GridBagConstraints.BOTH;
    cc.weightx = 1.0;
    cc.weighty = 1.0;

    number_label = new JLabel("enter a number");
    cc.gridwidth = GridBagConstraints.REMAINDER;
    gl.setConstraints(number_label, cc);
    this.getContentPane().add(number_label);

    number_edit = new JTextField("0");
    cc.gridwidth = GridBagConstraints.REMAINDER;
    gl.setConstraints(number_edit, cc);
    this.getContentPane().add(number_edit);

    okbutton = new JButton("ok");
    okbutton.setActionCommand("ok_buttonclick");
    okbutton.addActionListener(this);
    cc.gridwidth = 2;
    gl.setConstraints(okbutton, cc);
    this.getContentPane().add(okbutton);

    cancelbutton = new JButton();
    cancelbutton.setText("cancel");
    cancelbutton.setActionCommand("cancel_buttonclick");
    cancelbutton.addActionListener(this);
    cc.gridwidth = GridBagConstraints.REMAINDER;
    gl.setConstraints(cancelbutton, cc);
    this.getContentPane().add(cancelbutton);
    this.pack();
  }
  public void actionPerformed(ActionEvent e) {
    String action = e.getActionCommand();
    if (action.equals("ok_buttonclick")){
      //if the ok button is clicked then
      //get the value from the text box and use to update
      //the variable called number
      example_cellautorulefamily.number = Integer.valueOf(number_edit.getText()).intValue();
      this.setVisible(false);
    }
    if (action.equals("cancel_buttonclick")){
     this.setVisible(false);
    }
  }
}

Now we are going to override the method showoptions
so it can show a dailog box.

Add this code to the class named example_cellautorulefamilyc
  //here is the code that show the dailog box
  void showoptions(){
    //create it if it does not exist
    if (example_dialog_box == null) {
      example_dialog_box = new example_dialog_boxc("example dialog");
      example_dialog_box.setBounds(0,0,400,150);
    }

    //set the text box to the current value of the variable named num
    example_dialog_box.number_edit.setText(Integer.toString(number));

    //give the dialog box a reference to the example rule family
    example_dialog_box.example_cellautorulefamily = this;

    //show it
    example_dialog_box.setVisible(true);
  }

Now we add code that saves the variable called number each a file is saved
override the method called writelines.
here is code that does it. add this code to the class named example_cellautorulefamilyc
void writelines(Vector lines){
  lines.add("number," + number);
}

Now we add code that loads the variable called number each a file is loaded.
override the method called readline.
here is code that does it. add this code to the class named example_cellautorulefamilyc
void readline(String str){
  String ss[] = str.split(",");
  String st = ss[0];
  if (st.equals("number")) {
    number = Integer.valueOf(ss[1]).intValue();
  }
}

now compile the program by typing javac cellauto.java rule_families.java
example_rule_family.java example_rule_family2.java

run the program.

Go to view->show rule family browser to view the rule family browser.
Select the rule named example2 then click on the "select rule family" button.

Go to edit->show rule family options.
You should see a dialog box that saids enter a number.
Enter 2 and click Ok.
Draw any pattern
and notice that all the cells with non-zero states in the pattern
turn to state 2 (red).
You could try entering 3 into the dialog box (blue) or 1 (yellow).

Now save the pattern and restart the program load same pattern that last saved.
go to edit->show rule family options.
notice that the dailog box shows the last value entered before the file was saved.

Congratulations you programmed your own rule families.
You can look at the comments in rule_families.java for more info
and that's all for now.