John Conway’s game of life is the simplest known self-organizing system, and it is a good example of evolution. Just like evolution, the environment decides the fitness of the organism. In the case of evolution, the parameters that describe fitness are complex, and in John Conway’s game of life, they are very simple. The game consists of an area of cells. A cell with too few neighbours (none or one) dies from loneliness, a cell with too many neighbors dies from overcrowding. A cell with two or three neighbours survives and an empty space with two neighbours becomes a cell. So the game of life is an infinite iteration of applying rules and adding energy, just like the physical world is. When you start with a world with randomly added cells, and you apply the rules on the world time and time again, the cells will form structures that are more or less stable. A stable structure can be very simple or rarely very complex. If a structure is moving, it can collide with another structure and perish, or form a new structure. Some structures, stable or unstable, form new structures.
Math.com writes about John Conway’s game of life here. If you have Java installed, you will able to watch the behavior of a few stable structures.
The following source code (Visual Basic 9) illustrates how simple the games is, and please notice that there is no implementation of intelligence. Intelligence is simply not required to make complex structures. The code is written in a class that inherits from the System.Windows.Forms.Form class.
'The resources are a 2D map of bytes, a timer 'and a delegate (for technical reasons). Private World(400, 400) As Boolean Private WithEvents T As System.Timers.Timer Private Delegate Sub DrawBitmapDelegate(ByVal B As System.Drawing.Bitmap) Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load 'Start off by placing some (about 11,000) random cells in the world. Dim Rnd As New Random() For I As Integer = 0 To 11000 World(Rnd.Next(60, 341), Rnd.Next(60, 341)) = True Next 'Create a timer - one generation lasts for 20 ms. T = New System.Timers.Timer(20) AddHandler T.Elapsed, AddressOf DoGeneration T.Start() End Sub Private Sub DoGeneration(ByVal sender As Object, _ ByVal e As System.EventArgs) 'Appy the rules of the simulation on the cells in the world. ApplyRules() 'Display the world on the screen '(that is, copy to a bitmap, draw the bitmap). DrawWorld() End Sub
This makes the main program. The following code defines the functions that are called (ApplyRules and DrawWorld) followed by the functions they call in their turn.
Public Sub ApplyRules() 'Create a temporary buffer for the new world. Dim TempWorld(400, 400) As Boolean 'Apply the rules of the world to that new buffer. For Y As Integer = 0 To 400 For X As Integer = 0 To 400 Select Case CountNeighbours(X, Y) Case 0, 1 'With no or one neighbour, the 'cell dies of loneliness. TempWorld(X, Y) = False Case 2 'Two neighbours means survival. TempWorld(X, Y) = World(X, Y) Case 3 'Three neighbours: Birth of a new cell. TempWorld(X, Y) = True Case Else 'With four or more neighbours, the cell dies from overcrowding. TempWorld(X, Y) = False End Select Next Next 'Save the changes by making the temporary buffer permanent. World = TempWorld End Sub Private Sub DrawWorld() 'Let the world vector become pixels on a bitmap. Using B As New System.Drawing.Bitmap(401, 401) For Y As Integer = 0 To 400 For X As Integer = 0 To 400 If World(X, Y) Then B.SetPixel(X, Y, Color.Black) Else B.SetPixel(X, Y, Color.White) End If Next Next 'Draw the bitmap on the screen. A thread shift must be done. Dim D As New DrawBitmapDelegate(AddressOf DrawBitmap) Me.Invoke(D, B) End Using End Sub 'This method does the actual drawing, on a the GUI thread. Private Sub DrawBitmap(ByVal B As System.Drawing.Bitmap) Using G As System.Drawing.Graphics = System.Drawing.Graphics.FromHwnd(Me.Handle) 'Apply some magnification while doing the actual drawing. G.DrawImage(B, New Rectangle(0, 0, 800, 800), _ New Rectangle(0, 0, 400, 400), GraphicsUnit.Pixel) End Using End Sub Private Function CountNeighbours(ByVal X As Integer, ByVal Y As Integer) As Integer Dim Ret As Integer = 0 For NY As Integer = Y - 1 To Y + 1 For NX As Integer = X - 1 To X + 1 If Not (NY = 0 And NX = 0) Then If NY >= 0 And NY <= 400 And NX >= 0 And NX <= 400 Then If World(NX, NY) Then Ret += 1 End If End If End If Next Next Return Ret End Function
Another example is posted here.