The Game of Life rules are very simple. You start with a randomly generated grid of cells (some ‘[a]live’ and some ‘dead’).What happens next is decided by the following rules:
* 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.
I attempted a basic version of the Game of Life in Excel with VBA and a 30×30 grid, but it was very very slow.
My second iteration was much faster and allowed for a much larger grid as pictured below.
This was primarily achieved just by turning off screen updating while the values of the newly enlarged 100×100 cell grid was updated.
This led to my final iteration of the project…a 200×200 grid which would evolve 2-3 times per second. That is 40,000 cells being calculated and updated a couple of times every second.
The VBA code used to generate the final 200×200 iteration of the Game of Life is given below:
Sub TheGameOfLife3()
' reading in and writing out arrays to the worksheet is MUCH faster
' than reading the individual cells in a for loop etc.
Dim row As Integer
Dim column As Integer
Dim x As Integer
Dim y As Integer
Dim cellValue As Integer
Dim numNeighbours As Integer
Dim totalLifeFound As Integer
' The values in the Picture - 2d array accessed by thePicture(row,column)
Dim thePicture() As Variant
' initialise thePicture to set the size
thePicture = Worksheets("GOL-3").Range("B2:gt201").value
' Set the size of the 2d square array.
Const dimensions = 200
' Number of iterations to run for.
Const numIterations = 100
' Array to store the number of neighbours for every cell.
Dim neighboursArray(1 To dimensions, 1 To dimensions) As Integer
' Array to store the next generation of cells
Dim nextGeneration(1 To dimensions, 1 To dimensions) As Variant
' Start with calculations turned off.
Application.Calculation = xlManual
' Initialise thePicture cells with either 0 or 1 - randomly 85/15
For row = 1 To dimensions
For column = 1 To dimensions
randNumber = Application.WorksheetFunction.RandBetween(1, 100)
If randNumber >= 1 And randNumber <= 15 Then
thePicture(row, column) = 1
Else
thePicture(row, column) = 0
End If
'thePicture(row, column) = Application.WorksheetFunction.RandBetween(0, 1)
Next column
Next row
' Display what we have generated.
Range("B2:cw101").value = thePicture
' Loop through for a certain number of iterations/generations.
For Z = 1 To numIterations
' THE GAME OF LIFE - take the neighbours array and decide for each cell
' whether it will be alive or dead in the next generation.
totalLifeFound = 0
For row = 1 To dimensions
For column = 1 To dimensions
' Find our how many neighbours each of the cells has
numNeighbours = hmn(row, column, thePicture, dimensions)
' Any live cell with two or three live neighbours survives
' but the rest die.
If thePicture(row, column) = 1 Then
If numNeighbours >= 2 And numNeighbours <= 3 Then
nextGeneration(row, column) = 1
Else
nextGeneration(row, column) = 0
End If
End If
' Any dead cell with Exactly three live neighbours becomes a live cell
' but the rest stay dead.
If thePicture(row, column) = 0 Then
If numNeighbours = 3 Then
nextGeneration(row, column) = 1
Else
nextGeneration(row, column) = 0
End If
End If
Next column
Next row
' Make thePicture equal to the just generated nextGeneration
thePicture = nextGeneration
' Finally we update the display with the next generation data.
Range("B2:gt201").value = thePicture
Next Z
End Sub
' Function to count how many neighbours surround a particular cell…with NO wrap around.
Function hmn(row As Integer, column As Integer, ByRef thePicture() As Variant, dimensions As Integer) As Integer
hmn = 0
' top left corner
y = row - 1
x = column - 1
If y <= 0 Then y = dimensions
If x <= 0 Then x = dimensions
hmn = hmn + thePicture(y, x)
' top middle
y = row - 1
x = column
If y <= 0 Then y = dimensions
hmn = hmn + thePicture(y, x)
' top right
y = row - 1
x = column + 1
If y <= 0 Then y = dimensions
If x > dimensions Then x = 1
hmn = hmn + thePicture(y, x)
' middle left
y = row
x = column - 1
If x <= 0 Then x = dimensions
hmn = hmn + thePicture(y, x)
' middle right
y = row
x = column + 1
If x > dimensions Then x = 1
hmn = hmn + thePicture(y, x)
' bottom left corner
y = row + 1
x = column - 1
If y > dimensions Then y = 1
If x <= 0 Then x = dimensions
hmn = hmn + thePicture(y, x)
' bottom middle
y = row + 1
x = column
If y > dimensions Then y = 1
hmn = hmn + thePicture(y, x)
' bottom right corner
y = row + 1
x = column + 1
If y > dimensions Then y = 1
If x > dimensions Then x = 1
hmn = hmn + thePicture(y, x)
End Function