Visual Basic 2010 (Windows) Guide
Conway's Game Of Life:Basic Application

Step 1 - Set Up the Form

Start by creating a new Windows Application. Add a PictureBox to the form and name it picLife. Change its size property to 640, 640.

Add a menu strip to the top of the form. Create a File menu and add the following menu items to it,

  • Open Input File
  • Save Input
  • Save Grid As Image
  • -- Separator --
  • Exit
Add a toolstrip just beneath the menu and add buttons with the following text,
  • Go
  • Stop
  • Clear
  • Restore Input

Add 2 labels to the toolstrip and change their names in the properties window to,

  • lblGenerations
  • lblStatus

Add a timer to the form. Name it tmrLife, set its interval to 500.

Step 2 - Global Variables

We will need the following global variables to keep track of the state of each cell in the grid, the input given, the number of generations and whether or not there has been a change since the previous generation.

Dim grid(63, 63) As Boolean
Dim input(63, 63) As Boolean
Dim generations As Integer = 0
Dim change As Boolean = False

Step 3 - Setting Up The Grid

Double click on the empty space on the form to bring up the Form_Load event handler. You need the following lines to set up the cells,

For i As Integer = 0 To 63
   For j As Integer = 0 To 63
      grid(i, j) = False
   Next
Next

Step 3 - Drawing The Grid

The drawing of the grid takes place in the Paint event for the picLife PictureBox. You can create this event by looking in the properties window for picLife, clicking the lightning to bring up a list of events and double clicking on the Paint.

Dim g As Graphics = e.Graphics
g.Clear(Color.White)
g.PageUnit = GraphicsUnit.Pixel
Dim rect As Rectangle
For i As Integer = 10 To 640 Step 10
   g.DrawLine(Pens.Black, 0, i, 640, i)
   g.DrawLine(Pens.Black, i, 0, i, 640)
Next
For i As Integer = 0 To 63
   For j As Integer = 0 To 63
      If grid(i, j) Then
         rect = New Rectangle(i * 10, j * 10, 10, 10)
         g.FillRectangle(Brushes.Black, rect)
      End If
   Next
Next

This draws the grid and colours in any live cells. Since we set all of the cells to dead in the Form_Load event, this will simply draw out the grid on the PictureBox and can be tested at this stage.

Step 4 - Allowing The User To Set The Initial Conditions

We need to be able to turn cells on and off to set up a go on the game. We do this when the Picturebox is clicked. The following code works out which cell was clicked on and changes the value of that cell to the opposite of its current value using the NOT operation. The IF statement is to make sure that the grid can't be edited whilst the Game is running.

Find the MouseClick event for the picLife Picturebox.

If Not tmrLife.Enabled Then
   Dim x As Integer = e.X \ 10
   Dim y As Integer = e.Y \ 10
   grid(x, y) = Not grid(x, y)
   picLife.Refresh()
End If

Step 5 - Calculating The Next Generation

The following procedure and function are used to work out the next generation.

Sub CalculateNextGeneration()
   Dim neighbours(63, 63) As Byte
   change = False
   For i As Integer = 0 To 63
      For j As Integer = 0 To 63
         neighbours(i, j) = CountNeighbors(i, j)
      Next
   Next
   For i As Integer = 0 To 63
      For j As Integer = 0 To 63
         If grid(i, j) = False Then
            ' dead cells
            If neighbours(i, j) = 3 Then
               ' reproduction
               grid(i, j) = True
               change = True
            End If
         Else
            ' live cells
            If neighbours(i, j) > 3 Then
               ' overcrowding
               grid(i, j) = False
               change = True
            End If
            If neighbours(i, j) < 2 Then
               ' underpopulation
               grid(i, j) = False
               change = True
            End If
         End If
      Next
   Next
End Sub

Private Function CountNeighbors(ByVal cellX As Integer, ByVal cellY As Integer) As Integer
   Dim count As Integer
   count = 0
   If cellX > 0 And cellY > 0 Then
      'if both are > 0 then I can look at
      'upper-left, upper, and left cells safely
      If grid(cellX - 1, cellY - 1) Then count += 1
      If grid(cellX, cellY - 1) Then count += 1
      If grid(cellX - 1, cellY) Then count += 1
   End If
   If cellX < 63 And cellY < 63 Then
      'if both are < GridSize then I can look at
      'lower-right, right, and lower cells safely
      If grid(cellX + 1, cellY + 1) Then count += 1
      If grid(cellX, cellY + 1) Then count += 1
      If grid(cellX + 1, cellY) Then count += 1
   End If
   If cellX > 0 And cellY < 63 Then
      If grid(cellX - 1, cellY + 1) Then count += 1
   End If
   If cellX < 63 And cellY > 0 Then
      If grid(cellX + 1, cellY - 1) Then count += 1
   End If
   Return count
End Function

Step 6 - The Ticking Clock

Double click on the timer to bring up its tick event handler. Add the following lines,

CalculateNextGeneration()
If change Then
   generations += 1
   lblGenerations.Text = "Generations: " + Str(generations)
   picLife.Refresh()
Else
   tmrLife.Enabled = False
   lblStatus.Text = "Stopped"
End If

Step 7 - Storing & Restoring The Input

The following procedures will be used to keep track of the original input for a game. This saves the user having to re-enter input to view an animation again,

Sub CopyGridToInput()
   For i As Integer = 0 To 63
      For j As Integer = 0 To 63
         input(i, j) = grid(i, j)
      Next
   Next
End Sub

Sub CopyInputToGrid()
   For i As Integer = 0 To 63
      For j As Integer = 0 To 63
         grid(i, j) = input(i, j)
      Next
   Next
End Sub

Step 8 - Starting & Stopping

Double click on the Go button and add the following code to its event handler,

If generations = 0 Then
   CopyGridToInput()
End If
tmrLife.Enabled = True
lblStatus.Text = "Animating"

Double click on the Stop button and add this code to the event handler,

tmrLife.Enabled = False
lblStatus.Text = "Stopped"

Step 9 - The Clear Button

Double click on the Clear button and add this code to the event handler,

If Not tmrLife.Enabled Then
   For i As Integer = 0 To 63
      For j As Integer = 0 To 63
         grid(i, j) = False
      Next
   Next
   generations = 0
   lblGenerations.Text = "Generations: " + Str(generations)
   picLife.Refresh()
End If

Step 10 - Restoring Input

The following code should be executed when the Restore Input button is clicked,

If Not tmrLife.Enabled Then
   generations = 0
   lblGenerations.Text = "Generations: " + Str(generations)
   CopyInputToGrid()
   picLife.Refresh()
End If

This concludes the steps involved in setting up the basic application. You should have a reasonable implementation of the Game Of Life to test at this stage.