ProcJam – v0.01 effort

Ok so a late decision to enter procjam 2015, and here is my first attempt at producing a PCG generated song. Its about 95% PCG at the moment. I am using Joy Division as my base text resource and have had some great tutorials to work through that gave me a good start:

http://taskproj.com/2014/07/algorithmic-poetry-in-c/

Here’s the first effort – please note that there has been some editing (all stated by the use of{ } and the text inside) and comma’s also inserted:

THIS WAS CREATED BY A C# PROGRAM – WITH A LOT OF HELP FROM IAN CURTIS (RIP), BERNARD SUMNER, PETER HOOK AND STEPHEN MORRIS

FOOTSTEPS

me waiting for something more, as the territories marked

no matter how hard it end where will it

end, where will burn one who goaded you to

give you, you i tried to get to the

power, it’s creeping up just second nature it’s just

second nature it’s just to feel it end, where

will it end where will it end where will

it end where will it end where will it

[CHORUS]

end these are closed, i can do you see

there i can see all true realities, up slowly

that keep your throats wasted, our respect runs so

plain to get to you, i travelled far and step

outside, an angry voice and bent on water run

through fire can’t take much can’t take much can’t

take, good taste of speed, a taste of waste

their eyes tears in a struggle between right {“when”:DELETED}

[CHORUS]

we were young directionless, so plain to you see

there i, did you forget saints with your man

traps with habits of waste their eyes tears, as

the blood on their bodies made a request well

out of the room the one who cried we’ll

share a changeling to watch admire the centre of

sadness for the pleasure, oh i’ve seen the blame

CHORUS:

with no longer the footsteps i’m,

not afraid anymore i’ve seen blood in lime,

changing our time hoping for something

more as the first light starts to sing

fine only stare in the start

of the past stand tall and apart

{two lines of text:DELETED}

Tutorial on Dungeon Generation in Objective-C

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:

Screen Shot 2014-02-16 at 1.19.12 AM

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.