Skip to content

Commit c269346

Browse files
committed
wip
1 parent c6f68d2 commit c269346

File tree

3 files changed

+122
-48
lines changed

3 files changed

+122
-48
lines changed

src/Examples/Component Examples/Examples.GeneticAlgorithm/Lib/Population.fs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,25 @@ module Population =
1313
let simulateFirstGeneration states random =
1414
buildInitialPopulation random |> simulateGeneration states
1515

16-
let mutateBrains (random: System.Random, brains: ActorChromosome[]): ActorChromosome[] =
16+
let mutateBrains (random: System.Random, brains: ActorChromosome list): ActorChromosome list =
1717
let numBrains = brains.Length
18-
let survivors = [| brains.[0]; brains.[1]; |]
19-
let randos = Seq.init (numBrains - 4) (fun _ -> Genes.getRandomChromosome random) |> Seq.toArray
18+
let survivors = [ brains.[0]; brains.[1]; ]
19+
let randos = Seq.init (numBrains - 4) (fun _ -> Genes.getRandomChromosome random) |> Seq.toList
2020

21-
let children = [|
21+
let children = [
2222
Genes.createChild(random, survivors.[0].genes, survivors.[1].genes, 0.25);
2323
Genes.createChild(random, survivors.[0].genes, survivors.[1].genes, 0.5);
24-
|]
24+
]
2525

26-
Array.append children randos |> Array.append survivors
26+
List.append children randos |> List.append survivors
2727

28-
let mutateAndSimulateGeneration (random: System.Random, worlds: World[], results: SimulationResult[]) =
29-
let brains = Seq.map (fun b -> b.brain) results |> Seq.toArray
28+
let mutateAndSimulateGeneration (random: System.Random, worlds: World list, results: SimulationResult list) =
29+
let brains = Seq.map (fun b -> b.brain) results |> Seq.toList
3030
mutateBrains(random, brains) |> simulateGeneration worlds
3131

32-
let mutateAndSimulateMultiple (random: System.Random, worlds: World[], generations: int, results: SimulationResult[]) =
32+
let mutateAndSimulateMultiple (random: System.Random, worlds: World list, generations: int, results: SimulationResult list) =
3333
let mutable currentResults = results
3434
for _ = 1 to generations do
35-
let brains = Seq.map (fun b -> b.brain) currentResults |> Seq.toArray
36-
currentResults <- mutateBrains(random, brains) |> simulateGeneration worlds |> Seq.toArray
35+
let brains = Seq.map (fun b -> b.brain) currentResults |> Seq.toList
36+
currentResults <- mutateBrains(random, brains) |> simulateGeneration worlds |> Seq.toList
3737
currentResults

src/Examples/Component Examples/Examples.GeneticAlgorithm/Program.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type App() =
2121
match this.ApplicationLifetime with
2222
| :? IClassicDesktopStyleApplicationLifetime as desktopLifetime ->
2323
let mainWindow = MainWindow()
24-
//mainWindow.Renderer.DrawDirtyRects <- true
24+
mainWindow.Renderer.DrawDirtyRects <- true
2525
desktopLifetime.MainWindow <- mainWindow
2626
| _ -> ()
2727

src/Examples/Component Examples/Examples.GeneticAlgorithm/Views.fs

Lines changed: 110 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace Examples.GeneticAlgorithm
22

33
open System
4+
open System.Collections
45
open Avalonia.Controls
56
open Avalonia.Controls.Primitives
67
open Avalonia.Controls.Shapes
@@ -12,7 +13,8 @@ open Avalonia.FuncUI
1213
open Examples.GeneticAlgorithm.Lib
1314

