F#+ OpenGLでのConwayの生活

なぜf#?



彼が好きだから。 projecteulerで数十のタスクを解決した後、私は知識のより実用的なアプリケーションを見つけて、複雑ではなく具体的​​なものを書くことにしました。

誰が気にします-猫へようこそ。

すぐに予約します。 私は関数型プログラミングやOpenGLの分野の専門家ではないので、それをより良く/速く/より美しくするための有意義なコメントやヒントを喜んでいます。

言語自体を記述することは意味がありません。 すでにトピックに関する多くの資料があります。
手始めに、 WikiF#開発センターF#3.0の新機能をご覧ください。

それでは始めましょう


まず、セルのタイプを決定します。
type Sex = |Male|Female type Cell = { Sex: Sex; Age: int; Position: (int * int)} 


セルをレンダリングするときに床を使用します。 将来的には、アルゴリズムの実験に使用する予定です。
ゲームのグローバル変数を宣言します。
 //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 //    


ゲームプレイを担当するメインクラス


まず、新しいセルを生成するメソッドを作成します。
 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は、Randomオブジェクトを使用して新しいセルを作成します。
genCellsは、リストに新しいセルを追加します。
再帰関数
 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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

    :
    画像
    - :



    .
    :)
    "" , /

    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()

    :
    画像
    - :



    .
    :)
    "" , /

    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()

    :
    画像
    - :



    .
    :)
    "" , /

    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()

    :
    画像
    - :



    .
    :)
    "" , /

    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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

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()

:
画像
- :



.
:)
"" , /

bitbucket
!.

Upd: . :)

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


All Articles