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: . :)










All Articles