User:Pluke/gameoflife

From Wikibooks, open books for an open world
Jump to navigation Jump to search

CC3.0 from: http://community.computingatschool.org.uk/resources/281#likes

Conway’s Game of Life[edit | edit source]

Conway was a Computer Scientist in the 1970s, he was interested in simulating life of simple bacteria colonies. The "game" has no players, its evolution is determined by its initial state. You setup an initial configuration, or seed, and watch it evolve. In order to write the Game of Life, you need to do the following:

  1. Define a large 2D array, in which your individual cells will be either alive or dead. This is their world.
  2. Populate a few small areas with small groups of cells, initially statically. This is your seed, different seeds have different effects.
  3. Write a subroutine that looks at each cell in the world and determines whether or not that particular cell will be alive or not using the following rules:
  4. Any live cell with fewer than two live neighbours dies, loneliness.
  5. Any live cell with two or three live neighbours lives on to the next generation.
  6. Any live cell with more than three live neighbours dies, overcrowding.
  7. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

The tricky bit comes when you have to look at each cell in turn and then look at each of its neighbours. That is fine for cells in the middle of the world, however you must cope with the edges too. HINT: ignore elements that would be outside your world. In the diagram below, we are looking at the centre cell, it’s not on any edge. It has 3 live neighbours. So it becomes live ( even if it was empty before, or not ). HINT: You will need a separate temporary array to place your newly calculated values in…

  1. There should be a user-defined limit to the number of times the simulation goes around.
  2. The user will want to see how many times the simulation has been run, and the total number of living cells.
  3. Try a selection of seeds and see what happens. For example:

EXTENSION[edit | edit source]

  1. Automatically generate random seeds.
  2. Can you find any stable seed patterns?
  3. Can you find any oscillating seed patterns?
  4. Can you alter the rules to get a life-like growth that doesn’t just die? Hint try using another birth from more neighbours.
Imports System.Console
Imports System.Threading

Module Life

    'The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square cells, each of which 
    'is in one of two possible states, alive or dead. Every cell interacts with its eight neighbours, which are the 
    'cells that are horizontally, vertically, or diagonally adjacent. At each step in time, the following transitions 
    'occur:
    ' 1.Any live cell with fewer than two live neighbours dies, as if caused by under-population.
    ' 2.Any live cell with two or three live neighbours lives on to the next generation.
    ' 3.Any live cell with more than three live neighbours dies, as if by overcrowding.
    ' 4.Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

    'The initial pattern constitutes the seed of the system. The first generation is created by applying the above rules 
    'simultaneously to every cell in the seed—births and deaths occur simultaneously, and the discrete moment at which 
    'this happens is sometimes called a tick (in other words, each generation is a pure function of the preceding one). 
    'The rules continue to be applied repeatedly to create further generations.

    Const SIZE_ROW = 78
    Const SIZE_COL = 88
    Const MAX_LIFE = 400
    Const MAX_TIME = 50

    Enum eCell
        dead = 0
        alive = 1
    End Enum


    Sub Main()
        Dim grid(SIZE_ROW, SIZE_COL) As Integer
        Dim choice As Integer = 0
        Dim year As Integer = 0
        Dim colonySize As Integer = 0
        Dim lifeMax As Integer = MAX_LIFE
        Dim timeInterval As Integer = MAX_TIME
        Console.SetWindowSize(SIZE_COL + 2, SIZE_ROW + 2)
        Do
            choice = menu()
            Select Case choice
                Case 1
                Case 2
                    WriteLine("Please enter new life limit.  Limit is currently {0} years.", lifeMax)
                    lifeMax = CInt(ReadLine())
                Case 3
                    WriteLine("Please enter new time interval.  Intveral is currently {0} ms.", timeInterval)
                    'timeInterval = CInt(ReadLine())
                Case 4
                Case 5
                    'play game
                    initgrid(grid)
                    seed(grid)
                    drawgrid(grid, year, colonySize)
                    For year = 0 To lifeMax
                        colonySize = processLife(grid)
                        'Thread.Sleep(timeInterval)
                        drawgrid(grid, year, colonySize)
                    Next
                Case 6
                Case Else
                    WriteLine("invalid choice.")
            End Select
        Loop Until choice = -1

    End Sub

    Sub initgrid(ByRef g(,) As Integer)
        Dim i, j As Integer
        For i = 0 To SIZE_ROW - 1
            For j = 0 To SIZE_COL - 1
                g(i, j) = eCell.dead
            Next
        Next
    End Sub

    Sub seed(ByRef g(,) As Integer)
        'simple X type seed, in a set location
        g(0, 0) = eCell.alive
        g(1, 2) = eCell.alive
        g(0, 2) = eCell.alive
        g(1, 1) = eCell.alive
        g(2, 0) = eCell.alive
        g(2, 1) = eCell.alive
        g(2, 2) = eCell.alive

        g(5, 5) = eCell.alive
        g(5, 7) = eCell.alive
        g(6, 6) = eCell.alive
        g(7, 5) = eCell.alive
        g(7, 6) = eCell.alive
        g(7, 7) = eCell.alive


        g(15, 15) = eCell.alive
        g(16, 16) = eCell.alive
        g(17, 15) = eCell.alive

        g(35, 14) = eCell.alive
        g(35, 16) = eCell.alive
        g(35, 15) = eCell.alive

        g(25, 15) = eCell.alive
        g(27, 16) = eCell.alive
        g(26, 16) = eCell.alive
        g(25, 17) = eCell.alive

    End Sub

    Function processLife(ByRef g(,) As Integer) As Integer
        Dim colonysize As Integer = 0
        Dim tgt(SIZE_ROW, SIZE_COL) As Integer ' temporary grid for calculated results
        For i = 0 To SIZE_ROW - 1
            For j = 0 To SIZE_COL - 1

                Select Case neighbourCount(g, i, j)
                    Case Is < 2
                        tgt(i, j) = eCell.dead
                    Case Is = 2
                        tgt(i, j) = g(i, j)
                        'change nothing here
                    Case Is = 3
                        tgt(i, j) = eCell.alive
                        'Case Is = 4
                        '    g(i, j) = eCell.alive
                    Case Is > 3
                        tgt(i, j) = eCell.dead
                    Case Else
                        WriteLine("invalid value")
                End Select
                If tgt(i, j) = eCell.alive Then colonysize += 1
            Next
        Next
        g = tgt
        Return colonysize
    End Function

    

