Created
April 12, 2020 18:43
-
-
Save stevesparks/c5c95909a23941d3a8b9a6f290b64c27 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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