So I am getting a Cellular Automator (CA) generator ready for this years 7DRL and hoping to create the same game in iOS and HTML5 – I am sure I am biting too much off. However, I have a basic implementation of a Dungeon generator and detailed how to create it below in X-Code using Objective-C. It’s a very simple implementation – so feel free to comment if you think we can clean the code up!!!!
In terms of CA there are some great references to get you going:
http://pcg.wikidot.com/pcg-algorithm:cellular-automata
http://www.futuredatalab.com/proceduraldungeon/
http://csharpcodewhisperer.blogspot.com.au/2013/07/Rouge-like-dungeon-generation.html
For this tutorial the dungeon is represented by 0’s as Rock and 1’s as Path (or moveable space).
This is the output so far:

So its a pretty simple set of steps to get us going.
Firstly create a OSX->Application->Command LineTool->Foundation project in Xcode
Then add a class called Dungeon
The header for Dungeon should look like this
#import <Foundation/Foundation.h>
@interface Dungeon : NSObject
{
int map[100][100]; //max size of dungeon
int maxRows; //size of this dungeon
int maxCols; //size of this dungeon
}
- (id)initWithRows:(int)rows AndCol:(int)cols;
-(void)printMap;
@end
The implementation for this should look like
#import "Dungeon.h"
@implementation Dungeon
- (id)initWithRows:(int)rows AndCol:(int)cols
{
self = [super init];
if (self) {
[self initMap];
maxRows = rows;
maxCols = cols;
[self createCellularAutomatorDungeon:maxRows ForCols:maxCols];
}
return self;
}
//set all the map to rock
-(void)initMap
{
for(int i=0;i<maxRows;i++)
for(int j=0;j<maxCols;j++)
map[i][j] = 0;
}
//Loop through the 2 dim array and add space (not rock) if the wall has a specific minimum neighbourCount
- (void)createCellularAutomatorCellsForNeighbourCount:(int)neighbourCount
{
//first pass CA
for(int i=0;i<maxRows;i++)
{
for(int j=0;j<maxCols;j++)
{
if (map[i][j] == 0 && ([self getNeighboursForRow:i ForCol:j]>=neighbourCount))
map[i][j] = 1;
}
}
}
//use a classic CA algorithm
-(void)createCellularAutomatorDungeon:(int)rows ForCols:(int)cols
{
//randomly initialize wih a few random spaces in the rock
for(int i=1;i<maxRows;i++)
for(int j=1;j<maxCols;j++)
if (arc4random()%4==1)
map[i][j] = 1;
[self createCellularAutomatorCellsForNeighbourCount:4];//first pass
[self createCellularAutomatorCellsForNeighbourCount:5];//second pass
}
//Count of the number of neighbours for this point
-(int)getNeighboursForRow:(int)row ForCol:(int)col
{
int n = 0;
//top neighbours
if (row>0 && col>0)
{
for(int i=col-1;i<col+2;i++)
{
if (map[row-1][i]==1)
n++;
}
}
//middle neighbour left
if (col>0 && col<maxCols)
if (map[row][col-1]==1)
n++;
//middle neighbour right
if (col>0 && col<maxCols)
if (map[row][col+1]==1)
n++;
//bottom neighbours
if (row<maxRows && col<maxCols)
{
for(int i=col-1;i<col+2;i++)
{
if (map[row+1][i]==1)
{
n++;
}
}
}
return n;
}
-(BOOL)ifValidCoordinateForRow:(int)row ForCol:(int)col
{
return (map[col][row]==0 && row>0 && col > 0 && row<maxRows && col<maxCols);
}
-(void)printMap
{
for(int i=0;i<maxRows;i++)
{
for(int j=0;j<maxCols;j++)
printf("%u", map[i][j] );
printf("\n");
}
}
And make sure that main.m looks like
#import <Foundation/Foundation.h>
#import "Dungeon.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
NSLog(@"Basic Dungeon CA Algorithm");
Dungeon *dungeon =[[Dungeon alloc]initWithRows:30 AndCol:50];
[dungeon printMap];
}
return 0;
}
Ok so if you look at the code above in dungeon.m you should get a pretty good idea of how we are doing the generation of the dungeon using a CA algorithm. Read the comments as I have tried to explain anything a little unusual. If anything doesn’t make sense – leave a comment and I’ll get back to you.
Happy coding.