@reicek/neataptic-ts 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/agents/boundary-mapper.agent.md +31 -0
- package/.github/agents/docs-scout.agent.md +29 -0
- package/.github/agents/plan-scout.agent.md +31 -0
- package/.github/agents/solid-split.agent.md +143 -0
- package/.github/copilot-instructions.md +119 -0
- package/.github/skills/solid-split-playbook/SKILL.md +220 -0
- package/.github/skills/solid-split-playbook/assets/docs-checklist.md +34 -0
- package/.github/skills/solid-split-playbook/assets/split-plan-template.md +48 -0
- package/.github/skills/solid-split-playbook/assets/split-workflow-checklist.md +51 -0
- package/.github/skills/trace-analyzer-extension/SKILL.md +63 -0
- package/.github/skills/trace-analyzer-extension/assets/extension-checklist.md +24 -0
- package/.github/skills/trace-analyzer-extension/references/analyzer-extension-workflow.md +101 -0
- package/.github/skills/trace-audit-reporting/SKILL.md +96 -0
- package/.github/skills/trace-audit-reporting/assets/performance-report-template.md +123 -0
- package/.github/skills/trace-audit-reporting/references/trace-analysis-workflow.md +132 -0
- package/package.json +7 -3
- package/plans/ES2023 migration +13 -8
- package/plans/Evolution_Training_Interoperability_Contracts.md +1 -1
- package/plans/Flappy_Bird_Folder_Documentation_Pass.md +53 -0
- package/plans/Flappy_Evolution_Worker_Documentation_Pass.md +58 -0
- package/plans/Interactive_Examples_and_Learning_Path.md +10 -2
- package/plans/Memory_Optimization.md +3 -3
- package/plans/README.md +63 -0
- package/plans/Roadmap.md +15 -3
- package/plans/asciiMaze_SOLID_split.done.md +130 -0
- package/plans/flappy_bird_SOLID_split.done.md +67 -0
- package/scripts/analyze-trace.ts +590 -0
- package/scripts/assets/theme.css +221 -34
- package/scripts/copy-examples.mjs +9 -5
- package/scripts/export-onnx.mjs +3 -3
- package/scripts/generate-bench-tables.mjs +10 -10
- package/scripts/generate-bench-tables.ts +10 -10
- package/scripts/generate-docs.ts +1415 -449
- package/scripts/render-docs-html.ts +15 -8
- package/src/README.md +127 -222
- package/src/architecture/README.md +117 -184
- package/src/architecture/architect.ts +6 -0
- package/src/architecture/layer/README.md +38 -38
- package/src/architecture/network/README.md +49 -31
- package/src/architecture/network/activate/README.md +77 -77
- package/src/architecture/network/connect/README.md +15 -13
- package/src/architecture/network/deterministic/README.md +7 -7
- package/src/architecture/network/evolve/README.md +44 -44
- package/src/architecture/network/gating/README.md +20 -20
- package/src/architecture/network/genetic/README.md +51 -51
- package/src/architecture/network/mutate/README.md +97 -97
- package/src/architecture/network/network.types.ts +39 -0
- package/src/architecture/network/onnx/README.md +264 -264
- package/src/architecture/network/prune/README.md +39 -39
- package/src/architecture/network/remove/README.md +26 -26
- package/src/architecture/network/serialize/README.md +56 -56
- package/src/architecture/network/serialize/network.serialize.json.utils.ts +1 -0
- package/src/architecture/network/serialize/network.serialize.utils.ts +6 -1
- package/src/architecture/network/serialize/network.serialize.utils.types.ts +1 -1
- package/src/architecture/network/slab/README.md +61 -61
- package/src/architecture/network/standalone/README.md +24 -24
- package/src/architecture/network/stats/README.md +9 -9
- package/src/architecture/network/topology/README.md +46 -46
- package/src/architecture/network/training/README.md +21 -21
- package/src/architecture/network.ts +114 -10
- package/src/methods/README.md +9 -87
- package/src/multithreading/README.md +8 -77
- package/src/multithreading/workers/README.md +2 -2
- package/src/multithreading/workers/browser/README.md +0 -6
- package/src/multithreading/workers/node/README.md +0 -3
- package/src/neat/README.md +623 -568
- package/src/neat/neat.evolve.population.utils.ts +29 -5
- package/src/neat/neat.helpers.ts +16 -0
- package/src/neat/neat.topology-intent.utils.ts +160 -0
- package/src/utils/README.md +18 -18
- package/test/examples/asciiMaze/README.md +59 -59
- package/test/examples/asciiMaze/asciiMaze.e2e.test.ts +14 -9
- package/test/examples/asciiMaze/browser-entry/README.md +196 -0
- package/test/examples/asciiMaze/browser-entry/browser-entry.abort.services.ts +95 -0
- package/test/examples/asciiMaze/browser-entry/browser-entry.constants.ts +23 -0
- package/test/examples/asciiMaze/browser-entry/browser-entry.curriculum.services.ts +115 -0
- package/test/examples/asciiMaze/browser-entry/browser-entry.globals.services.ts +106 -0
- package/test/examples/asciiMaze/browser-entry/browser-entry.host.services.ts +157 -0
- package/test/examples/asciiMaze/browser-entry/browser-entry.services.ts +14 -0
- package/test/examples/asciiMaze/browser-entry/browser-entry.ts +129 -0
- package/test/examples/asciiMaze/browser-entry/browser-entry.types.ts +120 -0
- package/test/examples/asciiMaze/browser-entry/browser-entry.utils.ts +98 -0
- package/test/examples/asciiMaze/browser-entry.ts +10 -576
- package/test/examples/asciiMaze/dashboardManager/README.md +276 -0
- package/test/examples/asciiMaze/dashboardManager/archive/README.md +16 -0
- package/test/examples/asciiMaze/dashboardManager/archive/dashboardManager.archive.services.ts +267 -0
- package/test/examples/asciiMaze/dashboardManager/dashboardManager.constants.ts +35 -0
- package/test/examples/asciiMaze/dashboardManager/dashboardManager.services.ts +103 -0
- package/test/examples/asciiMaze/dashboardManager/dashboardManager.ts +181 -0
- package/test/examples/asciiMaze/dashboardManager/dashboardManager.types.ts +267 -0
- package/test/examples/asciiMaze/dashboardManager/dashboardManager.utils.ts +254 -0
- package/test/examples/asciiMaze/dashboardManager/live/README.md +14 -0
- package/test/examples/asciiMaze/dashboardManager/live/dashboardManager.live.services.ts +264 -0
- package/test/examples/asciiMaze/dashboardManager/telemetry/README.md +47 -0
- package/test/examples/asciiMaze/dashboardManager/telemetry/dashboardManager.telemetry.services.ts +513 -0
- package/test/examples/asciiMaze/dashboardManager.ts +13 -2335
- package/test/examples/asciiMaze/evolutionEngine/README.md +1058 -0
- package/test/examples/asciiMaze/evolutionEngine/curriculumPhase.ts +90 -0
- package/test/examples/asciiMaze/evolutionEngine/engineState.constants.ts +36 -0
- package/test/examples/asciiMaze/evolutionEngine/engineState.ts +58 -513
- package/test/examples/asciiMaze/evolutionEngine/engineState.types.ts +212 -0
- package/test/examples/asciiMaze/evolutionEngine/engineState.utils.ts +301 -0
- package/test/examples/asciiMaze/evolutionEngine/evolutionEngine.types.ts +445 -0
- package/test/examples/asciiMaze/evolutionEngine/evolutionLoop.ts +81 -50
- package/test/examples/asciiMaze/evolutionEngine/optionsAndSetup.ts +2 -4
- package/test/examples/asciiMaze/evolutionEngine/populationDynamics.ts +17 -33
- package/test/examples/asciiMaze/evolutionEngine/populationPruning.ts +1 -1
- package/test/examples/asciiMaze/evolutionEngine/rngAndTiming.ts +1 -2
- package/test/examples/asciiMaze/evolutionEngine/sampling.ts +1 -1
- package/test/examples/asciiMaze/evolutionEngine/scratchPools.ts +2 -5
- package/test/examples/asciiMaze/evolutionEngine/setupHelpers.ts +30 -37
- package/test/examples/asciiMaze/evolutionEngine/telemetryMetrics.ts +16 -58
- package/test/examples/asciiMaze/evolutionEngine/trainingWarmStart.ts +2 -2
- package/test/examples/asciiMaze/evolutionEngine.ts +55 -55
- package/test/examples/asciiMaze/fitness.ts +2 -2
- package/test/examples/asciiMaze/fitness.types.ts +65 -0
- package/test/examples/asciiMaze/interfaces.ts +64 -1352
- package/test/examples/asciiMaze/mazeMovement/README.md +356 -0
- package/test/examples/asciiMaze/mazeMovement/finalization/README.md +49 -0
- package/test/examples/asciiMaze/mazeMovement/finalization/mazeMovement.finalization.ts +138 -0
- package/test/examples/asciiMaze/mazeMovement/mazeMovement.constants.ts +101 -0
- package/test/examples/asciiMaze/mazeMovement/mazeMovement.services.ts +230 -0
- package/test/examples/asciiMaze/mazeMovement/mazeMovement.ts +299 -0
- package/test/examples/asciiMaze/mazeMovement/mazeMovement.types.ts +185 -0
- package/test/examples/asciiMaze/mazeMovement/mazeMovement.utils.ts +153 -0
- package/test/examples/asciiMaze/mazeMovement/policy/README.md +91 -0
- package/test/examples/asciiMaze/mazeMovement/policy/mazeMovement.policy.ts +467 -0
- package/test/examples/asciiMaze/mazeMovement/runtime/README.md +95 -0
- package/test/examples/asciiMaze/mazeMovement/runtime/mazeMovement.runtime.ts +354 -0
- package/test/examples/asciiMaze/mazeMovement/shaping/README.md +124 -0
- package/test/examples/asciiMaze/mazeMovement/shaping/mazeMovement.shaping.ts +459 -0
- package/test/examples/asciiMaze/mazeMovement.ts +12 -2978
- package/test/examples/flappy_bird/README.md +193 -88
- package/test/examples/flappy_bird/browser-entry/README.md +1441 -0
- package/test/examples/flappy_bird/browser-entry/browser-entry.host.utils.ts +4 -324
- package/test/examples/flappy_bird/browser-entry/browser-entry.network-view.utils.ts +9 -396
- package/test/examples/flappy_bird/browser-entry/browser-entry.playback.utils.ts +6 -714
- package/test/examples/flappy_bird/browser-entry/browser-entry.render.types.ts +26 -3
- package/test/examples/flappy_bird/browser-entry/browser-entry.runtime.types.ts +16 -1
- package/test/examples/flappy_bird/browser-entry/browser-entry.simulation.types.ts +39 -5
- package/test/examples/flappy_bird/browser-entry/browser-entry.spawn.utils.ts +11 -31
- package/test/examples/flappy_bird/browser-entry/browser-entry.stats.types.ts +32 -4
- package/test/examples/flappy_bird/browser-entry/browser-entry.ts +11 -0
- package/test/examples/flappy_bird/browser-entry/browser-entry.types.ts +8 -0
- package/test/examples/flappy_bird/browser-entry/browser-entry.visualization.types.ts +50 -7
- package/test/examples/flappy_bird/browser-entry/browser-entry.visualization.utils.ts +21 -893
- package/test/examples/flappy_bird/browser-entry/browser-entry.worker.types.ts +91 -10
- package/test/examples/flappy_bird/browser-entry/host/README.md +318 -0
- package/test/examples/flappy_bird/browser-entry/host/host.canvas.service.ts +16 -0
- package/test/examples/flappy_bird/browser-entry/host/host.constants.ts +20 -0
- package/test/examples/flappy_bird/browser-entry/host/host.dom.service.ts +10 -0
- package/test/examples/flappy_bird/browser-entry/host/host.resize.service.ts +1 -295
- package/test/examples/flappy_bird/browser-entry/host/host.stats.service.ts +14 -0
- package/test/examples/flappy_bird/browser-entry/host/host.ts +592 -6
- package/test/examples/flappy_bird/browser-entry/host/host.types.ts +13 -0
- package/test/examples/flappy_bird/browser-entry/host/resize/README.md +309 -0
- package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.constants.ts +47 -0
- package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.services.ts +392 -0
- package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.ts +132 -0
- package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.types.ts +92 -0
- package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.utils.ts +272 -0
- package/test/examples/flappy_bird/browser-entry/network-view/README.md +389 -0
- package/test/examples/flappy_bird/browser-entry/network-view/network-view.draw.service.ts +13 -0
- package/test/examples/flappy_bird/browser-entry/network-view/network-view.labels.utils.ts +12 -0
- package/test/examples/flappy_bird/browser-entry/network-view/network-view.layout.utils.ts +14 -0
- package/test/examples/flappy_bird/browser-entry/network-view/network-view.topology.utils.ts +267 -0
- package/test/examples/flappy_bird/browser-entry/network-view/network-view.ts +823 -7
- package/test/examples/flappy_bird/browser-entry/network-view/network-view.types.ts +11 -0
- package/test/examples/flappy_bird/browser-entry/playback/README.md +845 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/README.md +355 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/README.md +1068 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.batch.services.ts +64 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.cache.services.ts +207 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.constants.ts +197 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.batch.utils.ts +114 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.layout.utils.test.ts +96 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.layout.utils.ts +204 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.services.ts +49 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.utils.ts +313 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.layer.services.ts +81 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.math.utils.test.ts +33 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.math.utils.ts +201 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.pulse.selection.utils.ts +171 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.pulse.timing.utils.ts +124 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.pulse.utils.test.ts +279 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.pulse.utils.ts +132 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.scene.services.ts +26 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.services.ts +65 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.ts +48 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.types.ts +342 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.utils.ts +10 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.cache.services.ts +96 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.constants.ts +127 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.draw.services.ts +184 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.scene.services.ts +64 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.services.ts +6 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.ts +53 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.types.ts +105 -0
- package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.utils.ts +100 -0
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/README.md +541 -0
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.bird.utils.ts +180 -0
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.canvas.services.ts +77 -0
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.entity.services.ts +167 -0
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.scene.services.ts +57 -0
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.service.test.ts +176 -0
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.service.ts +113 -0
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.services.ts +35 -0
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.trail.utils.ts +248 -0
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types.ts +103 -0
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.utils.ts +11 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.constants.ts +1 -1
- package/test/examples/flappy_bird/browser-entry/playback/playback.frame-render.service.ts +10 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.iteration.services.ts +192 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.loop.service.ts +12 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.orchestration.types.ts +78 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.render.pipe-outline.service.ts +128 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.render.service.ts +1 -116
- package/test/examples/flappy_bird/browser-entry/playback/playback.session.services.ts +184 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.snapshot.utils.test.ts +121 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.snapshot.utils.ts +8 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.layer.services.ts +36 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.service.ts +11 -128
- package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.services.ts +268 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.types.ts +91 -0
- package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.utils.ts +11 -4
- package/test/examples/flappy_bird/browser-entry/playback/playback.trail.utils.ts +9 -86
- package/test/examples/flappy_bird/browser-entry/playback/playback.ts +75 -7
- package/test/examples/flappy_bird/browser-entry/playback/playback.types.ts +12 -9
- package/test/examples/flappy_bird/browser-entry/playback/playback.worker-channel.utils.ts +11 -123
- package/test/examples/flappy_bird/browser-entry/playback/snapshot/README.md +55 -0
- package/test/examples/flappy_bird/browser-entry/playback/snapshot/playback.snapshot.services.ts +103 -0
- package/test/examples/flappy_bird/browser-entry/playback/snapshot/playback.snapshot.summary.utils.test.ts +45 -0
- package/test/examples/flappy_bird/browser-entry/playback/snapshot/playback.snapshot.summary.utils.ts +28 -0
- package/test/examples/flappy_bird/browser-entry/playback/trail/README.md +95 -0
- package/test/examples/flappy_bird/browser-entry/playback/trail/playback.trail.history.services.test.ts +35 -0
- package/test/examples/flappy_bird/browser-entry/playback/trail/playback.trail.history.services.ts +64 -0
- package/test/examples/flappy_bird/browser-entry/playback/trail/playback.trail.opacity.utils.test.ts +37 -0
- package/test/examples/flappy_bird/browser-entry/playback/trail/playback.trail.opacity.utils.ts +74 -0
- package/test/examples/flappy_bird/browser-entry/playback/worker-channel/README.md +71 -0
- package/test/examples/flappy_bird/browser-entry/playback/worker-channel/playback.worker-channel.request.services.ts +45 -0
- package/test/examples/flappy_bird/browser-entry/playback/worker-channel/playback.worker-channel.summary.services.ts +74 -0
- package/test/examples/flappy_bird/browser-entry/playback/worker-channel/playback.worker-channel.types.ts +53 -0
- package/test/examples/flappy_bird/browser-entry/runtime/README.md +304 -0
- package/test/examples/flappy_bird/browser-entry/runtime/runtime.browser-globals.service.ts +15 -0
- package/test/examples/flappy_bird/browser-entry/runtime/runtime.errors.ts +17 -0
- package/test/examples/flappy_bird/browser-entry/runtime/runtime.evolution-launch.service.ts +56 -0
- package/test/examples/flappy_bird/browser-entry/runtime/runtime.evolution-loop.service.ts +19 -0
- package/test/examples/flappy_bird/browser-entry/runtime/runtime.lifecycle.service.ts +96 -0
- package/test/examples/flappy_bird/browser-entry/runtime/runtime.startup.service.ts +92 -0
- package/test/examples/flappy_bird/browser-entry/runtime/runtime.telemetry.service.ts +24 -0
- package/test/examples/flappy_bird/browser-entry/runtime/runtime.ts +31 -121
- package/test/examples/flappy_bird/browser-entry/runtime/runtime.types.ts +65 -0
- package/test/examples/flappy_bird/browser-entry/visualization/README.md +568 -0
- package/test/examples/flappy_bird/browser-entry/visualization/visualization.colors.utils.ts +26 -0
- package/test/examples/flappy_bird/browser-entry/visualization/visualization.constants.ts +110 -0
- package/test/examples/flappy_bird/browser-entry/visualization/visualization.draw.service.ts +979 -19
- package/test/examples/flappy_bird/browser-entry/visualization/visualization.legend.utils.ts +157 -3
- package/test/examples/flappy_bird/browser-entry/visualization/visualization.topology.utils.ts +13 -27
- package/test/examples/flappy_bird/browser-entry/visualization/visualization.ts +7 -20
- package/test/examples/flappy_bird/browser-entry/visualization/visualization.types.ts +14 -0
- package/test/examples/flappy_bird/browser-entry/worker-channel/README.md +238 -0
- package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.errors.ts +11 -0
- package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.generation.service.ts +12 -0
- package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.playback.service.test.ts +143 -0
- package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.playback.service.ts +140 -14
- package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.request.service.ts +27 -0
- package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.ts +8 -0
- package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.types.ts +23 -0
- package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.url.service.ts +5 -0
- package/test/examples/flappy_bird/constants/README.md +1163 -0
- package/test/examples/flappy_bird/constants/constants.birds.ts +16 -38
- package/test/examples/flappy_bird/constants/constants.difficulty.ts +21 -0
- package/test/examples/flappy_bird/constants/constants.network-view.ts +24 -0
- package/test/examples/flappy_bird/constants/constants.network.ts +1 -1
- package/test/examples/flappy_bird/constants/constants.observation.ts +7 -0
- package/test/examples/flappy_bird/constants/constants.palette.ts +9 -2
- package/test/examples/flappy_bird/constants/constants.physics.ts +9 -0
- package/test/examples/flappy_bird/constants/constants.pipe-render.ts +3 -0
- package/test/examples/flappy_bird/constants/constants.pipes.ts +22 -3
- package/test/examples/flappy_bird/constants/constants.runtime.ts +28 -4
- package/test/examples/flappy_bird/constants/constants.starfield.ts +78 -3
- package/test/examples/flappy_bird/constants/constants.ts +6 -0
- package/test/examples/flappy_bird/environment/README.md +182 -0
- package/test/examples/flappy_bird/environment/environment.collision.utils.ts +7 -0
- package/test/examples/flappy_bird/environment/environment.constants.ts +16 -3
- package/test/examples/flappy_bird/environment/environment.observation.utils.ts +12 -19
- package/test/examples/flappy_bird/environment/environment.state.service.ts +10 -0
- package/test/examples/flappy_bird/environment/environment.step.service.ts +15 -66
- package/test/examples/flappy_bird/environment/environment.types.ts +14 -0
- package/test/examples/flappy_bird/evaluation/README.md +155 -0
- package/test/examples/flappy_bird/evaluation/evaluation.constants.ts +23 -4
- package/test/examples/flappy_bird/evaluation/evaluation.fitness.utils.ts +16 -1
- package/test/examples/flappy_bird/evaluation/evaluation.rollout.service.ts +7 -374
- package/test/examples/flappy_bird/evaluation/evaluation.seed.utils.ts +4 -0
- package/test/examples/flappy_bird/evaluation/evaluation.types.ts +18 -2
- package/test/examples/flappy_bird/evaluation/rollout/README.md +355 -0
- package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.constants.ts +38 -0
- package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.service.ts +71 -0
- package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.services.ts +338 -0
- package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.types.ts +69 -0
- package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.utils.ts +399 -0
- package/test/examples/flappy_bird/flappy-evolution-worker/README.md +845 -0
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.constants.ts +49 -7
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.errors.ts +34 -3
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.evolution.service.ts +22 -0
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.playback.service.ts +62 -26
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.protocol.service.ts +27 -1
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.runtime.service.ts +23 -0
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.frame.service.ts +378 -0
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.types.ts +22 -0
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.utils.ts +20 -203
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.snapshot.utils.test.ts +94 -0
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.snapshot.utils.ts +78 -13
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.ts +235 -344
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.types.ts +170 -22
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.warm-start.service.ts +314 -0
- package/test/examples/flappy_bird/flappy.simulation.shared.utils.ts +17 -0
- package/test/examples/flappy_bird/flappyEnvironment.ts +21 -0
- package/test/examples/flappy_bird/flappyEvaluation.ts +12 -0
- package/test/examples/flappy_bird/flappyEvolution.worker.ts +7 -0
- package/test/examples/flappy_bird/index.ts +8 -2
- package/test/examples/flappy_bird/rng.ts +10 -0
- package/test/examples/flappy_bird/simulation-shared/README.md +518 -0
- package/test/examples/flappy_bird/simulation-shared/observation/README.md +255 -0
- package/test/examples/flappy_bird/simulation-shared/observation/observation.features.utils.ts +339 -0
- package/test/examples/flappy_bird/simulation-shared/observation/observation.ts +19 -0
- package/test/examples/flappy_bird/simulation-shared/observation/observation.vector.utils.ts +81 -0
- package/test/examples/flappy_bird/simulation-shared/simulation-shared.constants.ts +3 -0
- package/test/examples/flappy_bird/simulation-shared/simulation-shared.control.utils.ts +6 -0
- package/test/examples/flappy_bird/simulation-shared/simulation-shared.difficulty.utils.ts +9 -0
- package/test/examples/flappy_bird/simulation-shared/simulation-shared.errors.ts +10 -1
- package/test/examples/flappy_bird/simulation-shared/simulation-shared.memory.utils.ts +18 -0
- package/test/examples/flappy_bird/simulation-shared/simulation-shared.observation.utils.ts +7 -402
- package/test/examples/flappy_bird/simulation-shared/simulation-shared.spawn.utils.ts +36 -6
- package/test/examples/flappy_bird/{evaluation/evaluation.statistics.utils.ts → simulation-shared/simulation-shared.statistics.utils.ts} +30 -9
- package/test/examples/flappy_bird/simulation-shared/simulation-shared.types.ts +38 -5
- package/test/examples/flappy_bird/trainFlappyBird.ts +13 -0
- package/test/examples/flappy_bird/trainer/README.md +676 -0
- package/test/examples/flappy_bird/trainer/evaluation/README.md +253 -0
- package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.constants.ts +15 -0
- package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.services.ts +86 -0
- package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.ts +187 -0
- package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.types.ts +32 -0
- package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.utils.ts +182 -0
- package/test/examples/flappy_bird/trainer/trainer.evaluation.service.ts +13 -0
- package/test/examples/flappy_bird/trainer/trainer.fitness.service.ts +23 -1
- package/test/examples/flappy_bird/trainer/trainer.loop.service.ts +17 -1
- package/test/examples/flappy_bird/trainer/trainer.report.service.services.ts +181 -0
- package/test/examples/flappy_bird/trainer/trainer.report.service.ts +136 -0
- package/test/examples/flappy_bird/trainer/trainer.selection.utils.ts +89 -0
- package/test/examples/flappy_bird/trainer/trainer.setup.service.ts +22 -0
- package/test/examples/flappy_bird/trainer/trainer.signals.service.ts +8 -0
- package/test/examples/flappy_bird/trainer/trainer.ts +38 -553
- package/test/examples/flappy_bird/trainer/trainer.types.ts +44 -7
- package/test/neat/neat.topology-intent.test.ts +129 -0
- package/test/network/network.topology-intent.test.ts +44 -0
- package/test/examples/flappy_bird/browser-entry/browser-entry.utils.ts +0 -12
- package/test/examples/flappy_bird/environment/environment.ts +0 -7
- package/test/examples/flappy_bird/evaluation/evaluation.ts +0 -7
- package/test/examples/flappy_bird/simulation-shared/simulation-shared.ts +0 -15
- package/test/examples/flappy_bird/trainer/trainer.statistics.utils.ts +0 -78
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type { FlappySeedBatchEvaluation } from '../../flappyEvaluation';
|
|
2
|
+
import {
|
|
3
|
+
FLAPPY_TRAINER_FRAME_PRIMARY_BASE_SCORE,
|
|
4
|
+
FLAPPY_TRAINER_FRAME_PRIMARY_PIPE_WEIGHT,
|
|
5
|
+
FLAPPY_TRAINER_FRAME_PRIMARY_SURVIVAL_WEIGHT,
|
|
6
|
+
FLAPPY_TRAINER_FRAME_STABILITY_STDDEV_WEIGHT,
|
|
7
|
+
FLAPPY_TRAINER_PIPE_FALLBACK_PIPE_WEIGHT,
|
|
8
|
+
FLAPPY_TRAINER_PIPE_FILTER_TOLERANCE,
|
|
9
|
+
} from '../trainer.constants';
|
|
10
|
+
import type { FlappyTrainerNetwork } from '../trainer.types';
|
|
11
|
+
import {
|
|
12
|
+
FLAPPY_TRAINER_MIN_PIPE_PROGRESS,
|
|
13
|
+
FLAPPY_TRAINER_NEGATIVE_INFINITY_SCORE,
|
|
14
|
+
} from './trainer.evaluation.service.constants';
|
|
15
|
+
import type { PopulationAggregateScoringContext } from './trainer.evaluation.service.types';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Assigns refreshed frame-primary scores to the current population.
|
|
19
|
+
*
|
|
20
|
+
* Educational note:
|
|
21
|
+
* The trainer does not rank genomes purely by one raw metric. It combines pipe
|
|
22
|
+
* progress, survival, and stability into a provisional score so early-stage
|
|
23
|
+
* selection remains robust when several genomes are close in quality.
|
|
24
|
+
*
|
|
25
|
+
* @param population - Current population.
|
|
26
|
+
* @param aggregateByGenome - Aggregate cache keyed by genome.
|
|
27
|
+
* @param provisionalScoresByGenome - Mutable provisional score map.
|
|
28
|
+
* @returns Nothing.
|
|
29
|
+
*/
|
|
30
|
+
export function assignFramePrimaryScores(
|
|
31
|
+
population: readonly FlappyTrainerNetwork[],
|
|
32
|
+
aggregateByGenome: ReadonlyMap<
|
|
33
|
+
FlappyTrainerNetwork,
|
|
34
|
+
FlappySeedBatchEvaluation
|
|
35
|
+
>,
|
|
36
|
+
provisionalScoresByGenome: Map<FlappyTrainerNetwork, number>,
|
|
37
|
+
): void {
|
|
38
|
+
// Step 1: Resolve the aggregate scoring context shared by all genomes.
|
|
39
|
+
const populationAggregateScoringContext =
|
|
40
|
+
resolvePopulationAggregateScoringContext(population, aggregateByGenome);
|
|
41
|
+
|
|
42
|
+
// Step 2: Score each genome using the refreshed aggregate context.
|
|
43
|
+
for (const genome of population) {
|
|
44
|
+
const aggregate = aggregateByGenome.get(genome);
|
|
45
|
+
if (!aggregate) {
|
|
46
|
+
provisionalScoresByGenome.set(
|
|
47
|
+
genome,
|
|
48
|
+
FLAPPY_TRAINER_NEGATIVE_INFINITY_SCORE,
|
|
49
|
+
);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
provisionalScoresByGenome.set(
|
|
54
|
+
genome,
|
|
55
|
+
scoreAggregateFramePrimary(
|
|
56
|
+
aggregate,
|
|
57
|
+
populationAggregateScoringContext.maximumMeanPipesPassed,
|
|
58
|
+
),
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Collects all currently available aggregate values.
|
|
65
|
+
*
|
|
66
|
+
* Only genomes with completed aggregate results are included. That lets the
|
|
67
|
+
* scoring helpers distinguish between genuinely weak genomes and genomes that
|
|
68
|
+
* simply have not yet reached a later stage.
|
|
69
|
+
*
|
|
70
|
+
* @param population - Current population.
|
|
71
|
+
* @param aggregateByGenome - Aggregate cache keyed by genome.
|
|
72
|
+
* @returns Collected aggregate values.
|
|
73
|
+
*/
|
|
74
|
+
export function collectAggregateValues(
|
|
75
|
+
population: readonly FlappyTrainerNetwork[],
|
|
76
|
+
aggregateByGenome: ReadonlyMap<
|
|
77
|
+
FlappyTrainerNetwork,
|
|
78
|
+
FlappySeedBatchEvaluation
|
|
79
|
+
>,
|
|
80
|
+
): FlappySeedBatchEvaluation[] {
|
|
81
|
+
const aggregateValues: FlappySeedBatchEvaluation[] = [];
|
|
82
|
+
|
|
83
|
+
// Step 1: Include only genomes that already have an aggregate in the cache.
|
|
84
|
+
for (const genome of population) {
|
|
85
|
+
const aggregate = aggregateByGenome.get(genome);
|
|
86
|
+
if (aggregate) {
|
|
87
|
+
aggregateValues.push(aggregate);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return aggregateValues;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Resolves the leading mean pipe-progress value across available aggregates.
|
|
96
|
+
*
|
|
97
|
+
* Mean pipe progress acts as the leading indicator for the frame-primary score:
|
|
98
|
+
* if a genome is far behind the current pipe leader, it falls back to a simpler
|
|
99
|
+
* progress-first score.
|
|
100
|
+
*
|
|
101
|
+
* @param aggregateValues - Aggregate values currently available.
|
|
102
|
+
* @returns Highest mean pipe-progress value.
|
|
103
|
+
*/
|
|
104
|
+
export function resolveMaximumMeanPipesPassed(
|
|
105
|
+
aggregateValues: readonly FlappySeedBatchEvaluation[],
|
|
106
|
+
): number {
|
|
107
|
+
// Step 1: Resolve the leading mean pipe-progress value across all aggregates.
|
|
108
|
+
return aggregateValues.reduce(
|
|
109
|
+
(bestPipeProgress, aggregate) =>
|
|
110
|
+
Math.max(bestPipeProgress, aggregate.meanPipesPassed),
|
|
111
|
+
FLAPPY_TRAINER_MIN_PIPE_PROGRESS,
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Scores one aggregate using the frame-primary heuristic.
|
|
117
|
+
*
|
|
118
|
+
* Educational note:
|
|
119
|
+
* The heuristic intentionally mixes progress and stability. A genome that passes
|
|
120
|
+
* many pipes but has wildly inconsistent fitness across seeds is treated more
|
|
121
|
+
* cautiously than a similarly strong but steadier genome.
|
|
122
|
+
*
|
|
123
|
+
* @param aggregate - Aggregate evaluation result.
|
|
124
|
+
* @param maximumMeanPipesPassed - Best mean pipe progress in the population.
|
|
125
|
+
* @returns Provisional score.
|
|
126
|
+
*/
|
|
127
|
+
export function scoreAggregateFramePrimary(
|
|
128
|
+
aggregate: FlappySeedBatchEvaluation,
|
|
129
|
+
maximumMeanPipesPassed: number,
|
|
130
|
+
): number {
|
|
131
|
+
// Step 1: Resolve the stability penalty and pipe-progress eligibility filter.
|
|
132
|
+
const frameStabilityPenalty =
|
|
133
|
+
aggregate.fitnessStdDev * FLAPPY_TRAINER_FRAME_STABILITY_STDDEV_WEIGHT;
|
|
134
|
+
const passesPipeFilter =
|
|
135
|
+
aggregate.meanPipesPassed >=
|
|
136
|
+
maximumMeanPipesPassed - FLAPPY_TRAINER_PIPE_FILTER_TOLERANCE;
|
|
137
|
+
|
|
138
|
+
// Step 2: Use the full frame-primary score when the genome remains near the pipe leader.
|
|
139
|
+
if (passesPipeFilter) {
|
|
140
|
+
return (
|
|
141
|
+
FLAPPY_TRAINER_FRAME_PRIMARY_BASE_SCORE +
|
|
142
|
+
aggregate.meanFramesSurvived *
|
|
143
|
+
FLAPPY_TRAINER_FRAME_PRIMARY_SURVIVAL_WEIGHT +
|
|
144
|
+
aggregate.meanPipesPassed * FLAPPY_TRAINER_FRAME_PRIMARY_PIPE_WEIGHT -
|
|
145
|
+
frameStabilityPenalty
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Step 3: Fall back to the pipe-progress-first score for trailing genomes.
|
|
150
|
+
return (
|
|
151
|
+
aggregate.meanPipesPassed * FLAPPY_TRAINER_PIPE_FALLBACK_PIPE_WEIGHT +
|
|
152
|
+
aggregate.meanFramesSurvived -
|
|
153
|
+
frameStabilityPenalty
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Resolves the aggregate scoring context used by frame-primary scoring.
|
|
159
|
+
*
|
|
160
|
+
* This precomputation step keeps the per-genome scoring loop lean and avoids
|
|
161
|
+
* recomputing population-wide maxima for every genome.
|
|
162
|
+
*
|
|
163
|
+
* @param population - Current population.
|
|
164
|
+
* @param aggregateByGenome - Aggregate cache keyed by genome.
|
|
165
|
+
* @returns Aggregate scoring context.
|
|
166
|
+
*/
|
|
167
|
+
function resolvePopulationAggregateScoringContext(
|
|
168
|
+
population: readonly FlappyTrainerNetwork[],
|
|
169
|
+
aggregateByGenome: ReadonlyMap<
|
|
170
|
+
FlappyTrainerNetwork,
|
|
171
|
+
FlappySeedBatchEvaluation
|
|
172
|
+
>,
|
|
173
|
+
): PopulationAggregateScoringContext {
|
|
174
|
+
// Step 1: Collect the currently available aggregate values.
|
|
175
|
+
const aggregateValues = collectAggregateValues(population, aggregateByGenome);
|
|
176
|
+
|
|
177
|
+
// Step 2: Resolve the highest mean pipe-progress value in the population.
|
|
178
|
+
return {
|
|
179
|
+
aggregateValues,
|
|
180
|
+
maximumMeanPipesPassed: resolveMaximumMeanPipesPassed(aggregateValues),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trainer evaluation compatibility facade.
|
|
3
|
+
*
|
|
4
|
+
* The staged population-evaluation implementation now lives in the dedicated
|
|
5
|
+
* `trainer/evaluation/` submodule so orchestration, scoring helpers, internal
|
|
6
|
+
* contracts, and sub-services can evolve behind a focused boundary.
|
|
7
|
+
*/
|
|
8
|
+
export {
|
|
9
|
+
commitPopulationScores,
|
|
10
|
+
evaluatePopulationFullStage,
|
|
11
|
+
evaluatePopulationQuickStage,
|
|
12
|
+
evaluatePopulationReevaluationStage,
|
|
13
|
+
} from './evaluation/trainer.evaluation.service';
|
|
@@ -7,7 +7,14 @@ import type {
|
|
|
7
7
|
FlappyTrainerRuntimeState,
|
|
8
8
|
} from './trainer.types';
|
|
9
9
|
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Callback dependencies required by the trainer fitness orchestration service.
|
|
12
|
+
*
|
|
13
|
+
* Educational note:
|
|
14
|
+
* The trainer evaluates whole populations in staged passes. This dependency bag
|
|
15
|
+
* keeps the top-level service declarative and makes each stage independently
|
|
16
|
+
* replaceable without rewriting the orchestration logic.
|
|
17
|
+
*/
|
|
11
18
|
export interface TrainerFitnessServiceDependencies {
|
|
12
19
|
resolveGenerationEvaluationPlan: (
|
|
13
20
|
generationIndex: number,
|
|
@@ -49,10 +56,16 @@ export interface TrainerFitnessServiceDependencies {
|
|
|
49
56
|
/**
|
|
50
57
|
* Attaches population-level staged evaluator to the NEAT controller.
|
|
51
58
|
*
|
|
59
|
+
* This is the moment where the generic NEAT controller becomes a
|
|
60
|
+
* Flappy-specific trainer: a plain controller receives the staged population
|
|
61
|
+
* evaluator that understands shared-seed screening, full-pass scoring, and
|
|
62
|
+
* reevaluation.
|
|
63
|
+
*
|
|
52
64
|
* @param neatController - Trainer NEAT controller.
|
|
53
65
|
* @param trainerRuntimeState - Mutable trainer runtime state.
|
|
54
66
|
* @param elitismCount - Number of elite genomes preserved each generation.
|
|
55
67
|
* @param dependencies - Pure/impure helper callbacks used by the evaluator.
|
|
68
|
+
* @returns Nothing.
|
|
56
69
|
*/
|
|
57
70
|
export function attachPopulationFitnessEvaluator(
|
|
58
71
|
neatController: FlappyTrainerNeatController,
|
|
@@ -71,6 +84,15 @@ export function attachPopulationFitnessEvaluator(
|
|
|
71
84
|
/**
|
|
72
85
|
* Creates the asynchronous population fitness evaluator.
|
|
73
86
|
*
|
|
87
|
+
* Educational note:
|
|
88
|
+
* The trainer uses staged evaluation to reduce luck. Genomes are first screened
|
|
89
|
+
* quickly, then the most promising ones receive more expensive evaluation, and
|
|
90
|
+
* the best candidates are reevaluated again for robustness.
|
|
91
|
+
*
|
|
92
|
+
* That strategy is closer to tournament design than to naive one-shot scoring:
|
|
93
|
+
* the same generation budget is spent unevenly so weak genomes are filtered out
|
|
94
|
+
* early and strong genomes are compared more carefully.
|
|
95
|
+
*
|
|
74
96
|
* @param neatController - Trainer NEAT controller.
|
|
75
97
|
* @param trainerRuntimeState - Mutable trainer runtime state.
|
|
76
98
|
* @param elitismCount - Number of elite genomes preserved each generation.
|
|
@@ -11,7 +11,13 @@ import type {
|
|
|
11
11
|
FlappyTrainerRuntimeState,
|
|
12
12
|
} from './trainer.types';
|
|
13
13
|
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Callback signature for one-line generation logging.
|
|
16
|
+
*
|
|
17
|
+
* The loop owns evolution cadence, while the callback owns presentation.
|
|
18
|
+
* Keeping those concerns separate makes it easy to reuse the loop with richer
|
|
19
|
+
* reporting later.
|
|
20
|
+
*/
|
|
15
21
|
export type LogGenerationSummaryCallback = (
|
|
16
22
|
generationLabel: number,
|
|
17
23
|
mutationSchedule: FlappyMutationSchedule,
|
|
@@ -23,9 +29,15 @@ export type LogGenerationSummaryCallback = (
|
|
|
23
29
|
/**
|
|
24
30
|
* Runs the outer evolution loop until runtime stop is requested.
|
|
25
31
|
*
|
|
32
|
+
* Educational note:
|
|
33
|
+
* This is the trainer's main heartbeat: resolve the current mutation schedule,
|
|
34
|
+
* evolve one generation, run a representative fallback rollout for logging, and
|
|
35
|
+
* emit a compact summary.
|
|
36
|
+
*
|
|
26
37
|
* @param neatController - Trainer NEAT controller.
|
|
27
38
|
* @param trainerRuntimeState - Mutable trainer runtime state.
|
|
28
39
|
* @param logGenerationSummary - Callback that emits compact generation logs.
|
|
40
|
+
* @returns Promise resolved when the trainer has been stopped.
|
|
29
41
|
*/
|
|
30
42
|
export async function runTrainerEvolutionLoop(
|
|
31
43
|
neatController: FlappyTrainerNeatController,
|
|
@@ -55,8 +67,12 @@ export async function runTrainerEvolutionLoop(
|
|
|
55
67
|
/**
|
|
56
68
|
* Applies mutation schedule values to the NEAT controller options.
|
|
57
69
|
*
|
|
70
|
+
* The schedule is resolved outside this helper so the loop can read as a clean
|
|
71
|
+
* "resolve -> apply -> evolve -> report" flow.
|
|
72
|
+
*
|
|
58
73
|
* @param neatController - Trainer NEAT controller.
|
|
59
74
|
* @param mutationSchedule - Mutation schedule for current generation.
|
|
75
|
+
* @returns Nothing.
|
|
60
76
|
*/
|
|
61
77
|
function applyMutationSchedule(
|
|
62
78
|
neatController: FlappyTrainerNeatController,
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import {
|
|
2
|
+
evaluateFlappyFitnessAcrossSeeds,
|
|
3
|
+
rolloutEpisode,
|
|
4
|
+
type FlappyRolloutOptions,
|
|
5
|
+
type FlappySeedBatchEvaluation,
|
|
6
|
+
} from '../flappyEvaluation';
|
|
7
|
+
import {
|
|
8
|
+
FLAPPY_TRAINER_DUMMY_FLAP_OUTPUT,
|
|
9
|
+
FLAPPY_TRAINER_DUMMY_NETWORK_ID,
|
|
10
|
+
FLAPPY_TRAINER_DUMMY_NO_FLAP_OUTPUT,
|
|
11
|
+
} from './trainer.constants';
|
|
12
|
+
import type { FlappyTrainerNetwork } from './trainer.types';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Aggregate and representative rollout resolved for the best genome.
|
|
16
|
+
*
|
|
17
|
+
* Keeping these values together lets the report facade stay focused on
|
|
18
|
+
* orchestration while this helper module owns cache fallback behavior.
|
|
19
|
+
*/
|
|
20
|
+
export interface ResolvedBestGenerationDetails {
|
|
21
|
+
bestAggregate: FlappySeedBatchEvaluation;
|
|
22
|
+
bestEpisode: ReturnType<typeof rolloutEpisode>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Collects only finite scores from the current population.
|
|
27
|
+
*
|
|
28
|
+
* Unevaluated or invalid scores are intentionally skipped so percentile and
|
|
29
|
+
* standard deviation calculations operate on stable numeric inputs only.
|
|
30
|
+
*
|
|
31
|
+
* @param population - Current population.
|
|
32
|
+
* @returns Finite scores in population order.
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const scores = collectFiniteGenomeScores(population);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function collectFiniteGenomeScores(
|
|
39
|
+
population: readonly FlappyTrainerNetwork[],
|
|
40
|
+
): number[] {
|
|
41
|
+
const finiteScores: number[] = [];
|
|
42
|
+
|
|
43
|
+
for (const genome of population) {
|
|
44
|
+
const genomeScore = genome.score ?? Number.NEGATIVE_INFINITY;
|
|
45
|
+
if (Number.isFinite(genomeScore)) {
|
|
46
|
+
finiteScores.push(genomeScore);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return finiteScores;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Resolves cached or fallback best-of-generation details for reporting.
|
|
55
|
+
*
|
|
56
|
+
* The report layer needs both aggregate seed statistics and one representative
|
|
57
|
+
* episode. This helper centralizes the fallback rules so the service facade can
|
|
58
|
+
* remain a thin orchestration layer.
|
|
59
|
+
*
|
|
60
|
+
* @param population - Current population.
|
|
61
|
+
* @param bestGenome - Genome selected as generation best.
|
|
62
|
+
* @param aggregateByGenome - Cached aggregate evaluations keyed by genome.
|
|
63
|
+
* @param fallbackSeeds - Seeds used when the aggregate must be recomputed.
|
|
64
|
+
* @param fallbackRolloutOptions - Rollout options for fallback evaluation.
|
|
65
|
+
* @returns Aggregate metrics and a representative best-genome episode.
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* const { bestAggregate, bestEpisode } = resolveBestGenerationDetails(
|
|
69
|
+
* population,
|
|
70
|
+
* bestGenome,
|
|
71
|
+
* aggregateByGenome,
|
|
72
|
+
* reevaluationSeeds,
|
|
73
|
+
* reevaluationRolloutOptions,
|
|
74
|
+
* );
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export function resolveBestGenerationDetails(
|
|
78
|
+
population: readonly FlappyTrainerNetwork[],
|
|
79
|
+
bestGenome: FlappyTrainerNetwork | undefined,
|
|
80
|
+
aggregateByGenome: ReadonlyMap<
|
|
81
|
+
FlappyTrainerNetwork,
|
|
82
|
+
FlappySeedBatchEvaluation
|
|
83
|
+
>,
|
|
84
|
+
fallbackSeeds: readonly number[],
|
|
85
|
+
fallbackRolloutOptions: FlappyRolloutOptions,
|
|
86
|
+
): ResolvedBestGenerationDetails {
|
|
87
|
+
return {
|
|
88
|
+
bestAggregate: resolveBestAggregate(
|
|
89
|
+
population,
|
|
90
|
+
bestGenome,
|
|
91
|
+
aggregateByGenome,
|
|
92
|
+
fallbackSeeds,
|
|
93
|
+
fallbackRolloutOptions,
|
|
94
|
+
),
|
|
95
|
+
bestEpisode: resolveBestEpisode(
|
|
96
|
+
population,
|
|
97
|
+
bestGenome,
|
|
98
|
+
fallbackSeeds,
|
|
99
|
+
fallbackRolloutOptions,
|
|
100
|
+
),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function resolveBestAggregate(
|
|
105
|
+
population: readonly FlappyTrainerNetwork[],
|
|
106
|
+
bestGenome: FlappyTrainerNetwork | undefined,
|
|
107
|
+
aggregateByGenome: ReadonlyMap<
|
|
108
|
+
FlappyTrainerNetwork,
|
|
109
|
+
FlappySeedBatchEvaluation
|
|
110
|
+
>,
|
|
111
|
+
fallbackSeeds: readonly number[],
|
|
112
|
+
fallbackRolloutOptions: FlappyRolloutOptions,
|
|
113
|
+
): FlappySeedBatchEvaluation {
|
|
114
|
+
const fallbackGenome = resolveFallbackGenome(population, bestGenome);
|
|
115
|
+
if (!fallbackGenome) {
|
|
116
|
+
return buildEmptySeedBatchEvaluation();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const cachedAggregate = aggregateByGenome.get(fallbackGenome);
|
|
120
|
+
if (cachedAggregate) {
|
|
121
|
+
return cachedAggregate;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return evaluateFlappyFitnessAcrossSeeds(
|
|
125
|
+
fallbackGenome,
|
|
126
|
+
fallbackSeeds,
|
|
127
|
+
fallbackRolloutOptions,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function resolveBestEpisode(
|
|
132
|
+
population: readonly FlappyTrainerNetwork[],
|
|
133
|
+
bestGenome: FlappyTrainerNetwork | undefined,
|
|
134
|
+
fallbackSeeds: readonly number[],
|
|
135
|
+
fallbackRolloutOptions: FlappyRolloutOptions,
|
|
136
|
+
): ReturnType<typeof rolloutEpisode> {
|
|
137
|
+
const fallbackGenome = resolveFallbackGenome(population, bestGenome);
|
|
138
|
+
if (!fallbackGenome) {
|
|
139
|
+
return rolloutEpisode(resolveDummyNetwork(), fallbackRolloutOptions);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const episodeSeed = fallbackSeeds[0];
|
|
143
|
+
return rolloutEpisode(fallbackGenome, {
|
|
144
|
+
...fallbackRolloutOptions,
|
|
145
|
+
seed: episodeSeed,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function resolveFallbackGenome(
|
|
150
|
+
population: readonly FlappyTrainerNetwork[],
|
|
151
|
+
bestGenome: FlappyTrainerNetwork | undefined,
|
|
152
|
+
): FlappyTrainerNetwork | undefined {
|
|
153
|
+
return bestGenome ?? population[0];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function buildEmptySeedBatchEvaluation(): FlappySeedBatchEvaluation {
|
|
157
|
+
return {
|
|
158
|
+
seedCount: 0,
|
|
159
|
+
meanFitness: 0,
|
|
160
|
+
medianFitness: 0,
|
|
161
|
+
p90Fitness: 0,
|
|
162
|
+
fitnessStdDev: 0,
|
|
163
|
+
robustFitness: 0,
|
|
164
|
+
meanPipesPassed: 0,
|
|
165
|
+
meanFramesSurvived: 0,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function resolveDummyNetwork(): FlappyTrainerNetwork {
|
|
170
|
+
return {
|
|
171
|
+
activate: activateWithoutFlap,
|
|
172
|
+
_id: FLAPPY_TRAINER_DUMMY_NETWORK_ID,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function activateWithoutFlap(): number[] {
|
|
177
|
+
return [
|
|
178
|
+
FLAPPY_TRAINER_DUMMY_NO_FLAP_OUTPUT,
|
|
179
|
+
FLAPPY_TRAINER_DUMMY_FLAP_OUTPUT,
|
|
180
|
+
];
|
|
181
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import {
|
|
2
|
+
rolloutEpisode,
|
|
3
|
+
type FlappySeedBatchEvaluation,
|
|
4
|
+
} from '../flappyEvaluation';
|
|
5
|
+
import {
|
|
6
|
+
FLAPPY_TRAINER_LOG_PARTS_DELIMITER,
|
|
7
|
+
FLAPPY_TRAINER_SCORE_MEDIAN_PERCENTILE,
|
|
8
|
+
FLAPPY_TRAINER_SCORE_P90_PERCENTILE,
|
|
9
|
+
} from './trainer.constants';
|
|
10
|
+
import type { FlappyMutationSchedule } from './trainer.evaluation-plan.utils';
|
|
11
|
+
import {
|
|
12
|
+
collectFiniteGenomeScores,
|
|
13
|
+
resolveBestGenerationDetails,
|
|
14
|
+
} from './trainer.report.service.services';
|
|
15
|
+
import { buildGenerationLogParts } from './trainer.reporting.utils';
|
|
16
|
+
import { resolveBestGenomeByScore } from './trainer.selection.utils';
|
|
17
|
+
import {
|
|
18
|
+
computeMean,
|
|
19
|
+
computePercentile,
|
|
20
|
+
computePopulationStandardDeviation,
|
|
21
|
+
} from '../flappy.simulation.shared.utils';
|
|
22
|
+
import type {
|
|
23
|
+
FlappyGenerationEvaluationPlan,
|
|
24
|
+
FlappyGenerationReport,
|
|
25
|
+
FlappyTrainerNetwork,
|
|
26
|
+
} from './trainer.types';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Builds a compact report for the current generation.
|
|
30
|
+
*
|
|
31
|
+
* Educational note:
|
|
32
|
+
* The trainer logs more than a single best score because single-number progress
|
|
33
|
+
* can hide instability. Mean, median, $p90$, and standard deviation reveal
|
|
34
|
+
* whether a generation is broadly improving or whether one lucky genome is
|
|
35
|
+
* masking a weak population.
|
|
36
|
+
*
|
|
37
|
+
* @param population - Current population.
|
|
38
|
+
* @param aggregateByGenome - Aggregate evaluation results keyed by genome.
|
|
39
|
+
* @param generationEvaluationPlan - Per-generation staged evaluation plan.
|
|
40
|
+
* @returns Aggregated generation report.
|
|
41
|
+
*/
|
|
42
|
+
export function buildGenerationReport(
|
|
43
|
+
population: readonly FlappyTrainerNetwork[],
|
|
44
|
+
aggregateByGenome: ReadonlyMap<
|
|
45
|
+
FlappyTrainerNetwork,
|
|
46
|
+
FlappySeedBatchEvaluation
|
|
47
|
+
>,
|
|
48
|
+
generationEvaluationPlan: FlappyGenerationEvaluationPlan,
|
|
49
|
+
): FlappyGenerationReport {
|
|
50
|
+
// Step 1: Collect stable numeric inputs for distribution statistics.
|
|
51
|
+
const finalScores = collectFiniteGenomeScores(population);
|
|
52
|
+
const scoreMean = computeMean(finalScores);
|
|
53
|
+
const scoreStdDev = computePopulationStandardDeviation(
|
|
54
|
+
finalScores,
|
|
55
|
+
scoreMean,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
// Step 2: Resolve best-genome derived metrics through the report helper boundary.
|
|
59
|
+
const bestGenome = resolveBestGenomeByScore(population);
|
|
60
|
+
const { bestAggregate, bestEpisode } = resolveBestGenerationDetails(
|
|
61
|
+
population,
|
|
62
|
+
bestGenome,
|
|
63
|
+
aggregateByGenome,
|
|
64
|
+
generationEvaluationPlan.reevaluationSeeds,
|
|
65
|
+
generationEvaluationPlan.reevaluationRolloutOptions,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Step 3: Fold the resolved metrics into the compact generation report.
|
|
69
|
+
return {
|
|
70
|
+
generationIndex: generationEvaluationPlan.generationIndex,
|
|
71
|
+
difficultyScale: generationEvaluationPlan.difficultyScale,
|
|
72
|
+
mutationRate: generationEvaluationPlan.mutationRate,
|
|
73
|
+
mutationAmount: generationEvaluationPlan.mutationAmount,
|
|
74
|
+
quickSeedCount: generationEvaluationPlan.quickSeeds.length,
|
|
75
|
+
fullSeedCount: generationEvaluationPlan.fullSeeds.length,
|
|
76
|
+
reevaluationSeedCount: generationEvaluationPlan.reevaluationSeeds.length,
|
|
77
|
+
evaluatedPopulationSize: population.length,
|
|
78
|
+
scoreMean,
|
|
79
|
+
scoreMedian: computePercentile(
|
|
80
|
+
finalScores,
|
|
81
|
+
FLAPPY_TRAINER_SCORE_MEDIAN_PERCENTILE,
|
|
82
|
+
),
|
|
83
|
+
scoreP90: computePercentile(
|
|
84
|
+
finalScores,
|
|
85
|
+
FLAPPY_TRAINER_SCORE_P90_PERCENTILE,
|
|
86
|
+
),
|
|
87
|
+
scoreStdDev,
|
|
88
|
+
bestRobustFitness: bestGenome?.score ?? Number.NaN,
|
|
89
|
+
bestMeanFitness: bestAggregate.meanFitness,
|
|
90
|
+
bestPipesPassed: bestEpisode.pipesPassed,
|
|
91
|
+
bestFramesSurvived: bestEpisode.framesSurvived,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Emits one compact generation log line.
|
|
97
|
+
*
|
|
98
|
+
* The emitted line is designed for long-running terminal sessions: dense enough
|
|
99
|
+
* to be useful, but stable enough that humans can visually scan progress over
|
|
100
|
+
* hundreds of generations.
|
|
101
|
+
*
|
|
102
|
+
* @param generationLabel - Current generation label.
|
|
103
|
+
* @param mutationSchedule - Active mutation schedule.
|
|
104
|
+
* @param report - Optional aggregated generation report.
|
|
105
|
+
* @param fittestGenome - Fittest genome returned by the NEAT controller.
|
|
106
|
+
* @param fallbackEpisode - Fallback representative rollout episode.
|
|
107
|
+
* @returns Nothing.
|
|
108
|
+
*/
|
|
109
|
+
export function logGenerationSummary(
|
|
110
|
+
generationLabel: number,
|
|
111
|
+
mutationSchedule: FlappyMutationSchedule,
|
|
112
|
+
report: FlappyGenerationReport | undefined,
|
|
113
|
+
fittestGenome: FlappyTrainerNetwork,
|
|
114
|
+
fallbackEpisode: ReturnType<typeof rolloutEpisode>,
|
|
115
|
+
): void {
|
|
116
|
+
const bestFitness =
|
|
117
|
+
report?.bestRobustFitness ??
|
|
118
|
+
(fittestGenome.score as number) ??
|
|
119
|
+
fallbackEpisode.fitness;
|
|
120
|
+
const bestPipesPassed =
|
|
121
|
+
report?.bestPipesPassed ?? fallbackEpisode.pipesPassed;
|
|
122
|
+
const bestFramesSurvived =
|
|
123
|
+
report?.bestFramesSurvived ?? fallbackEpisode.framesSurvived;
|
|
124
|
+
|
|
125
|
+
const logParts = buildGenerationLogParts(
|
|
126
|
+
generationLabel,
|
|
127
|
+
bestFitness,
|
|
128
|
+
bestPipesPassed,
|
|
129
|
+
bestFramesSurvived,
|
|
130
|
+
report,
|
|
131
|
+
mutationSchedule,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// eslint-disable-next-line no-console
|
|
135
|
+
console.log(logParts.join(FLAPPY_TRAINER_LOG_PARTS_DELIMITER));
|
|
136
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { FlappyTrainerNetwork, ScoredGenomeEntry } from './trainer.types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns top genomes ordered by current provisional score.
|
|
5
|
+
*
|
|
6
|
+
* @param population - Current trainer population.
|
|
7
|
+
* @param provisionalScoresByGenome - Optional map of staged provisional scores.
|
|
8
|
+
* @param targetCount - Maximum number of genomes to return.
|
|
9
|
+
* @returns Highest-scoring genomes in descending score order.
|
|
10
|
+
*/
|
|
11
|
+
export function selectTopGenomesByScore(
|
|
12
|
+
population: readonly FlappyTrainerNetwork[],
|
|
13
|
+
provisionalScoresByGenome: ReadonlyMap<FlappyTrainerNetwork, number>,
|
|
14
|
+
targetCount: number,
|
|
15
|
+
): FlappyTrainerNetwork[] {
|
|
16
|
+
const scoredEntries = buildScoredGenomeEntries(
|
|
17
|
+
population,
|
|
18
|
+
provisionalScoresByGenome,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
scoredEntries.sort(compareScoredGenomeEntriesDescending);
|
|
22
|
+
|
|
23
|
+
const selectedGenomes: FlappyTrainerNetwork[] = [];
|
|
24
|
+
const maximumSelectionCount = Math.max(
|
|
25
|
+
0,
|
|
26
|
+
Math.min(targetCount, scoredEntries.length),
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
let selectedIndex = 0;
|
|
30
|
+
while (selectedIndex < maximumSelectionCount) {
|
|
31
|
+
const scoredEntry = scoredEntries[selectedIndex];
|
|
32
|
+
if (scoredEntry) {
|
|
33
|
+
selectedGenomes.push(scoredEntry.genome);
|
|
34
|
+
}
|
|
35
|
+
selectedIndex += 1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return selectedGenomes;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Resolves the best genome by current score.
|
|
43
|
+
*
|
|
44
|
+
* @param population - Current trainer population.
|
|
45
|
+
* @returns Highest-scoring genome or `undefined` when population is empty.
|
|
46
|
+
*/
|
|
47
|
+
export function resolveBestGenomeByScore(
|
|
48
|
+
population: readonly FlappyTrainerNetwork[],
|
|
49
|
+
): FlappyTrainerNetwork | undefined {
|
|
50
|
+
const scoredGenomes = buildScoredGenomeEntries(population, undefined);
|
|
51
|
+
scoredGenomes.sort(compareScoredGenomeEntriesDescending);
|
|
52
|
+
return scoredGenomes[0]?.genome;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function buildScoredGenomeEntries(
|
|
56
|
+
population: readonly FlappyTrainerNetwork[],
|
|
57
|
+
provisionalScoresByGenome:
|
|
58
|
+
| ReadonlyMap<FlappyTrainerNetwork, number>
|
|
59
|
+
| undefined,
|
|
60
|
+
): ScoredGenomeEntry[] {
|
|
61
|
+
const scoredEntries: ScoredGenomeEntry[] = [];
|
|
62
|
+
|
|
63
|
+
for (const genome of population) {
|
|
64
|
+
const score = resolveGenomeScore(genome, provisionalScoresByGenome);
|
|
65
|
+
scoredEntries.push({ genome, score });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return scoredEntries;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function resolveGenomeScore(
|
|
72
|
+
genome: FlappyTrainerNetwork,
|
|
73
|
+
provisionalScoresByGenome:
|
|
74
|
+
| ReadonlyMap<FlappyTrainerNetwork, number>
|
|
75
|
+
| undefined,
|
|
76
|
+
): number {
|
|
77
|
+
if (provisionalScoresByGenome) {
|
|
78
|
+
return provisionalScoresByGenome.get(genome) ?? Number.NEGATIVE_INFINITY;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return genome.score ?? Number.NEGATIVE_INFINITY;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function compareScoredGenomeEntriesDescending(
|
|
85
|
+
leftEntry: ScoredGenomeEntry,
|
|
86
|
+
rightEntry: ScoredGenomeEntry,
|
|
87
|
+
): number {
|
|
88
|
+
return rightEntry.score - leftEntry.score;
|
|
89
|
+
}
|