1415
type StateStore =
15-
{ ShowHeatMap: IWritable<bool>
16+
{ Random: Random
17+
ShowHeatMap: IWritable<bool>
1618
Worlds: IWritable<World list>
1719
Squirrels: IWritable<SimulationResult list>
1820

@@ -25,6 +27,16 @@ type StateStore =
2527
SelectedGameStateIdx: IWritable<int>
2628
SelectedGameState: IReadable<GameState option> }
2729

30+
member this.NextGeneration () : unit =
31+
let brains =
32+
this.Squirrels.Current
33+
|> List.map (fun squirrel -> squirrel.brain)
34+
35+
let brains = Population.mutateBrains(this.Random, brains)
36+
let generation = Population.simulateGeneration this.Worlds.Current brains
37+
38+
this.Squirrels.Set (List.ofSeq generation)
39+
2840
static member Init () =
2941
let seed = Random 42
3042
let worlds = WorldGeneration.makeWorlds(seed, 10)
@@ -68,12 +80,15 @@ type StateStore =
6880
|> Option.defaultValue List.empty
6981
)
7082
|> State.readTryFindByKey (fun (idx, _) -> idx) selectedGameStateIdx
71-
|> State.readMap (fun world ->
72-
world
83+
|> State.readMap (fun gameState ->
84+
printfn $"game state changed {gameState}"
85+
86+
gameState
7387
|> Option.map snd
7488
)
7589

76-
{ ShowHeatMap = showHeatMap
90+
{ Random = seed
91+
ShowHeatMap = showHeatMap
7792
Worlds = worlds
7893
Squirrels = population
7994
SelectedSquirrelId = selectedSimulationResultId
@@ -109,7 +124,7 @@ type Views =
109124
(* Next Generation *)
110125
Button.create [
111126
Button.content "Next Generation"
112-
Button.onClick ignore
127+
Button.onClick (ignore >> StateStore.shared.NextGeneration)
113128
]
114129

115130
(* Next 10 Generation *)
@@ -198,19 +213,39 @@ type Views =
198213
UniformGrid.columns world.MaxX
199214
UniformGrid.rows world.MaxY
200215
UniformGrid.children [
201-
for x = 0 to world.MaxX - 1 do
202-
for y = 0 to world.MaxY - 1 do
216+
(* world cords state at 1 *)
217+
for x = 1 to world.MaxX do
218+
for y = 1 to world.MaxY do
203219
let actor =
204220
world.Actors
205221
|> Array.tryFind (fun actor -> actor.Pos.X = x && actor.Pos.Y = y)
206222

207223
match actor with
208224
| Some actor ->
209-
Rectangle.create [
210-
Rectangle.row y
211-
Rectangle.column x
212-
Rectangle.fill "red"
213-
Rectangle.margin (2.0, 2.0)
225+
ContentControl.create [
226+
ContentControl.row y
227+
ContentControl.column x
228+
ContentControl.margin (2.0, 2.0)
229+
ContentControl.background "#27ae60"
230+
ContentControl.fontSize 24.0
231+
ContentControl.verticalContentAlignment VerticalAlignment.Center
232+
ContentControl.horizontalContentAlignment HorizontalAlignment.Center
233+
234+
yield! [
235+
match actor.ActorKind with
236+
| ActorKind.Acorn ->
237+
ContentControl.content "🌰"
238+
| ActorKind.Squirrel true ->
239+
ContentControl.content "🐿🌰"
240+
| ActorKind.Squirrel false ->
241+
ContentControl.content "🐿"
242+
| ActorKind.Tree ->
243+
ContentControl.content "🌲"
244+
| ActorKind.Rabbit ->
245+
ContentControl.content "🐇"
246+
| ActorKind.Doggo ->
247+
ContentControl.content "🐕"
248+
]
214249
]
215250
| None ->
216251
Rectangle.create [
@@ -231,41 +266,80 @@ type Views =
231266
TextBlock.text "No Game State Selected"
232267
] :> _
233268
)
234-
static member worldView (simulationResult: IReadable<SimulationResult>) =
269+
static member simulationView () =
235270
Component.create ("content-view", fun ctx ->
236-
let showHeatMap = ctx.usePassedStateReadOnly StateStore.shared.ShowHeatMap
237-
let simulationResult = ctx.usePassedStateReadOnly simulationResult
271+
let worldResult = ctx.usePassedStateReadOnly StateStore.shared.SelectedWorldResult
272+
let gameStateIdx = ctx.usePassedState StateStore.shared.SelectedGameStateIdx
273+
274+
match worldResult.Current with
275+
| Some worldResult ->
276+
DockPanel.create [
277+
DockPanel.lastChildFill true
278+
DockPanel.children [
279+
DockPanel.create [
280+
DockPanel.dock Dock.Bottom
281+
DockPanel.children [
282+
283+
Slider.create [
284+
Slider.dock Dock.Top
285+
Slider.minimum (double 0)
286+
Slider.maximum (double (worldResult.states.Length - 1))
287+
Slider.tickFrequency (double 1)
288+
Slider.value (double gameStateIdx.Current)
289+
Slider.onValueChanged (fun value ->
290+
gameStateIdx.Set (int value)
291+
)
292+
]
238293

239-
DockPanel.create [
240-
DockPanel.children [
241-
Views.selectedGameStateView ()
242-
]
294+
StackPanel.create [
295+
StackPanel.dock Dock.Top
296+
StackPanel.children [
297+
TextBlock.create [
298+
TextBlock.text $"world score: {worldResult.score}"
299+
]
300+
301+
TextBlock.create [
302+
TextBlock.text (
303+
let state =
304+
match int (List.last worldResult.states).SimState with
305+
| 0 ->
306+
"running"
307+
| 1 ->
308+
"won"
309+
| 2 ->
310+
"lost"
311+
| _ ->
312+
"unknown"
313+
314+
$"result: {state}"
315+
)
243316

244-
] :> IView
317+
318+
319+
]
320+
]
321+
322+
]
323+
]
324+
]
325+
326+
Views.selectedGameStateView ()
327+
]
328+
329+
] :> IView
330+
| None ->
331+
TextBlock.create [
332+
TextBlock.text "No World Result Selected"
333+
] :> IView
245334
)
246335

247336
static member contentView () =
248337
Component.create ("content-view", fun ctx ->
249-
let selected = ctx.usePassedState StateStore.shared.SelectedSquirrel
250-
251338

252339
DockPanel.create [
253340
DockPanel.lastChildFill true
254341
DockPanel.children [
255-
match selected.Current with
256-
| Some _ ->
257-
let s =
258-
selected
259-
|> State.readMap (fun s -> s.Value)
260-
|> ctx.usePassedStateReadOnly
261-
262-
Views.worldView s
263-
264-
| None ->
265-
TextBlock.create [
266-
TextBlock.text "no inhabitant selected"
267-
]
268-
342+
Views.simulationView ()
269343
]
270344
]
271345
:> IView

0 commit comments

Comments
 (0)