Game of life in F# with accelerator
- by jpalmer
I'm trying to write life in F# using accelerator v2, but for some odd reason my output isn't square despite all my arrays being square - It appears that everything but a rectangular area in the top left of the matrix is being set to false. I've got no idea how this could be happening as all my operations should treat the entire array equally. Any ideas?
open Microsoft.ParallelArrays
open System.Windows.Forms
open System.Drawing
type IPA = IntParallelArray
type BPA = BoolParallelArray
type PAops = ParallelArrays
let RNG = new System.Random()
let size = 1024
let arrinit i = Array2D.init size size (fun x y -> i)
let target = new DX9Target()
let threearr = new IPA(arrinit 3)
let twoarr = new IPA(arrinit 2)
let onearr = new IPA(arrinit 1)
let zeroarr = new IPA(arrinit 0)
let shifts = [|-1;-1|]::[|-1;0|]::[|-1;1|]::[|0;-1|]::[|0;1|]::[|1;-1|]::[|1;0|]::[|1;1|]::[]
let progress (arr:BPA) = let sums = shifts //adds up whether a neighbor is on or not
|> List.fold (fun (state:IPA) t ->PAops.Add(PAops.Cond(PAops.Rotate(arr,t),onearr,zeroarr),state)) zeroarr
PAops.Or(PAops.CompareEqual(sums,threearr),PAops.And(PAops.CompareEqual(sums,twoarr),arr)) //rule for life
let initrandom () = Array2D.init size size (fun x y -> if RNG.NextDouble() > 0.5 then true else false)
type meform () as self=
inherit Form()
let mutable array = new BoolParallelArray(initrandom())
let timer = new System.Timers.Timer(1.0) //redrawing timer
do base.DoubleBuffered <- true
do base.Size <- Size(size,size)
do timer.Elapsed.Add(fun _ -> self.Invalidate())
do timer.Start()
let draw (t:Graphics) =
array <- array |> progress
let bmap = new System.Drawing.Bitmap(size,size)
target.ToArray2D array
|> Array2D.iteri (fun x y t ->
if not t then bmap.SetPixel(x,y,Color.Black))
t.DrawImageUnscaled(bmap,0,0)
do self.Paint.Add(fun t -> draw t.Graphics)
do Application.Run(new meform())