0

I'm generating simple game maps using a method described in this post. I'm using the second method of starting with a seed tile and randomly growing out. I'm testing it in a Swift playground on a 30x30 array. The problem is my method takes several minutes to generate a 30x30 map, and maps in my real game might exceed 100x100 tiles. How can I optimize the following code to run faster?

import UIKit
import SpriteKit
var map = [[String]](count: 30, repeatedValue:[String](count: 30, repeatedValue:" "))
var landTiles = [(y: Int,x: Int)]()
landTiles.append((15,x: 15))
let minX = 3
let maxX = 28
let minY = 3
let maxY = 28
var coastTiles = [(y: Int,x: Int)]()
var hasReachedBounds = false
while !hasReachedBounds {
    coastTiles = []
    for tile in landTiles {
        let coastal = isCoastal(tile.y, x: tile.x)
        if coastal {
            coastTiles.append(tile)
        }
    }

    let numTiles = UInt32(coastTiles.count)
    print(map)
    let randomTile = coastTiles[Int(arc4random_uniform(numTiles))]
    if randomTile.x <= minX || randomTile.x >= maxX || randomTile.y <= minY || randomTile.y >= maxY {
    hasReachedBounds = true
    break
    }
    let coastal = isCoastal(randomTile.y, x: randomTile.x)
    if !coastal{
        continue
    }

    let randomPosition = arc4random_uniform(4) + 1
    switch randomPosition {
    case 1:
        landTiles.append((randomTile.y + 1, randomTile.x))
        map [randomTile.y + 1][randomTile.x] = "&"
    case 2:
        landTiles.append((randomTile.y, randomTile.x + 1))
        map [randomTile.y][randomTile.x + 1] = "&"
    case 3:
        landTiles.append((randomTile.y - 1, randomTile.x))
        map [randomTile.y - 1][randomTile.x] = "&"
    case 4:
        landTiles.append((randomTile.y, randomTile.x - 1))
        map [randomTile.y][randomTile.x - 1] = "&"
    default: break

    }

}
func isCoastal (y: Int, x: Int) -> Bool{
    if map[y + 1][x] == " " || map[y][x + 1] == " " || map[y - 1][x] == " " || map[y][x - 1] == " "{
        return true
    } else {
        return false
    }
}

print(map)
Community
  • 1
  • 1
A Tyshka
  • 3,830
  • 7
  • 24
  • 46
  • I would guess your algorithm is spending a lot of time churning by choosing a random tile that is not on the coast (edge of the map?). Keep track of which tiles are on the "coast" and randomly pick from one of those to extend your map or use a procedure for working your way outward from the seed without using random selection. – Phil DD Mar 30 '16 at 21:03
  • I thought about that but wouldn't it take even longer to check every tile to see if it's coastal? – A Tyshka Mar 30 '16 at 22:08
  • 1
    Don't check every tile. Your map is a two-dimensional array of a fixed size. Pick a tile in the center and work your way outwards until the map is filled in. The idea is to change your algorithm to only touch each possible tile in the map once rather than randomly picking a map cell and getting an already filled in value. Put a counter in your algorithm above where you check for !coastal. The number will likely surprise you. For a 30x30 map you shouldn't iterate trying to populate the map more than 900 times, one for each map cell. – Phil DD Apr 07 '16 at 15:50
  • @PhilDD I followed your advice and now the map only chooses from coastal tiles. However checking the coastal tiles every time has dramatically slowed it down, so map generation time has gone from 20 seconds to two minutes. Advice? – A Tyshka May 17 '16 at 22:40

0 Answers0