Cellz: Getting Started

View League Table
Download Cellz Developer Kit

Introduction

This document explains how to specify and submit a controller for the Cellz game.  Cellz is currently being run as a competition for GECCO 2004.  One of the purposes of the Cellz, and of the GECCO contest, is to gain insights into what makes a good representation space in which to search for controllers of this type.

The Cellz toolkit comes with two representations: a perceptron style controller, and a general kind of neural network controller - simply a directed function graph.

The toolkit comes with a simple evolutionary algorithm (a random mutation hill-climber) that allows you to evolve controllers in either space.  Note that to win the contest, you are encouraged to choose a better space to work in than either of these!  The evolutionary algorithms contained in the toolkit are very simple, and are provided for demonstration purposes.  Again, you should be able to do better!

The descriptions below are rather brief.  For more details refer to the source code, which I hope you will find easy to understand.  The code is structured into several packages and many simple classes.  You will find the code easy to navigate if you use a modern Java IDE, such as Intellij Idea or Eclipse.

Controllers to be submitted to the GECCO contest must use either the perceptron or directed graph input format.  Note that the directed function graph is a very general representation.  Whichever space you choose to do your evolution in, you should then map your evolved controller to the directed graph format.  Controllers specified in this format can be evaluated directly with the Cellz developer kit.  You can do this either with a direct call to a Java method, or by writing your controller to a file, and then invoking the games.cellz.FitnessEvaluator command line program to evaluate it.

The perceptron input format is really for a bit of fun - it allows anyone to submit an entry simply by specifying 32 numbers!  This idea of a simple entry route was inspired by Dan Ashlock's CEC 2004 contest on plant growth - a different contest, but with a very simple input format.

Directed Function Graph

Conventional GP uses an expression tree.  Here we use a simple general directed graph format.  You can easily map any expression tree into this format (but be careful to use only the allowed set of function nodes, or choose functions that can be mapped into the allowed set).

This is implemented with the Network class - see the code in problems.neural.Network.java

A Network (i.e. directed function graph) is evaluated with the following method.  The outputs are then read off from the top end of the net array.

    public void eval(double[] ip) {
        // set up the input nodes first
        for (int i = 0; i < ip.length; i++) {
            net[i] = ip[i];
        }

        // now evaluated the network
        // note that the input nodes are not evaluated
        for (int i = nInputs; i < maxNodes; i++) {
            if (node[i] != null) {
                net[i] = node[i].eval(net);
            }
        }
    }

The Cell Controller

At each point in time your cell controller takes directional inputs from the game area (think of a wrap-around retina) and outputs a force vector.  It is also given it's current mass and velocity.

The interface to the cell controller is specified in Java like this:

public interface SensorLogic {
/**
*
* @param food: food sensor array
* @param cell: cell sensor array
* @param v: current velocity vector of this cell
* @param mass: current mass of this cell
* @return the chosen force vector
*/
public Vector2d getForce(double[] food, double[] cell, Vector2d v, double mass);
}

The sensor arrays are 8-dimensional (think compass points), so these parameters end up as 19 numerical inputs to your controller.  The sensor arrays are depicted below:

The nodes of the graph are functions drawn from the following set:

Where 'I' indicates a set of graph inputs (max 10 inputs per node), 'i' indicates a single graph input, and 'r' is a real-valued constant.  Note that cells automatically split after they exceed a certain critical mass, specified in the Settings file.

File Format

The format is simple: each line specifies a node, giving it a number, a function, then its list of inputs.

Each cell is given 19 inputs, labelled 0 to 18.

Your function nodes then begin at number 19.

You are allowed a maximum of 250 function nodes.  An example file is shown below.

Evaluating a Controller

