Cellular automata generator

Interesting cave systems can be created using ROT.Map.Cellular, a generator which simulates a cellular automaton. Using this generator is a bit more complex, because it offers richer features and is more configurable.

Apart from the traditional width and height arguments, ROT.Map.Cellular accepts also a configuration object with the following optional keys:

It is also possible to initialize/set values for the first generation of cells. Two methods are provided:

It is possible (and desirable) to call the create method repeatedly: every call will create a new generation. There is no need to specify a callback, if you only want to advance into next generation, without actually retrieving the current map data. By default, the born and survive options are set according to this Roguebasin article.

ROT.Map.Cellular uses the following callback values:

var w = 80, h = 40; var map = new ROT.Map.Cellular(w, h); /* cells with 1/2 probability */ map.randomize(0.5); /* generate and show four generations */ for (var i=0; i<4; i++) { var display = new ROT.Display({width:w, height:h, fontSize:4}); SHOW(display.getContainer()); map.create(display.DEBUG); }
var w = 100, h = 60; var display = new ROT.Display({width:w, height:h, fontSize:6}); SHOW(display.getContainer()); /* custom born/survive rules */ var map = new ROT.Map.Cellular(w, h, { born: [4, 5, 6, 7, 8], survive: [2, 3, 4, 5] }); map.randomize(0.9); /* generate fifty iterations, show the last one */ for (var i=49; i>=0; i--) { map.create(i ? null : display.DEBUG); }

Once the map has been created, you can optionally call connect() to connect every free space. This way the player can traverse every part of the maze. You might have to refresh this page a few times to spot the differences.

var w = 80, h = 40; /* create a map */ var map = new ROT.Map.Cellular(w, h); /* cells with 1/2 probability */ map.randomize(0.5); /* make a few generations */ for (var i=0; i<4; i++) map.create(); /* display only the final map */ var display = new ROT.Display({width:w, height:h, fontSize:4}); SHOW(display.getContainer()); map.create(display.DEBUG); /* now connect the maze so the player can reach all non-wall sections */ var display = new ROT.Display({width:w, height:h, fontSize:4}); SHOW(display.getContainer()); map.connect(display.DEBUG);

You can also connect walls instead of empty space by specifying the map value that should be connected. See the second parameter of the connect() call below:

var w = 80, h = 40; /* create a map */ var map = new ROT.Map.Cellular(w, h); /* cells with 1/2 probability */ map.randomize(0.5); /* make a few generations */ for (var i=0; i<4; i++) map.create(); /* display only the final map */ var display = new ROT.Display({width:w, height:h, fontSize:4}); SHOW(display.getContainer()); map.create(display.DEBUG); /* now connect the maze so the player can reach all non-wall sections */ var display = new ROT.Display({width:w, height:h, fontSize:4}); SHOW(display.getContainer()); map.connect(display.DEBUG, 1);

Finally, you can be optionally notified when connect creates a new connection between formerly separate regions.

var w = 80, h = 40; /* create a map */ var map = new ROT.Map.Cellular(w, h); /* cells with 1/2 probability */ map.randomize(0.5); /* make a few generations */ for (var i=0; i<4; i++) map.create(); /* display only the final map */ var display = new ROT.Display({width:w, height:h, fontSize:4}); SHOW(display.getContainer()); map.create(display.DEBUG); /* now connect the maze */ var display = new ROT.Display({width:w, height:h, fontSize:4}); SHOW(display.getContainer()); map.connect(display.DEBUG, 0, function(from, to) { SHOW("Connection was made " + from + " to " + to); });