Lukas Köhl Lukas Köhl - 1 year ago 142
Swift Question

Procedural Level Generation With Cellular Automaton In Swift

Is there a easy way to create a procedural level with a cellular automaton in swift/SpriteKit(library?)? I want to create a 'cave' with 11 fields in the height and 22 width. These should be randomly created and every field without a wall should be reached.
I just found a documentation using Objective-C, which I am not familiar with. I spend quite some time trying to understand the code and follow the example without success.

PS: If there is an easier way I appreciate some algorithms

Answer Source

I made a Playground where you can experiment

//: Playground - noun: a place where people can play

import UIKit
import SpriteKit
import XCPlayground


class Cave {

    var cellmap:[[Bool]]

    let chanceToStartAlive = 35
    let deathLimit = 3
    let birthLimit = 4
    var xCell = 40 // number of cell in x axes
    var yCell = 20 // number of cell in y axes
    var wCell = 20 // cell width
    var hCell = 20 // cell height

    init(){
        cellmap = Array(count:yCell, repeatedValue:
            Array(count:xCell, repeatedValue:false))

        cellmap = self.initialiseMap(xCell, yIndex:yCell)
    }

    func initialiseMap(xIndex:Int, yIndex:Int) -> [[Bool]]{
        var map:[[Bool]] = Array(count:yIndex, repeatedValue:
            Array(count:xIndex, repeatedValue:false))

        for y in 0...(yIndex - 1) {
            for x in 0...(xIndex - 1) {

                let diceRoll = Int(arc4random_uniform(100))

                if diceRoll < chanceToStartAlive {
                    map[y][x] = true
                } else {
                    map[y][x] = false
                }
            }
        }
        return map
    }

    func addSprite(scene:SKScene){
        for (indexY, row) in cellmap.enumerate(){
            for (indexX, isWall) in row.enumerate(){
                if isWall {

                    let wall = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: wCell, height: hCell))
                    wall.position = CGPoint(x: (indexX * wCell) + (wCell / 2) , y: (indexY * hCell) + (hCell / 2)  )
                    scene.addChild(wall)
                }
            }
        }
    }

    func countAliveNeighbours(x:Int, y:Int) -> Int{

        var count = 0
        var neighbour_x = 0
        var neighbour_y = 0

        for i in -1...1 {

            for j in -1...1 {

                neighbour_x = x + j
                neighbour_y = y + i


                if(i == 0 && j == 0){
                } else if(neighbour_x < 0 || neighbour_y < 0 || neighbour_y >= cellmap.count || neighbour_x >= cellmap[0].count){
                    count = count + 1
                } else if(cellmap[neighbour_y][neighbour_x]){
                    count = count + 1
                }

            }

        }

        return count

    }

    func applyRules(){

        var newMap:[[Bool]] = Array(count:yCell, repeatedValue:
            Array(count:xCell, repeatedValue:false))



        for y in 0...(cellmap.count - 1) {
            for x in 0...(cellmap[0].count - 1) {
                let nbs = countAliveNeighbours( x, y: y);
                if(cellmap[y][x]){
                    if(nbs < deathLimit){
                        newMap[y][x] = false;
                    }
                    else{
                        newMap[y][x] = true;
                    }
                } else{
                    if(nbs > birthLimit){
                        newMap[y][x] = true;
                    }
                    else{
                        newMap[y][x] = false;
                    }
                }
            }
        }
        cellmap = newMap
    }
}

let view:SKView = SKView(frame: CGRectMake(0, 0, 1024, 768))

XCPShowView("Live View", view: view)

let scene:SKScene = SKScene(size: CGSizeMake(1024, 768))
scene.scaleMode = SKSceneScaleMode.AspectFit

let aCave = Cave()

aCave.applyRules()
aCave.applyRules()

aCave.addSprite(scene)
view.presentScene(scene)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download