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
- 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.