A simulation on a rectangular grid - Conway’s game of life
This activity has the following desired goals:
- Learning about cellular automata (A, M).
- Learning to do simulations on a rectangular grid (A, M).
- Implement Conway’s game of life (M, T).
Step 0
Read up on Cellular Automata.
Step 1
Type in the following code and run it:
size(500, 500)
cleari()
clearOutput()
originBottomLeft()
setBackground(white)
val n = 50
val dx = cwidth.toFloat / n
val dy = cheight.toFloat / n
def createPopulation(n: Int): ArrayBuffer[ArrayBuffer[Int]] = {
val newPop = ArrayBuffer.empty[ArrayBuffer[Int]]
repeatFor(0 until n) { x =>
val populationColumn = ArrayBuffer.empty[Int]
repeatFor(0 until n) { y =>
populationColumn.append(0)
}
newPop.append(populationColumn)
}
newPop
}
var population = createPopulation(n)
def drawCell(x: Int, y: Int) {
val cell = Picture.rectangle(dx, dy)
cell.setPosition(x * dx, y * dy)
cell.setPenThickness(0.1)
cell.setPenColor(cm.lightBlue)
draw(cell)
}
def drawLiveCell(x: Int, y: Int) {
val cell = Picture.ellipseInRect(dx, dy)
cell.setPosition(x * dx, y * dy)
cell.setPenThickness(2)
cell.setPenColor(cm.lightBlue)
cell.setFillColor(cm.darkBlue)
draw(cell)
}
def drawGrid() {
repeatFor(0 until n) { x =>
repeatFor(0 until n) { y =>
drawCell(x, y)
}
}
}
def drawPopulation() {
repeatFor(0 until n) { x =>
repeatFor(0 until n) { y =>
if (population(x)(y) == 1) {
drawLiveCell(x, y)
}
}
}
}
def populationCopy = {
val newPop = createPopulation(n)
repeatFor(0 until n) { x =>
repeatFor(0 until n) { y =>
newPop(x)(y) = population(x)(y)
}
}
newPop
}
def inRange(n: Int, low: Int, high: Int) = {
n >= low && n <= high
}
def evolveCell(x: Int, y: Int, newPop: ArrayBuffer[ArrayBuffer[Int]]) {
if (inRange(x - 1, 0, n - 1) && inRange(y - 1, 0, n - 1)) {
if (population(x - 1)(y - 1) == 1) {
newPop(x)(y) = 1
newPop(x - 1)(y - 1) = 0
}
}
}
def updatePopulation() {
val newPop = populationCopy
repeatFor(0 until n) { x =>
repeatFor(0 until n) { y =>
evolveCell(x, y, newPop)
}
}
population = newPop
}
def initPopulation(init: ArrayBuffer[(Int, Int)]) {
repeatFor(init) { xy =>
population(xy._1)(xy._2) = 1
}
}
def initPattern = ArrayBuffer((0, 0), (1, 0), (0, 1))
initPopulation(initPattern)
drawGrid()
drawPopulation()
timer(500) {
erasePictures()
updatePopulation()
drawGrid()
drawPopulation()
}
Q1a. Read through the code above and try to understand what it does. What does the above code do? How does it do it?
Exploration
Make changes to the evolveCell
command in the code above to play with different cellular automata simulations.
Exercise
Change the evolveCell
command to implement Conway’s game of life. The cell rules (from Wikipedia) are the following:
- Any live cell with two or three live neighbours survives.
- Any dead cell with three live neighbours becomes a live cell.
- All other live cells die in the next generation. Similarly, all other dead cells stay dead.
Copyright © 2010–2024 Kogics Foundation. Licensed as per Terms of Use.