Skip to content

Instantly share code, notes, and snippets.

@stevesparks
Created April 12, 2020 18:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevesparks/c5c95909a23941d3a8b9a6f290b64c27 to your computer and use it in GitHub Desktop.
Save stevesparks/c5c95909a23941d3a8b9a6f290b64c27 to your computer and use it in GitHub Desktop.
class GameScene: SKScene {
var board = [[CellNode]]()
let boardSizeX = 46
let boardSizeY = 25
override func didMove(to view: SKView) {
for x in 0...boardSizeX {
var nodes = [CellNode]()
for y in 0...boardSizeY {
let newNode = CellNode.generate()
if arc4random() % 100 < 13 {
newNode.isDead = false
}
newNode.position = CGPoint(x: x * 20 - (boardSizeX * 10), y: (y * 20) - (boardSizeY * 10))
addChild(newNode)
nodes.append(newNode)
}
board.append(nodes)
}
// set the neighbors
for x in 0...boardSizeX {
let nodes = board[x]
let beforeNodes = x > 0 ? board[x-1] : []
let afterNodes = x < (boardSizeX-1) ? board[x+1] : []
for y in 0...boardSizeY {
let node = nodes[y]
if y > 0 {
node.neighbors.append(nodes[y-1])
if !beforeNodes.isEmpty {
node.neighbors.append(beforeNodes[y-1])
}
if !afterNodes.isEmpty {
node.neighbors.append(afterNodes[y-1])
}
}
if y < (boardSizeY-1) {
node.neighbors.append(nodes[y+1])
if !beforeNodes.isEmpty {
node.neighbors.append(beforeNodes[y+1])
}
if !afterNodes.isEmpty {
node.neighbors.append(afterNodes[y+1])
}
}
if !beforeNodes.isEmpty {
node.neighbors.append(beforeNodes[y])
}
if !afterNodes.isEmpty {
node.neighbors.append(afterNodes[y])
}
}
}
// Inject more life when it dies
let tap = UITapGestureRecognizer(target: self, action: #selector(kick))
view.addGestureRecognizer(tap)
}
func nextGeneration() {
for row in board {
for cell in row {
cell.calculateNextGeneration()
}
}
for row in board {
for cell in row {
cell.applyNextGeneration()
}
}
}
@objc
func kick() {
for row in board {
for cell in row {
if cell.isDead {
cell.isDead = arc4random() % 100 > 13
}
}
}
}
override func update(_ currentTime: TimeInterval) {
nextGeneration()
}
}
fileprivate extension UIColor {
static let deadColor = UIColor.blue
static let aliveColor = UIColor.green
}
class CellNode: SKShapeNode {
static let baseSize = CGSize(width: 20, height: 20)
class func generate() -> CellNode {
let newNode = CellNode(rectOf: baseSize)
newNode.strokeColor = .black
return newNode
}
var isDead = true {
didSet {
self.fillColor = isDead ? .deadColor : .aliveColor
}
}
var neighbors = [CellNode]()
var willBeDead = true
func calculateNextGeneration() {
let livingNeighbors = neighbors.filter { !$0.isDead }
switch (isDead, livingNeighbors.count) {
case (true, 3): willBeDead = false
case (false, 2): willBeDead = false
case (false, 3): willBeDead = false
default: willBeDead = true
}
}
func applyNextGeneration() {
isDead = willBeDead
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment