📜 ⬆️ ⬇️

Conway's life on F # + OpenGL

Why f #?



Just because I like him. Having solved a couple of dozens of tasks on a projecteuler, I decided to find a more practical application of knowledge and write something not complicated, but tangible.

Who cares - welcome under cat.

Immediately make a reservation. I am not a specialist in the field of functional programming or OpenGL, so I will be glad to any meaningful comments and tips on how to make better / faster / more beautiful.

Describe the language itself does not make sense. Already have a lot of material on the topic.
You can, for starters, visit the Wiki , F # Development Center , What's new in F # 3.0 .
')

So let's get started


First, we define the types for our cell:
type Sex = |Male|Female type Cell = { Sex: Sex; Age: int; Position: (int * int)} 


We will use the floor when drawing cells. In the future, I plan to use it to experiment with the algorithm.
Let's declare global game variables:
 //Globals let mutable (field:Cell[]) = [||] //   let mutable pause = false //   let mutable isInProc = false // ,    let mutable generation = 0 //  let mutable ftime = DateTime.Now // let mutable fps = 0.0 //     fps //   openGL let mutable modelview = Matrix4.LookAt(Vector3.UnitZ, Vector3.Zero, Vector3.UnitY) let mutable Size = 100 //  let mutable CellCount = 2000 //   let mutable LifeLength = 50 //   let mutable ScreenWidth = 500 //    


The main class responsible for gameplay


First of all, we will write methods for generating new cells:
 type Life() = member this.genCell (rnd:Random) = { Sex = match rnd.Next(2) with |0 -> Sex.Male |_ -> Sex.Female Age=0 Position=(rnd.Next(Size), rnd.Next(Size))} member this.genCells = let rnd = new System.Random() let rec lst (l:list<Cell>) = match l.Length with |c when c = CellCount -> l |_ -> match this.genCell rnd with |c when not (this.existCell (l |> List.toArray) c.Position) -> lst (c::l) |_ -> lst l List.Empty |> lst |> List.toArray 

genCell creates a new cell using the Random object.
genCells fills the list with new cells.
Recursive function
 let rec lst (l:list)        ,   . 

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

 let rec lst (l:list)        ,   . 

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

 let rec lst (l:list)        ,   . 

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

 let rec lst (l:list)        ,   . 

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

  1. let rec lst (l:list) , .

    :
    member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

    2 :
    nCells point
    ! , , , «» .

    :
    member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
    .

    member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
    Partitionfield tuple .
    pFree, pExist

    , :
    member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
    :
    , (freeNeighb) , (- = 3) (born) , 2

    , OpenGL , .. .
    2 :
    doNextStep
    , :
    member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
    OnRenderFrame
    OpenGL, :
    override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

    , , LifeLength:
    member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

    . , :
    member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

    :
    image
    - :



    .
    :)
    "" , /

    bitbucket
    !.

    Upd: . :)

  2. let rec lst (l:list) , .

    :
    member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

    2 :
    nCells point
    ! , , , «» .

    :
    member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
    .

    member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
    Partitionfield tuple .
    pFree, pExist

    , :
    member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
    :
    , (freeNeighb) , (- = 3) (born) , 2

    , OpenGL , .. .
    2 :
    doNextStep
    , :
    member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
    OnRenderFrame
    OpenGL, :
    override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

    , , LifeLength:
    member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

    . , :
    member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

    :
    image
    - :



    .
    :)
    "" , /

    bitbucket
    !.

    Upd: . :)

  3. let rec lst (l:list) , .

    :
    member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

    2 :
    nCells point
    ! , , , «» .

    :
    member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
    .

    member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
    Partitionfield tuple .
    pFree, pExist

    , :
    member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
    :
    , (freeNeighb) , (- = 3) (born) , 2

    , OpenGL , .. .
    2 :
    doNextStep
    , :
    member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
    OnRenderFrame
    OpenGL, :
    override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

    , , LifeLength:
    member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

    . , :
    member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

    :
    image
    - :



    .
    :)
    "" , /

    bitbucket
    !.

    Upd: . :)

  4. let rec lst (l:list) , .

    :
    member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

    2 :
    nCells point
    ! , , , «» .

    :
    member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
    .

    member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
    Partitionfield tuple .
    pFree, pExist

    , :
    member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
    :
    , (freeNeighb) , (- = 3) (born) , 2

    , OpenGL , .. .
    2 :
    doNextStep
    , :
    member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
    OnRenderFrame
    OpenGL, :
    override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

    , , LifeLength:
    member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

    . , :
    member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

    :
    image
    - :



    .
    :)
    "" , /

    bitbucket
    !.

    Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

 let rec lst (l:list)        ,   . 

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

 let rec lst (l:list)        ,   . 

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

 let rec lst (l:list)        ,   . 

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

 let rec lst (l:list)        ,   . 

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

