Life in Silverlight 4
Written by Mike James   
Wednesday, 07 July 2010
Article Index
Life in Silverlight 4
Data binding
User interaction
Computing Life
Trying it out

Banner

Generations

This is all we need for a design mode so time to move on to run the display.

The idea is that when the user clicks the button a timer is activated to call routines which calculate and update the array - which in turn automatically updates the Grid.

In the case of Silverlight timers can be a problem. Using WPF we can use a System timer even though it runs on a different thread to the UI because the binding update code seems to run on the UI thread irrespective of how property changes occur. In the case of Silverlight this doesn't seem to be so and we need to use a dispatch timer that does run on the same thread as the UI to avoid cross thread UI access issues.

 

First we need a timer:

private System.Windows.Threading.
DispatcherTimer timer=
new System.Windows.Threading.
DispatcherTimer();

and a Timer setup routine:


private void setupTimer()
{
timer.Interval =
new TimeSpan(0, 0, 0, 0, 200);
timer.Tick += (obj, evnt) =>
{
counter();
nextgen();
};
}

The two routines counter and nextgen have yet to be written and they apply the rules of Life to the array. Calling both computes the next generation and displays it - more of these later.

Also notice that the Elapsed delegate, called each time the Timer period is up, is set using a Lambda expression.

 

 

A call to setupTimer has to be added to the end of the Window_Loaded event handler:

 setupTimer();
}

Finally we need to write the button click handler to start and stop the timer:

private void button1_Click(
object sender, RoutedEventArgs e)
{
if (button1.Content.ToString() == "Run")
{
button1.Content= "Stop";
timer.Start();
}
else
{
button1.Content="Run";
timer.Stop();
}
}

This simply toggles the text on the button from Run to Stop and back and starts and stops the timer.

Computing Life

The counter routine is easy enough once you have worked out where the eight neighbours of the cell cells(i,j) are. The big problem is that to count the number of live cells we are going to want to use expressions such as:

cells[i - 1, j].state + cells[i + 1, j].state

but the system does not automatically cast a boolean value to an integer value and so such an expression gives an error message. There are many ways of dealing with this problem but the most interesting is to add a custom implicit cast to the Cell class that automatically converts its Type, i.e. Cell to Int. Notice we are going one step further than casting a boolean to an int - by casting Cell to int and arranging for its value to be based on its state property we are making state a default property for the Cell class.

To define the implicit cast we have to add the following method to the Cell class:

public static 
implicit operator int(Cell c)
{
return Convert.ToInt32(c.state);
}

With this addition we can simply add Cell objects together and writer counter in a straightforward way:

private void counter()
{
for (int i = 1; i < GridSize - 1; i++)
{
for (int j = 1; j < GridSize - 1; j++)
{
n[i, j] = cells[i - 1, j] +
cells[i + 1, j] +
cells[i, j - 1] +
cells[i, j + 1];
n[i, j]+= cells[i - 1, j - 1] +
cells[i + 1, j - 1] +
cells[i + 1, j + 1] +
cells[i - 1, j + 1];
}
}
}

We also need to remember to declare the array n:

private int[,] n = 
new int[GridSize, GridSize];

At the end of the routine n(i,j) contains the number of live neighbours that the cell cells(i,j) has. This information is used by nextgen to update the life array according to the rules of Life.

private void nextgen()
{
 for (int i = 1; i < GridSize - 1; i++)
{
for (int j = 1; j < GridSize - 1; j++)
 {
if(n[i, j]==3) cells[i, j].state = true;
if (n[i, j]>=4) cells[i, j].state = false;
if (n[i, j] <= 1) cells[i, j].state =false;
}
}
}

This looks complicated but you should be able to understand it if you break it down into its component parts. First there is a pair of outer loops that scan through the entire array. For each of the elements the number of neighbours n(i,j) is tested to see if there are 3, 4 or more or 1 or less. In each case the state of cells(i,j) is updated accordingly.

Banner

<ASIN:1847199763 >

<ASIN:0470534044 >

<ASIN:0470524650 >

<ASIN:1430230185 >



Last Updated ( Monday, 30 October 2023 )