When you have designed or evolved your own controller (or if you're in the process of evolving one), you can evaluate its fitness using the FitnessEvaluator class.  This may be invoked from the command-line, or from within another Java program.

The command-line version is used as follows (in this example were running 10 experiments, each for 1,000 time-steps:

java games.cellz.FitnessEvaluator SampleDG.txt 1000 10
Made network with 89 total nodes
Results summary:

min = 483.44841591500034
max = 812.1678760590038
ave = 635.949299122832
sd = 107.90986011178774
se = 34.12409399434012
sum = 6359.4929912283205
sumsq = 4149115.9517323235
watch = null
n = 10
1412 ms elapsed

To evaluate a controller from a Java program, import the games.cellz.FitnessEvaluator class, then call the static evaluate method of that class:

 StatisticalSummary ss = 
   FitnessEvaluator.evaluate(controller, timeSteps, nRuns);

where controller could be an instance of NeuralControl, which is a class that takes a neural network (directed function graph) and wraps it to implement the CellControl interface.

Evolving a Controller

To help get you started, a random mutation hill-climber is supplied.  This is set up to evolve either perceptron (default) or directed graph controllers.  You can run this as follows:

java games.cellz.EvolveController <nGens> <timeSteps>

The Cellz game has a significant random element to it, so it's a good idea to base the fitness function (at least for the hill-climber) on many game runs - the default used by this program is 10 game runs per fitness evaluation.  If you run the hill-climber for 1000 generations, it should evolve a reasonable controller when searching in perceptron space.  Searching in Directed Graph space seems to be harder - but good luck with this! 

The program will print out the best individual it found during the run of the hill climber.  In the case of evolving a perceptron, this just prints out the weight matrix.  Save this to a text file.

Converting a Perceptron to a Directed Graph

You can then run the ConvertPerceptron program to convert this to a directed graph representation, which may then be submitted as an entry to the competition.

Suppose you saved the weights to a file called EvoWeights.txt, then you can run the conversion program as follows:

java games.cellz.ConvertPerceptron EvoWeights.txt EvoDG.txt

This could produce a file containing text such as that shown in the appendix.

Cellz Animation

You can observe the behaviour of your evolved cell controller:

java games.cellz.DishController SampleDG.txt

You can overide the default options - should look something like this:

Note that if you miss off the filename, the system will run with a default hand-designed controller (working on the same sensor-based inputs).

java games.cellz.DishController

This has interesting behavior, in that it performs very well for a few thousand time-steps, and then completely freezes.  Try it!

Note that you can also play against your evolved programs - set MouseController = true, and you'll have a species of yellow cell to control - the cells always head straight for the mouse pointer.  With some skill and luck, you may be able to beat your own evolved controllers!

Submitting a Controller

When you have a controller in the correct directed graph format, you can submit it to the web-based evaluation system.  Just paste the textual specification of the controller into the web form, and click submit (note that nearer the competition deadline you'll also need to provide some registration details).

The submission form is  here

If all goes well, you should get a response something like this:

Trying   10 experiments
Each for 1000 time steps


 min = 527.1215983779816
 max = 918.5496552099675
 ave = 747.0635335229495
 sd  = 114.73990510637535
 se  = 36.28394386477305
 sum  = 7470.635335229495
 sumsq  = 5699526.443612331
 watch = null
 n   = 10
1792 ms elapsed

Thank you for your submission

Appendix 1: Sample Perceptron Controller

Below is a sample perceptron controller - simply specified as a set of 32 weights in the weight matrix connecting the 16 inputs with the two outputs:

-91.08398800672279 181.36371005075267 -46.70294024496973 110.84617492377723 99.20823198346234 -5.156549901404951 43.027384813844414 -319.1250595529542 178.30382832839948 45.862523930926336 99.83320181604208 -216.76474097449307 63.301287359780744 -40.7527129164992 -78.33699942251222 62.72863029677474
271.31993625545476 -222.7670199821426 432.4742500271704 -17.746681433059315 -42.0223492084727 -427.814325716213 -96.57975646348736 -411.089671736812 24.856269663769172 -87.51111336185215 -6.710333625137078 115.68385478744595 77.02414672665172 3.472136920894549 251.4568079030636 270.5703611905452

Appendix 2: Sample Directed Graph Controller

A sample controller (derived from an evolved perceptron) is shown below.  Note that the behaviour is not identical - the perceptron output goes through some non-linearities (see games.cellz.WeightedSum), whereas the outputs of the directed graph are used directly.

You can evaluate this by pasting it into the text area on the web based evaluation service page, here

// sample DG from a simple perceptron controller
// specify number of inputs and total number of nodes
19 89

// now the set of constants - 
// node number starts immediately after all inputs

19 Const -91.08398800672279
20 Const 181.36371005075267
21 Const -46.70294024496973
22 Const 110.84617492377723
23 Const 99.20823198346234
24 Const -5.156549901404951
25 Const 43.027384813844414
26 Const -319.1250595529542
27 Const 178.30382832839948
28 Const 45.862523930926336
29 Const 99.83320181604208
30 Const -216.76474097449307
31 Const 63.301287359780744
32 Const -40.7527129164992
33 Const -78.33699942251222
34 Const 62.72863029677474
35 Const 271.31993625545476
36 Const -222.7670199821426
37 Const 432.4742500271704
38 Const -17.746681433059315
39 Const -42.0223492084727
40 Const -427.814325716213
41 Const -96.57975646348736
42 Const -411.089671736812
43 Const 24.856269663769172
44 Const -87.51111336185215
45 Const -6.710333625137078
46 Const 115.68385478744595
47 Const 77.02414672665172
48 Const 3.472136920894549
49 Const 251.4568079030636
50 Const 270.5703611905452

// products - each one multiplies an input by a constant
51 Prod 0 19 
52 Prod 1 20 
53 Prod 2 21 
54 Prod 3 22 
55 Prod 4 23 
56 Prod 5 24 
57 Prod 6 25 
58 Prod 7 26 
59 Prod 8 27 
60 Prod 9 28 
61 Prod 10 29 
62 Prod 11 30 
63 Prod 12 31 
64 Prod 13 32 
65 Prod 14 33 
66 Prod 15 34 
67 Prod 0 35 
68 Prod 1 36 
69 Prod 2 37 
70 Prod 3 38 
71 Prod 4 39 
72 Prod 5 40 
73 Prod 6 41 
74 Prod 7 42 
75 Prod 8 43 
76 Prod 9 44 
77 Prod 10 45 
78 Prod 11 46 
79 Prod 12 47 
80 Prod 13 48 
81 Prod 14 49 
82 Prod 15 50 

// sum the products - limited fan-in
// (as specified by GECCO contest)
83 Sum 51 52 53 54 55 56 57 58 
84 Sum 59 60 61 62 63 64 65 66 
85 Sum 67 68 69 70 71 72 73 74 
86 Sum 75 76 77 78 79 80 81 82 

// finally the outputs
87 Sum 83 84 
88 Sum 85 86 


Appendix 3: Cellz Paper

You can download the following paper to appear in CEC 2004:

    PortlandCellz.pdf

This gives more background on the game, though note that the precise details differ in a few ways to the setup for the GECCO contest.

Appendix 4: Game Parameters

The parameters that control the game, and the display / animation of the game are contained in the Settings class, listed below.

package games.cellz;

public class Settings {

    public static boolean video = false;  // show animation window if true
    public static boolean sound = false;  // generate sounds to accompany events?
    public static boolean trace = false;  // if true then each cell leaves a trace as it moves
    public static int delay = 100;        // the delay between frame updates in the animation

    // next four relate to the physics model
    public static double maxVelocity = 15;
    public static double friction = 0.03;
    public static double initMass = 50;
    public static double maxForce = split / 10; // relate max force to max cell mass
 
    // next four define game setup  
    public static int split = 80; // cells split when they reach this mass
    public static int nFood = 10; // number of food particles
    public static int nCells = 5; // initial number of cells
    public static int foodSize = 4; // should specify the mass to be consistent

    public static int timeLimit = -1; // cycle forever if '-1' - set a positive value for a limited run
    public static boolean mouse = false; // if true, then add a human (mouse) controlled species

    // there will be a sensor array for each species (food is considered a species)
    public static int nSpecies = 2; 

    // maximum number of nodes allowed in the Directed Graph
    public static int maxDAGNodes = 250;

    public static int width = 640;  // dimensions of play area (in screen pixels or meters)
    public static int height = 480;

}