let rec lst (l:list) , .

:
member this.allNeighbourCells (position:int*int) = let nCells (point:int*int) = let x,y = point [| (x-1, y-1); (x-1, y); (x-1, y+1); (x, y-1); (x, y+1); (x+1, y-1); (x+1, y); (x+1, y+1); |] let (!) pos = let tx = match fst pos with |x when x < 0 -> Size - 1 |x when x >= Size -> 0 |_ -> fst pos let ty = match snd pos with |y when y < 0 -> Size - 1 |y when y >= Size -> 0 |_ -> snd pos (tx, ty) nCells position |> Array.map ((!))

2 :
nCells point
! , , , «» .

:
member this.existCell field c = field |> Array.exists (fun af -> c = af.Position)
.

member this.partitionfield field = this.allNeighbourCells >> Array.partition(fun c -> this.existCell field c) member this.pFree field = this.partitionfield field >> snd member this.pExist field = this.partitionfield field >> fst
Partitionfield tuple .
pFree, pExist

, :
member this.Iterate (field:Cell[]) = // let freeNeighb = field |> PSeq.collect (fun c -> this.pFree field c.Position) |> Seq.distinct let born = freeNeighb |> Seq.filter (fun c -> this.pExist field c |> Array.length = 3) |> Seq.map(fun c -> let rnd = new System.Random() {this.genCell(rnd) with Position = c}) let alive = field |> PSeq.filter(fun c -> let neighb = this.pExist field c.Position |> Array.length neighb <= 3 && neighb >= 2) |> PSeq.map (fun c -> {c with Age = (c.Age + 1)}) let res = alive |> Seq.append born |> Seq.toArray res
:
, (freeNeighb) , (- = 3) (born) , 2

, OpenGL , .. .
2 :
doNextStep
, :
member this.doNextStep = async{ let res = (this.life.Iterate field) field <- res |> Array.filter(fun c -> c.Age < LifeLength) isInProc <- false generation <- generation + 1 let delta = DateTime.Now - ftime ftime <- DateTime.Now fps <- Math.Round ((fps + 1000.0 / delta.TotalMilliseconds) / 2.0, 1) }
OnRenderFrame
OpenGL, :
override o.OnRenderFrame(e) = base.OnRenderFrame e match (pause, isInProc) with | (false, false) -> isInProc <- true; Async.Start(o.doNextStep) | _ -> () GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit) GL.MatrixMode(MatrixMode.Modelview) GL.LoadMatrix(&modelview) field |> Seq.iter (fun c -> o.DrawCell c) if not pause then base.Title <- String.Format("F# Life cell count: {0} Generation: {1} FPS: {2}", (field |> Seq.length), generation, fps) else base.Title <- String.Format("F# Life cell count: {0} Generation: {1} Paused", (field |> Seq.length), generation) base.SwapBuffers()

, , LifeLength:
member this.doNextStep = .... field <- res |> Array.filter(fun c -> c.Age < LifeLength ...

. , :
member this.DrawCell (cell:Cell) = let cellWidth = float32(this.ClientSize.Width) / float32 Size let alpha = match (1.f - float32 cell.Age / float32 LifeLength) with |c when c < 0.f -> 0.f | c -> c let color = match cell.Sex with |Male -> [|0.5f; 0.f; 0.f; alpha|] |Female -> [|0.7f; 0.f; 0.f; alpha|] let pos = (float32 (fst cell.Position) * cellWidth, float32 (snd cell.Position) * cellWidth) GL.Begin(BeginMode.Triangles) GL.Color4 (color) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(fst pos + 0.5f, snd pos + 0.5f, 1.f) GL.Vertex3(cellWidth + fst pos - 0.5f, cellWidth + snd pos - 0.5f, 1.f) GL.End()

:
image
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

Source: https://habr.com/ru/post/173419/


All Articles