Learning F#: The Game of Life (Vol. 7)

Intro

I am still plugging away on my F# implementation of the Game of Life. I am now at the point where I would like to see some visuals. As a result, I created a client project that consists of a view-model, a XAML file, and a value converter class.

Impediment

I am unable to launch the actual application.
I received the following warning:
“Main module of program is empty: nothing will happen when it is run”

I then added a new file and provided the following code:

module Bootstrap

open System.Windows

[<EntryPoint>]
let main args =
    Application.Current.Run() |> ignore;
    // Return 0. This indicates success.
    0

The code above still doesn’t resolve my issue though. Hence, I receive a null reference exception on Application.Current.

ViewModel

As of right now, the viewmodel class looks like the following:

namespace Client

open UILogic
open Model

type ViewModel() =
    inherit ViewModelBase()

    let rowCount = 3
    let grid = rowCount |> createGrid
                        |> setCell { X=1; Y=1; State=Alive }

    let mutable _cells = grid |> Map.toSeq
                              |> Seq.map snd
                              |> Seq.toList
    member this.Cells
        with get() = _cells 
        and set(value) =
            _cells <- value


XAML

The XAML file is hardcoded to reflect a fixed grid. Later on, I will generate a grid programmatically.

The XAML is as follows:

<Window x:Class="Client.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Client"
        Background="Black"
        Title="Game of Life" Height="450" Width="500">

    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>

    <Window.Resources>
        <local:StateToBrushConverter x:Key="StateToBrushConverter" />
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Rectangle Grid.Row="0" Grid.Column="0" Fill="{Binding Cells[0], Converter={StaticResource StateToBrushConverter}}" />
        <Rectangle Grid.Row="0" Grid.Column="1" Fill="{Binding Cells[1], Converter={StaticResource StateToBrushConverter}}" />
        <Rectangle Grid.Row="0" Grid.Column="2" Fill="{Binding Cells[2], Converter={StaticResource StateToBrushConverter}}" />
        <Rectangle Grid.Row="1" Grid.Column="0" Fill="{Binding Cells[3], Converter={StaticResource StateToBrushConverter}}" />
        <Rectangle Grid.Row="1" Grid.Column="1" Fill="{Binding Cells[4], Converter={StaticResource StateToBrushConverter}}" />
        <Rectangle Grid.Row="1" Grid.Column="2" Fill="{Binding Cells[5], Converter={StaticResource StateToBrushConverter}}" />
        <Rectangle Grid.Row="2" Grid.Column="0" Fill="{Binding Cells[6], Converter={StaticResource StateToBrushConverter}}" />
        <Rectangle Grid.Row="2" Grid.Column="1" Fill="{Binding Cells[7], Converter={StaticResource StateToBrushConverter}}" />
        <Rectangle Grid.Row="2" Grid.Column="2" Fill="{Binding Cells[8], Converter={StaticResource StateToBrushConverter}}" />
    </Grid>

</Window>

StateToBrushConverter

I need to differentiate living cells from dead cells. As a result, I added a value converter to display the color of living cells.

namespace Client
open System.Windows.Data
open Model
open System.Windows.Media
 
type StateToBrushConverter() =
    interface IValueConverter with
        member x.Convert(value, targetType, parameter, culture) = 
            let cell = value :?> Cell
            match cell.State with 
            | Alive -> SolidColorBrush(Colors.LightGreen) :> obj
            | Dead  -> SolidColorBrush(Colors.Black)      :> obj
 
        member x.ConvertBack(value, targetType, parameter, culture) = failwith "Not implemented yet"

Conclusion

I am still plugging away on my F# implementation of the Game of Life. I am now at the point where I would like to see some visuals. As a result, I created a client project that consists of a view-model, a XAML file, and a value converter class.

Leave a comment