Swift中的细胞自动机程序级生成



有没有一种简单的方法可以在swift/SpriteKit(库?)中使用元胞自动机创建过程级?我想创造一个"洞穴",高11块,宽22块。这些应该是随机创建的,每个没有墙的字段都应该到达。我刚刚发现了一个使用Objective-C的文档,我对此并不熟悉。我花了相当长的时间试图理解代码并遵循示例,但没有成功。

PS:如果有更简单的方法,我会欣赏一些算法

我做了一个游乐场,在那里你可以实验

//: 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)

更新了Xcode 8和Swift 3的游乐场代码。我交换了X和Y细胞计数,因为您可能会看到"纵向"方向的视图。

请记住打开"助理编辑器"以查看结果。它也需要一段时间来执行,所以给它几分钟的时间来运行算法。

//: Playground - noun: a place where people can play
import UIKit
import SpriteKit
import XCPlayground
import PlaygroundSupport

class Cave {
    var cellmap:[[Bool]]
    let chanceToStartAlive = 35
    let deathLimit = 3
    let birthLimit = 4
    var xCell = 20 // number of cell in x axes
    var yCell = 40 // number of cell in y axes
    var wCell = 20 // cell width
    var hCell = 20 // cell height
    init(){
        cellmap = Array(repeating:
            Array(repeating:false, count:xCell), count:yCell)
        cellmap = self.initialiseMap(xIndex: xCell, yIndex:yCell)
    }
    func initialiseMap(xIndex:Int, yIndex:Int) -> [[Bool]]{
        var map:[[Bool]] = Array(repeating:
            Array(repeating:false, count:xIndex), count:yIndex)
        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.enumerated(){
            for (indexX, isWall) in row.enumerated(){
                if isWall {
                    let wall = SKSpriteNode(color: UIColor.red, 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(repeating:
            Array(repeating:false, count:xCell), count:yCell)

        for y in 0...(cellmap.count - 1) {
            for x in 0...(cellmap[0].count - 1) {
                let nbs = countAliveNeighbours( x: 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: CGRect(x: 0, y: 0, width: 768, height: 1024))
let scene:SKScene = SKScene(size: CGSize(width: 768, height: 1024))
scene.scaleMode = SKSceneScaleMode.aspectFit
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = view
let aCave = Cave()
aCave.applyRules()
aCave.applyRules()
aCave.addSprite(scene: scene)
view.presentScene(scene)

相关内容

  • 没有找到相关文章

最新更新