Function neighbourCount(ByRef g(,) As Integer, ByVal i As Integer, ByVal j As Integer) As Integer
        Dim count As Integer = 0
        Dim m, n As Integer
        For m = i - 1 To i + 1
            If m > -1 And m < SIZE_ROW + 1 Then 'ignore out of bounds
                For n = j - 1 To j + 1
                    If n > -1 And n < SIZE_COL + 1 Then 'ignore out of bounds
                        If g(m, n) = eCell.alive Then
                            count += 1
                        End If
                    End If
                Next
            End If
        Next
        If g(i, j) = eCell.alive Then
            count -= 1
        End If
        Return count
    End Function

    Sub drawgrid(ByRef g(,) As Integer, ByVal year As Integer, ByVal size As Integer)
        Dim i, j As Integer
        Console.ForegroundColor = ConsoleColor.White
        'Console.BackgroundColor = ConsoleColor.Black
        Console.Clear()
        Console.WriteLine("Year: {0}  Colony Size : {1}", year, size)
        Console.ForegroundColor = ConsoleColor.Green
        'Console.BackgroundColor = ConsoleColor.DarkGray
        For i = 0 To SIZE_ROW - 1
            For j = 0 To SIZE_COL - 1
                Select Case g(i, j)
                    Case 0
                        Console.BackgroundColor = ConsoleColor.Black
                        Write(" ")
                    Case 1
                        Console.BackgroundColor = ConsoleColor.Green
                        Write(" ")
                End Select
            Next
            WriteLine()
        Next
        Console.BackgroundColor = ConsoleColor.Black
    End Sub

    Function menu() As Integer
        Dim value As Integer
        Console.BackgroundColor = ConsoleColor.Black
        Console.Clear()
        Console.ForegroundColor = ConsoleColor.White
        WriteLine()
        WriteLine("++++++++++++++++")
        WriteLine("+ GAME OF LIFE +")
        WriteLine("++++++++++++++++")
        WriteLine()
        WriteLine("Options : - ")
        WriteLine(" 1 random seed ")
        WriteLine(" 2 change simulation year limit ")
        WriteLine(" 3 change time interval for year ")
        WriteLine(" 4 change number of seeds ")
        WriteLine(" 5 start ")
        WriteLine(" -1 quit ")
        WriteLine()
        WriteLine("Please enter choice:")
        value = CInt(ReadLine())
        Return value

    End Function

End Module