@reicek/neataptic-ts 0.1.21 → 0.1.22

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.
Files changed (223) hide show
  1. package/.github/agents/boundary-mapper.agent.md +29 -0
  2. package/.github/agents/docs-scout.agent.md +29 -0
  3. package/.github/agents/plan-scout.agent.md +29 -0
  4. package/.github/agents/solid-split.agent.md +138 -0
  5. package/.github/copilot-instructions.md +103 -0
  6. package/package.json +6 -3
  7. package/plans/ES2023 migration +13 -8
  8. package/plans/Evolution_Training_Interoperability_Contracts.md +1 -1
  9. package/plans/Interactive_Examples_and_Learning_Path.md +10 -2
  10. package/plans/Memory_Optimization.md +3 -3
  11. package/plans/README.md +63 -0
  12. package/plans/Roadmap.md +15 -3
  13. package/plans/asciiMaze_SOLID_split.done.md +130 -0
  14. package/plans/flappy_bird_SOLID_split.done.md +67 -0
  15. package/scripts/assets/theme.css +221 -34
  16. package/scripts/copy-examples.mjs +9 -5
  17. package/scripts/export-onnx.mjs +3 -3
  18. package/scripts/generate-bench-tables.mjs +10 -10
  19. package/scripts/generate-bench-tables.ts +10 -10
  20. package/scripts/generate-docs.ts +1415 -449
  21. package/scripts/render-docs-html.ts +15 -8
  22. package/src/README.md +101 -223
  23. package/src/architecture/README.md +57 -185
  24. package/src/architecture/layer/README.md +38 -38
  25. package/src/architecture/network/README.md +33 -31
  26. package/src/architecture/network/activate/README.md +77 -77
  27. package/src/architecture/network/connect/README.md +15 -13
  28. package/src/architecture/network/deterministic/README.md +7 -7
  29. package/src/architecture/network/evolve/README.md +44 -44
  30. package/src/architecture/network/gating/README.md +20 -20
  31. package/src/architecture/network/genetic/README.md +51 -51
  32. package/src/architecture/network/mutate/README.md +97 -97
  33. package/src/architecture/network/onnx/README.md +264 -264
  34. package/src/architecture/network/prune/README.md +39 -39
  35. package/src/architecture/network/remove/README.md +26 -26
  36. package/src/architecture/network/serialize/README.md +56 -56
  37. package/src/architecture/network/slab/README.md +61 -61
  38. package/src/architecture/network/standalone/README.md +24 -24
  39. package/src/architecture/network/stats/README.md +9 -9
  40. package/src/architecture/network/topology/README.md +46 -46
  41. package/src/architecture/network/training/README.md +21 -21
  42. package/src/methods/README.md +9 -87
  43. package/src/multithreading/README.md +8 -77
  44. package/src/multithreading/workers/README.md +2 -2
  45. package/src/multithreading/workers/browser/README.md +0 -6
  46. package/src/multithreading/workers/node/README.md +0 -3
  47. package/src/neat/README.md +562 -568
  48. package/src/utils/README.md +18 -18
  49. package/test/examples/asciiMaze/README.md +59 -59
  50. package/test/examples/asciiMaze/asciiMaze.e2e.test.ts +14 -9
  51. package/test/examples/asciiMaze/browser-entry/README.md +196 -0
  52. package/test/examples/asciiMaze/browser-entry/browser-entry.abort.services.ts +95 -0
  53. package/test/examples/asciiMaze/browser-entry/browser-entry.constants.ts +23 -0
  54. package/test/examples/asciiMaze/browser-entry/browser-entry.curriculum.services.ts +115 -0
  55. package/test/examples/asciiMaze/browser-entry/browser-entry.globals.services.ts +106 -0
  56. package/test/examples/asciiMaze/browser-entry/browser-entry.host.services.ts +157 -0
  57. package/test/examples/asciiMaze/browser-entry/browser-entry.services.ts +14 -0
  58. package/test/examples/asciiMaze/browser-entry/browser-entry.ts +129 -0
  59. package/test/examples/asciiMaze/browser-entry/browser-entry.types.ts +120 -0
  60. package/test/examples/asciiMaze/browser-entry/browser-entry.utils.ts +98 -0
  61. package/test/examples/asciiMaze/browser-entry.ts +10 -576
  62. package/test/examples/asciiMaze/dashboardManager/README.md +276 -0
  63. package/test/examples/asciiMaze/dashboardManager/archive/README.md +16 -0
  64. package/test/examples/asciiMaze/dashboardManager/archive/dashboardManager.archive.services.ts +267 -0
  65. package/test/examples/asciiMaze/dashboardManager/dashboardManager.constants.ts +35 -0
  66. package/test/examples/asciiMaze/dashboardManager/dashboardManager.services.ts +103 -0
  67. package/test/examples/asciiMaze/dashboardManager/dashboardManager.ts +181 -0
  68. package/test/examples/asciiMaze/dashboardManager/dashboardManager.types.ts +267 -0
  69. package/test/examples/asciiMaze/dashboardManager/dashboardManager.utils.ts +254 -0
  70. package/test/examples/asciiMaze/dashboardManager/live/README.md +14 -0
  71. package/test/examples/asciiMaze/dashboardManager/live/dashboardManager.live.services.ts +264 -0
  72. package/test/examples/asciiMaze/dashboardManager/telemetry/README.md +47 -0
  73. package/test/examples/asciiMaze/dashboardManager/telemetry/dashboardManager.telemetry.services.ts +513 -0
  74. package/test/examples/asciiMaze/dashboardManager.ts +13 -2335
  75. package/test/examples/asciiMaze/evolutionEngine/README.md +1058 -0
  76. package/test/examples/asciiMaze/evolutionEngine/curriculumPhase.ts +90 -0
  77. package/test/examples/asciiMaze/evolutionEngine/engineState.constants.ts +36 -0
  78. package/test/examples/asciiMaze/evolutionEngine/engineState.ts +58 -513
  79. package/test/examples/asciiMaze/evolutionEngine/engineState.types.ts +212 -0
  80. package/test/examples/asciiMaze/evolutionEngine/engineState.utils.ts +301 -0
  81. package/test/examples/asciiMaze/evolutionEngine/evolutionEngine.types.ts +445 -0
  82. package/test/examples/asciiMaze/evolutionEngine/evolutionLoop.ts +81 -50
  83. package/test/examples/asciiMaze/evolutionEngine/optionsAndSetup.ts +2 -4
  84. package/test/examples/asciiMaze/evolutionEngine/populationDynamics.ts +17 -33
  85. package/test/examples/asciiMaze/evolutionEngine/populationPruning.ts +1 -1
  86. package/test/examples/asciiMaze/evolutionEngine/rngAndTiming.ts +1 -2
  87. package/test/examples/asciiMaze/evolutionEngine/sampling.ts +1 -1
  88. package/test/examples/asciiMaze/evolutionEngine/scratchPools.ts +2 -5
  89. package/test/examples/asciiMaze/evolutionEngine/setupHelpers.ts +30 -37
  90. package/test/examples/asciiMaze/evolutionEngine/telemetryMetrics.ts +16 -58
  91. package/test/examples/asciiMaze/evolutionEngine/trainingWarmStart.ts +2 -2
  92. package/test/examples/asciiMaze/evolutionEngine.ts +55 -55
  93. package/test/examples/asciiMaze/fitness.ts +2 -2
  94. package/test/examples/asciiMaze/fitness.types.ts +65 -0
  95. package/test/examples/asciiMaze/interfaces.ts +64 -1352
  96. package/test/examples/asciiMaze/mazeMovement/README.md +356 -0
  97. package/test/examples/asciiMaze/mazeMovement/finalization/README.md +49 -0
  98. package/test/examples/asciiMaze/mazeMovement/finalization/mazeMovement.finalization.ts +138 -0
  99. package/test/examples/asciiMaze/mazeMovement/mazeMovement.constants.ts +101 -0
  100. package/test/examples/asciiMaze/mazeMovement/mazeMovement.services.ts +230 -0
  101. package/test/examples/asciiMaze/mazeMovement/mazeMovement.ts +299 -0
  102. package/test/examples/asciiMaze/mazeMovement/mazeMovement.types.ts +185 -0
  103. package/test/examples/asciiMaze/mazeMovement/mazeMovement.utils.ts +153 -0
  104. package/test/examples/asciiMaze/mazeMovement/policy/README.md +91 -0
  105. package/test/examples/asciiMaze/mazeMovement/policy/mazeMovement.policy.ts +467 -0
  106. package/test/examples/asciiMaze/mazeMovement/runtime/README.md +95 -0
  107. package/test/examples/asciiMaze/mazeMovement/runtime/mazeMovement.runtime.ts +354 -0
  108. package/test/examples/asciiMaze/mazeMovement/shaping/README.md +124 -0
  109. package/test/examples/asciiMaze/mazeMovement/shaping/mazeMovement.shaping.ts +459 -0
  110. package/test/examples/asciiMaze/mazeMovement.ts +12 -2978
  111. package/test/examples/flappy_bird/Trace-20260309T191949.json +24124 -0
  112. package/test/examples/flappy_bird/browser-entry/README.md +1129 -0
  113. package/test/examples/flappy_bird/browser-entry/browser-entry.host.utils.ts +4 -324
  114. package/test/examples/flappy_bird/browser-entry/browser-entry.network-view.utils.ts +6 -399
  115. package/test/examples/flappy_bird/browser-entry/browser-entry.playback.utils.ts +1 -717
  116. package/test/examples/flappy_bird/browser-entry/browser-entry.spawn.utils.ts +11 -31
  117. package/test/examples/flappy_bird/browser-entry/browser-entry.visualization.utils.ts +15 -893
  118. package/test/examples/flappy_bird/browser-entry/host/README.md +307 -0
  119. package/test/examples/flappy_bird/browser-entry/host/host.resize.service.ts +1 -295
  120. package/test/examples/flappy_bird/browser-entry/host/host.ts +562 -6
  121. package/test/examples/flappy_bird/browser-entry/host/resize/README.md +274 -0
  122. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.constants.ts +31 -0
  123. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.services.ts +360 -0
  124. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.ts +117 -0
  125. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.types.ts +63 -0
  126. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.utils.ts +250 -0
  127. package/test/examples/flappy_bird/browser-entry/network-view/README.md +399 -0
  128. package/test/examples/flappy_bird/browser-entry/network-view/network-view.topology.utils.ts +255 -0
  129. package/test/examples/flappy_bird/browser-entry/network-view/network-view.ts +802 -7
  130. package/test/examples/flappy_bird/browser-entry/playback/README.md +684 -0
  131. package/test/examples/flappy_bird/browser-entry/playback/background/README.md +277 -0
  132. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/README.md +770 -0
  133. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.cache.services.ts +178 -0
  134. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.constants.ts +107 -0
  135. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.utils.ts +518 -0
  136. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.math.utils.ts +117 -0
  137. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.pulse.utils.ts +233 -0
  138. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.services.ts +211 -0
  139. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.ts +48 -0
  140. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.types.ts +212 -0
  141. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.utils.ts +81 -0
  142. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.cache.services.ts +96 -0
  143. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.constants.ts +62 -0
  144. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.services.ts +244 -0
  145. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.ts +53 -0
  146. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.types.ts +68 -0
  147. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.utils.ts +100 -0
  148. package/test/examples/flappy_bird/browser-entry/playback/frame-render/README.md +310 -0
  149. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.service.ts +92 -0
  150. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.services.ts +272 -0
  151. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types.ts +39 -0
  152. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.utils.ts +493 -0
  153. package/test/examples/flappy_bird/browser-entry/playback/playback.constants.ts +1 -1
  154. package/test/examples/flappy_bird/browser-entry/playback/playback.frame-render.service.ts +4 -0
  155. package/test/examples/flappy_bird/browser-entry/playback/playback.snapshot.utils.ts +44 -0
  156. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.service.ts +39 -122
  157. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.services.ts +272 -0
  158. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.types.ts +62 -0
  159. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.utils.ts +11 -4
  160. package/test/examples/flappy_bird/browser-entry/playback/playback.ts +409 -8
  161. package/test/examples/flappy_bird/browser-entry/playback/playback.types.ts +4 -12
  162. package/test/examples/flappy_bird/browser-entry/runtime/README.md +235 -0
  163. package/test/examples/flappy_bird/browser-entry/runtime/runtime.evolution-launch.service.ts +45 -0
  164. package/test/examples/flappy_bird/browser-entry/runtime/runtime.lifecycle.service.ts +81 -0
  165. package/test/examples/flappy_bird/browser-entry/runtime/runtime.startup.service.ts +74 -0
  166. package/test/examples/flappy_bird/browser-entry/runtime/runtime.ts +31 -121
  167. package/test/examples/flappy_bird/browser-entry/runtime/runtime.types.ts +36 -0
  168. package/test/examples/flappy_bird/browser-entry/visualization/README.md +557 -0
  169. package/test/examples/flappy_bird/browser-entry/visualization/visualization.constants.ts +110 -0
  170. package/test/examples/flappy_bird/browser-entry/visualization/visualization.draw.service.ts +957 -19
  171. package/test/examples/flappy_bird/browser-entry/visualization/visualization.legend.utils.ts +138 -3
  172. package/test/examples/flappy_bird/browser-entry/visualization/visualization.topology.utils.ts +3 -27
  173. package/test/examples/flappy_bird/browser-entry/visualization/visualization.ts +1 -23
  174. package/test/examples/flappy_bird/browser-entry/worker-channel/README.md +156 -0
  175. package/test/examples/flappy_bird/constants/README.md +1179 -0
  176. package/test/examples/flappy_bird/constants/constants.network-view.ts +24 -0
  177. package/test/examples/flappy_bird/constants/constants.palette.ts +7 -0
  178. package/test/examples/flappy_bird/constants/constants.starfield.ts +78 -3
  179. package/test/examples/flappy_bird/environment/README.md +143 -0
  180. package/test/examples/flappy_bird/environment/environment.observation.utils.ts +1 -19
  181. package/test/examples/flappy_bird/environment/environment.step.service.ts +3 -66
  182. package/test/examples/flappy_bird/evaluation/README.md +130 -0
  183. package/test/examples/flappy_bird/evaluation/evaluation.fitness.utils.ts +1 -1
  184. package/test/examples/flappy_bird/evaluation/evaluation.rollout.service.ts +5 -375
  185. package/test/examples/flappy_bird/evaluation/rollout/README.md +291 -0
  186. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.constants.ts +30 -0
  187. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.service.ts +58 -0
  188. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.services.ts +310 -0
  189. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.types.ts +56 -0
  190. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.utils.ts +368 -0
  191. package/test/examples/flappy_bird/flappy-evolution-worker/README.md +618 -0
  192. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.playback.service.ts +7 -7
  193. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.frame.service.ts +364 -0
  194. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.types.ts +14 -0
  195. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.utils.ts +4 -201
  196. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.ts +184 -345
  197. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.warm-start.service.ts +291 -0
  198. package/test/examples/flappy_bird/flappy.simulation.shared.utils.ts +5 -0
  199. package/test/examples/flappy_bird/simulation-shared/README.md +417 -0
  200. package/test/examples/flappy_bird/simulation-shared/observation/README.md +183 -0
  201. package/test/examples/flappy_bird/simulation-shared/observation/observation.features.utils.ts +301 -0
  202. package/test/examples/flappy_bird/simulation-shared/observation/observation.ts +9 -0
  203. package/test/examples/flappy_bird/simulation-shared/observation/observation.vector.utils.ts +59 -0
  204. package/test/examples/flappy_bird/simulation-shared/simulation-shared.observation.utils.ts +5 -403
  205. package/test/examples/flappy_bird/simulation-shared/simulation-shared.spawn.utils.ts +20 -6
  206. package/test/examples/flappy_bird/{evaluation/evaluation.statistics.utils.ts → simulation-shared/simulation-shared.statistics.utils.ts} +23 -8
  207. package/test/examples/flappy_bird/trainer/README.md +563 -0
  208. package/test/examples/flappy_bird/trainer/evaluation/README.md +199 -0
  209. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.constants.ts +9 -0
  210. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.services.ts +73 -0
  211. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.ts +165 -0
  212. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.types.ts +25 -0
  213. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.utils.ts +161 -0
  214. package/test/examples/flappy_bird/trainer/trainer.evaluation.service.ts +13 -0
  215. package/test/examples/flappy_bird/trainer/trainer.report.service.services.ts +181 -0
  216. package/test/examples/flappy_bird/trainer/trainer.report.service.ts +126 -0
  217. package/test/examples/flappy_bird/trainer/trainer.selection.utils.ts +89 -0
  218. package/test/examples/flappy_bird/trainer/trainer.ts +11 -553
  219. package/test/examples/flappy_bird/browser-entry/browser-entry.utils.ts +0 -12
  220. package/test/examples/flappy_bird/environment/environment.ts +0 -7
  221. package/test/examples/flappy_bird/evaluation/evaluation.ts +0 -7
  222. package/test/examples/flappy_bird/simulation-shared/simulation-shared.ts +0 -15
  223. package/test/examples/flappy_bird/trainer/trainer.statistics.utils.ts +0 -78
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Shared mutable services for the dedicated mazeMovement module.
3
+ *
4
+ * This module owns the pooled buffers, PRNG state, output-history plumbing,
5
+ * and shared run-scoped counters used by the legacy MazeMovement facade while
6
+ * Step 2 incrementally moves helper categories into the dedicated boundary.
7
+ */
8
+
9
+ import type { INetwork } from '../interfaces';
10
+ import type {
11
+ MazeMovementBufferPools,
12
+ MazeMovementRunServiceState,
13
+ } from './mazeMovement.types';
14
+ import {
15
+ isFiniteNumberArray,
16
+ materializePath,
17
+ nextPowerOfTwo,
18
+ } from './mazeMovement.utils';
19
+
20
+ interface InternalMazeMovementBufferPools {
21
+ visitedFlags: Uint8Array | null;
22
+ visitCounts: Uint16Array | null;
23
+ pathX: Int32Array | null;
24
+ pathY: Int32Array | null;
25
+ gridCapacity: number;
26
+ pathCapacity: number;
27
+ cachedWidth: number;
28
+ cachedHeight: number;
29
+ }
30
+
31
+ const BUFFER_POOLS: InternalMazeMovementBufferPools = {
32
+ visitedFlags: null,
33
+ visitCounts: null,
34
+ pathX: null,
35
+ pathY: null,
36
+ gridCapacity: 0,
37
+ pathCapacity: 0,
38
+ cachedWidth: 0,
39
+ cachedHeight: 0,
40
+ };
41
+
42
+ const RUN_SERVICE_STATE: MazeMovementRunServiceState = {
43
+ saturations: 0,
44
+ noMoveStreak: 0,
45
+ prevDistanceStep: undefined,
46
+ };
47
+
48
+ const PRNG_STATE = {
49
+ value: null as Uint32Array | null,
50
+ };
51
+
52
+ /**
53
+ * Expose the shared mutable run-scoped state used across helper categories.
54
+ *
55
+ * @returns The singleton mutable run-state object for the current process.
56
+ */
57
+ export function getMazeMovementRunServiceState(): MazeMovementRunServiceState {
58
+ return RUN_SERVICE_STATE;
59
+ }
60
+
61
+ /**
62
+ * Reset the shared mutable run-scoped state before a new simulation begins.
63
+ *
64
+ * @returns The reused singleton state after reset.
65
+ */
66
+ export function resetMazeMovementRunServiceState(): MazeMovementRunServiceState {
67
+ RUN_SERVICE_STATE.saturations = 0;
68
+ RUN_SERVICE_STATE.noMoveStreak = 0;
69
+ RUN_SERVICE_STATE.prevDistanceStep = undefined;
70
+ return RUN_SERVICE_STATE;
71
+ }
72
+
73
+ /**
74
+ * Ensure the pooled grid and path buffers are initialized for a run.
75
+ *
76
+ * @param width - Maze width in cells.
77
+ * @param height - Maze height in cells.
78
+ * @param maxSteps - Maximum path length expected for the run.
79
+ * @returns The initialized pooled buffer surface.
80
+ */
81
+ export function initializeMazeMovementBufferPools(
82
+ width: number,
83
+ height: number,
84
+ maxSteps: number,
85
+ ): MazeMovementBufferPools {
86
+ const requiredCellCount = width * height;
87
+
88
+ if (
89
+ BUFFER_POOLS.visitedFlags == null ||
90
+ requiredCellCount > BUFFER_POOLS.gridCapacity
91
+ ) {
92
+ const newCellCapacity = nextPowerOfTwo(requiredCellCount);
93
+ BUFFER_POOLS.visitedFlags = new Uint8Array(newCellCapacity);
94
+ BUFFER_POOLS.visitCounts = new Uint16Array(newCellCapacity);
95
+ BUFFER_POOLS.gridCapacity = newCellCapacity;
96
+ } else {
97
+ BUFFER_POOLS.visitedFlags.fill(0, 0, requiredCellCount);
98
+ BUFFER_POOLS.visitCounts!.fill(0, 0, requiredCellCount);
99
+ }
100
+
101
+ const requiredPathEntries = maxSteps + 1;
102
+ if (
103
+ BUFFER_POOLS.pathX == null ||
104
+ requiredPathEntries > BUFFER_POOLS.pathCapacity
105
+ ) {
106
+ const newPathCapacity = nextPowerOfTwo(requiredPathEntries);
107
+ BUFFER_POOLS.pathX = new Int32Array(newPathCapacity);
108
+ BUFFER_POOLS.pathY = new Int32Array(newPathCapacity);
109
+ BUFFER_POOLS.pathCapacity = newPathCapacity;
110
+ }
111
+
112
+ BUFFER_POOLS.cachedWidth = width;
113
+ BUFFER_POOLS.cachedHeight = height;
114
+
115
+ return requireMazeMovementBufferPools();
116
+ }
117
+
118
+ /**
119
+ * Return the initialized pooled buffer surface for the current run.
120
+ *
121
+ * @returns The shared buffer pools.
122
+ * @throws Error when a caller reaches the pools before initialization.
123
+ */
124
+ export function requireMazeMovementBufferPools(): MazeMovementBufferPools {
125
+ if (
126
+ BUFFER_POOLS.visitedFlags == null ||
127
+ BUFFER_POOLS.visitCounts == null ||
128
+ BUFFER_POOLS.pathX == null ||
129
+ BUFFER_POOLS.pathY == null
130
+ ) {
131
+ throw new Error(
132
+ 'Maze movement buffer pools were used before initialization.',
133
+ );
134
+ }
135
+
136
+ return BUFFER_POOLS as MazeMovementBufferPools;
137
+ }
138
+
139
+ /**
140
+ * Read the currently cached maze dimensions for bounds and index helpers.
141
+ *
142
+ * @returns Cached width and height for the active pooled buffers.
143
+ */
144
+ export function getMazeMovementBufferMetadata(): {
145
+ cachedWidth: number;
146
+ cachedHeight: number;
147
+ } {
148
+ return {
149
+ cachedWidth: BUFFER_POOLS.cachedWidth,
150
+ cachedHeight: BUFFER_POOLS.cachedHeight,
151
+ };
152
+ }
153
+
154
+ /**
155
+ * Convert a cell coordinate into the pooled linear grid index.
156
+ *
157
+ * @param x - Zero-based maze column.
158
+ * @param y - Zero-based maze row.
159
+ * @returns Linearized index used by pooled grid buffers.
160
+ */
161
+ export function indexMazeMovementCell(x: number, y: number): number {
162
+ return Math.imul(y, BUFFER_POOLS.cachedWidth) + x;
163
+ }
164
+
165
+ /**
166
+ * Generate a pseudo-random number in the range `[0, 1)`.
167
+ *
168
+ * @returns A deterministic or host-random unit float for exploration logic.
169
+ */
170
+ export function randomMazeMovementUnit(): number {
171
+ const pooledState = PRNG_STATE.value;
172
+ if (pooledState == null || pooledState.length === 0) {
173
+ return Math.random();
174
+ }
175
+
176
+ const current = (pooledState[0] + 0x6d2b79f5) >>> 0;
177
+ pooledState[0] = current;
178
+
179
+ let mixed = current;
180
+ mixed = Math.imul(mixed ^ (mixed >>> 15), mixed | 1) >>> 0;
181
+ mixed =
182
+ (mixed ^ (mixed + Math.imul(mixed ^ (mixed >>> 7), mixed | 61))) >>> 0;
183
+
184
+ const final32 = (mixed ^ (mixed >>> 14)) >>> 0;
185
+ return final32 / 4_294_967_296;
186
+ }
187
+
188
+ /**
189
+ * Read the reflected `_lastStepOutputs` network history when present.
190
+ *
191
+ * @param network - Network that may carry the reflected output history.
192
+ * @returns Sanitized output history or `undefined` when absent or invalid.
193
+ */
194
+ export function readMazeMovementOutputHistory(
195
+ network: INetwork,
196
+ ): number[][] | undefined {
197
+ const historyCandidate = Reflect.get(network as object, '_lastStepOutputs');
198
+ if (!Array.isArray(historyCandidate)) return undefined;
199
+ return historyCandidate.every(isFiniteNumberArray)
200
+ ? (historyCandidate as number[][])
201
+ : undefined;
202
+ }
203
+
204
+ /**
205
+ * Persist the reflected `_lastStepOutputs` network history.
206
+ *
207
+ * @param network - Network receiving the reflected output history.
208
+ * @param history - Bounded output-history payload to persist.
209
+ */
210
+ export function writeMazeMovementOutputHistory(
211
+ network: INetwork,
212
+ history: number[][],
213
+ ): void {
214
+ Reflect.set(network as object, '_lastStepOutputs', history);
215
+ }
216
+
217
+ /**
218
+ * Materialize the active pooled path buffers into a fresh tuple array.
219
+ *
220
+ * @param length - Number of active path entries to copy.
221
+ * @returns A newly allocated materialized path snapshot.
222
+ */
223
+ export function materializeMazeMovementPath(
224
+ length: number,
225
+ ): [number, number][] {
226
+ const bufferPools = requireMazeMovementBufferPools();
227
+ return materializePath(length, bufferPools.pathX, bufferPools.pathY);
228
+ }
229
+
230
+ export {};
@@ -0,0 +1,299 @@
1
+ /**
2
+ * Public MazeMovement facade for the dedicated mazeMovement module boundary.
3
+ *
4
+ * The folder now owns runtime helpers, policy helpers, shaping helpers, and
5
+ * finalization logic. This file keeps the user-facing API in one place while
6
+ * the implementation stays split into focused helpers.
7
+ */
8
+
9
+ import type { INetwork } from '../interfaces';
10
+ import type {
11
+ DirectionSelectionStats,
12
+ MazeMovementSimulationResult,
13
+ SimulationState,
14
+ } from './mazeMovement.types';
15
+ import { MAZE_MOVEMENT_CONSTANTS } from './mazeMovement.constants';
16
+ import {
17
+ decideMazeMovementDirection,
18
+ selectMazeMovementDirection,
19
+ applyMazeMovementEpsilonExploration,
20
+ applyMazeMovementForcedExploration,
21
+ applyMazeMovementProximityGreedy,
22
+ } from './policy/mazeMovement.policy';
23
+ import {
24
+ applyMazeMovementPostActionPenalties,
25
+ executeMazeMovementAndRewards,
26
+ maybeTerminateMazeMovementDeepStagnation,
27
+ } from './shaping/mazeMovement.shaping';
28
+ import {
29
+ finalizeFailedMazeMovementRun,
30
+ finalizeSuccessfulMazeMovementRun,
31
+ } from './finalization/mazeMovement.finalization';
32
+ import {
33
+ buildMazeMovementVisionAndDistance,
34
+ createMazeMovementRunState,
35
+ isMazeMovementCellOpen,
36
+ recordMazeMovementVisitAndPenalties,
37
+ } from './runtime/mazeMovement.runtime';
38
+
39
+ const C = MAZE_MOVEMENT_CONSTANTS;
40
+
41
+ /**
42
+ * Maze movement entry surface used by fitness evaluation and evolution runs.
43
+ *
44
+ * The public API intentionally remains class-based so existing example imports
45
+ * do not change while the implementation lives under the dedicated module.
46
+ */
47
+ export class MazeMovement {
48
+ /** Reused integer coordinate scratch for hot-path movement helpers. */
49
+ static #COORDINATE_SCRATCH = new Int32Array(2);
50
+
51
+ /**
52
+ * Determine whether a candidate target cell is inside bounds and not a wall.
53
+ *
54
+ * @param encodedMaze - Maze grid to inspect.
55
+ * @param position - Candidate `[x, y]` position.
56
+ * @returns True when the target cell can be entered.
57
+ */
58
+ static isValidMove(
59
+ encodedMaze: ReadonlyArray<ReadonlyArray<number>>,
60
+ position: readonly [number, number],
61
+ ): boolean;
62
+
63
+ /**
64
+ * Determine whether a candidate target cell is inside bounds and not a wall.
65
+ *
66
+ * @param encodedMaze - Maze grid to inspect.
67
+ * @param x - Candidate maze column.
68
+ * @param y - Candidate maze row.
69
+ * @returns True when the target cell can be entered.
70
+ */
71
+ static isValidMove(
72
+ encodedMaze: ReadonlyArray<ReadonlyArray<number>>,
73
+ x: number,
74
+ y: number,
75
+ ): boolean;
76
+
77
+ static isValidMove(
78
+ encodedMaze: ReadonlyArray<ReadonlyArray<number>>,
79
+ positionOrX: readonly [number, number] | number,
80
+ yMaybe?: number,
81
+ ): boolean {
82
+ if (typeof positionOrX === 'number') {
83
+ const candidateColumn = positionOrX | 0;
84
+ const candidateRow = (yMaybe ?? 0) | 0;
85
+ return isMazeMovementCellOpen(
86
+ encodedMaze,
87
+ candidateColumn,
88
+ candidateRow,
89
+ MazeMovement.#COORDINATE_SCRATCH,
90
+ );
91
+ }
92
+
93
+ if (!Array.isArray(positionOrX) || positionOrX.length !== 2) return false;
94
+
95
+ const [candidateColumn, candidateRow] = positionOrX;
96
+ return isMazeMovementCellOpen(
97
+ encodedMaze,
98
+ candidateColumn,
99
+ candidateRow,
100
+ MazeMovement.#COORDINATE_SCRATCH,
101
+ );
102
+ }
103
+
104
+ /**
105
+ * Move the agent one step in the requested direction when the target cell is open.
106
+ *
107
+ * @param encodedMaze - Maze grid used for collision checks.
108
+ * @param position - Current agent position.
109
+ * @param direction - Direction index in the action space.
110
+ * @returns New position when the move is valid, otherwise the original position.
111
+ * @example
112
+ * const moved = MazeMovement.moveAgent(encodedMaze, [3, 2], 1);
113
+ */
114
+ static moveAgent(
115
+ encodedMaze: ReadonlyArray<ReadonlyArray<number>>,
116
+ position: readonly [number, number],
117
+ direction: number,
118
+ ): [number, number] {
119
+ if (direction === C.NO_MOVE) {
120
+ return [position[0], position[1]];
121
+ }
122
+
123
+ const nextPosition: [number, number] = [position[0], position[1]];
124
+ if (direction >= 0 && direction < C.ACTION_DIM) {
125
+ const [deltaColumn, deltaRow] = C.DIRECTION_DELTAS[direction];
126
+ nextPosition[0] += deltaColumn;
127
+ nextPosition[1] += deltaRow;
128
+ }
129
+
130
+ return MazeMovement.isValidMove(encodedMaze, nextPosition)
131
+ ? nextPosition
132
+ : [position[0], position[1]];
133
+ }
134
+
135
+ /**
136
+ * Convert raw network outputs into a chosen action plus diagnostics.
137
+ *
138
+ * @param outputs - Raw action logits for the four maze directions.
139
+ * @returns Chosen direction plus softmax and entropy diagnostics.
140
+ * @example
141
+ * const stats = MazeMovement.selectDirection([0.2, 1.4, -0.1, 0]);
142
+ */
143
+ static selectDirection(outputs: number[]): DirectionSelectionStats {
144
+ return selectMazeMovementDirection(outputs);
145
+ }
146
+
147
+ /**
148
+ * Simulate one full maze episode for a network-controlled agent.
149
+ *
150
+ * @param network - Policy network used to choose actions.
151
+ * @param encodedMaze - Maze grid for the active episode.
152
+ * @param startPos - Start coordinate.
153
+ * @param exitPos - Exit coordinate.
154
+ * @param distanceMap - Optional precomputed distance map.
155
+ * @param maxSteps - Maximum allowed step count before termination.
156
+ * @returns Final simulation result including path, fitness, and progress.
157
+ */
158
+ static simulateAgent(
159
+ network: INetwork,
160
+ encodedMaze: number[][],
161
+ startPos: readonly [number, number],
162
+ exitPos: readonly [number, number],
163
+ distanceMap?: number[][],
164
+ maxSteps: number = C.DEFAULT_MAX_STEPS,
165
+ ): MazeMovementSimulationResult {
166
+ const simulationState = createMazeMovementRunState(
167
+ encodedMaze,
168
+ startPos,
169
+ distanceMap,
170
+ maxSteps,
171
+ );
172
+
173
+ while (simulationState.steps < maxSteps) {
174
+ simulationState.steps++;
175
+
176
+ // Step 1: refresh visit bookkeeping, perception, and policy choice.
177
+ MazeMovement.#processPerceptionAndPolicy(
178
+ simulationState,
179
+ network,
180
+ encodedMaze,
181
+ exitPos,
182
+ distanceMap,
183
+ );
184
+
185
+ // Step 2: execute the chosen action, apply shaping, and stop if needed.
186
+ const shouldStop = MazeMovement.#processMovementAndShaping(
187
+ simulationState,
188
+ encodedMaze,
189
+ distanceMap,
190
+ );
191
+ if (shouldStop) break;
192
+
193
+ // Step 3: finalize immediately when the exit is reached.
194
+ if (MazeMovement.#hasReachedExit(simulationState, exitPos)) {
195
+ return finalizeSuccessfulMazeMovementRun(simulationState, maxSteps);
196
+ }
197
+ }
198
+
199
+ return finalizeFailedMazeMovementRun(
200
+ simulationState,
201
+ encodedMaze,
202
+ startPos,
203
+ exitPos,
204
+ distanceMap,
205
+ );
206
+ }
207
+
208
+ /**
209
+ * Refresh visit bookkeeping, perception state, and direction policy.
210
+ *
211
+ * @param simulationState - Mutable run state for the active episode.
212
+ * @param network - Policy network used for action selection.
213
+ * @param encodedMaze - Maze grid used for the run.
214
+ * @param exitPos - Exit coordinate for the run.
215
+ * @param distanceMap - Optional precomputed distance map.
216
+ */
217
+ static #processPerceptionAndPolicy(
218
+ simulationState: SimulationState,
219
+ network: INetwork,
220
+ encodedMaze: number[][],
221
+ exitPos: readonly [number, number],
222
+ distanceMap?: number[][],
223
+ ): void {
224
+ recordMazeMovementVisitAndPenalties(simulationState);
225
+ buildMazeMovementVisionAndDistance(
226
+ simulationState,
227
+ encodedMaze,
228
+ exitPos,
229
+ distanceMap,
230
+ );
231
+ decideMazeMovementDirection(
232
+ simulationState,
233
+ network,
234
+ MazeMovement.#COORDINATE_SCRATCH,
235
+ );
236
+ applyMazeMovementProximityGreedy(
237
+ simulationState,
238
+ encodedMaze,
239
+ distanceMap,
240
+ MazeMovement.#COORDINATE_SCRATCH,
241
+ );
242
+ applyMazeMovementEpsilonExploration(
243
+ simulationState,
244
+ encodedMaze,
245
+ MazeMovement.#COORDINATE_SCRATCH,
246
+ );
247
+ applyMazeMovementForcedExploration(
248
+ simulationState,
249
+ encodedMaze,
250
+ MazeMovement.#COORDINATE_SCRATCH,
251
+ );
252
+ }
253
+
254
+ /**
255
+ * Execute the selected move, apply post-action shaping, and evaluate stop rules.
256
+ *
257
+ * @param simulationState - Mutable run state for the active episode.
258
+ * @param encodedMaze - Maze grid used for movement and distance lookup.
259
+ * @param distanceMap - Optional precomputed distance map.
260
+ * @returns True when the episode should stop after this step.
261
+ */
262
+ static #processMovementAndShaping(
263
+ simulationState: SimulationState,
264
+ encodedMaze: number[][],
265
+ distanceMap?: number[][],
266
+ ): boolean {
267
+ executeMazeMovementAndRewards(
268
+ simulationState,
269
+ encodedMaze,
270
+ distanceMap,
271
+ MazeMovement.#COORDINATE_SCRATCH,
272
+ );
273
+ applyMazeMovementPostActionPenalties(
274
+ simulationState,
275
+ MazeMovement.#COORDINATE_SCRATCH,
276
+ );
277
+ return maybeTerminateMazeMovementDeepStagnation(
278
+ simulationState,
279
+ MazeMovement.#COORDINATE_SCRATCH,
280
+ );
281
+ }
282
+
283
+ /**
284
+ * Determine whether the current state has reached the maze exit.
285
+ *
286
+ * @param simulationState - Mutable run state for the active episode.
287
+ * @param exitPos - Exit coordinate for the run.
288
+ * @returns True when the agent position matches the exit coordinate.
289
+ */
290
+ static #hasReachedExit(
291
+ simulationState: SimulationState,
292
+ exitPos: readonly [number, number],
293
+ ): boolean {
294
+ return (
295
+ simulationState.position[0] === exitPos[0] &&
296
+ simulationState.position[1] === exitPos[1]
297
+ );
298
+ }
299
+ }
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Shared type surface for the dedicated mazeMovement module.
3
+ *
4
+ * Step 2 moves internal simulation contracts here first so later helper files
5
+ * can depend on one narrow typed surface.
6
+ */
7
+
8
+ /**
9
+ * Initialized pooled buffers shared across maze movement simulations.
10
+ *
11
+ * These pools are reused between runs to keep the hot path allocation-light
12
+ * while preserving a narrow typed seam for service helpers.
13
+ */
14
+ export interface MazeMovementBufferPools {
15
+ /** Reused per-cell visited flags aligned to the current maze dimensions. */
16
+ visitedFlags: Uint8Array;
17
+ /** Reused per-cell visit counters aligned to the current maze dimensions. */
18
+ visitCounts: Uint16Array;
19
+ /** Reused X-coordinate path buffer for the active simulation. */
20
+ pathX: Int32Array;
21
+ /** Reused Y-coordinate path buffer for the active simulation. */
22
+ pathY: Int32Array;
23
+ /** Cached maze width used by index helpers. */
24
+ cachedWidth: number;
25
+ /** Cached maze height used by bounds helpers. */
26
+ cachedHeight: number;
27
+ }
28
+
29
+ /**
30
+ * Mutable run-scoped service state shared by the mazeMovement facade.
31
+ *
32
+ * The dedicated services module owns these counters so later runtime, policy,
33
+ * and shaping helpers can depend on one explicit mutable surface instead of
34
+ * directly reaching into class-private state.
35
+ */
36
+ export interface MazeMovementRunServiceState {
37
+ /** Rolling saturation counter used by adaptive penalties and epsilon logic. */
38
+ saturations: number;
39
+ /** Consecutive no-move counter used to force exploration. */
40
+ noMoveStreak: number;
41
+ /** Previous distance value fed into the next vision-builder call. */
42
+ prevDistanceStep: number | undefined;
43
+ }
44
+
45
+ /**
46
+ * Diagnostic telemetry produced when selecting a direction from network logits.
47
+ *
48
+ * Encapsulates the chosen direction along with entropy and probability data so
49
+ * downstream helpers can apply shaping rewards and penalties without
50
+ * rederiving softmax statistics on hot paths.
51
+ */
52
+ export interface DirectionSelectionStats {
53
+ /** Chosen action index (0..#ACTION_DIM-1) or -1 when no move is selected. */
54
+ direction: number;
55
+ /** Defensive copy of per-action softmax probabilities. */
56
+ softmax: number[];
57
+ /** Normalised entropy of the action distribution in [0,1]. */
58
+ entropy: number;
59
+ /** Probability assigned to the chosen action. */
60
+ maxProb: number;
61
+ /** Probability assigned to the runner-up action. */
62
+ secondProb: number;
63
+ }
64
+
65
+ /**
66
+ * Internal aggregate state used during a single agent simulation run.
67
+ *
68
+ * Purpose:
69
+ * - Hold all derived runtime values, counters and diagnostic stats used by the
70
+ * MazeMovement simulation helpers. This shape is intentionally rich so tests
71
+ * and visualisers can inspect intermediate state when debugging.
72
+ *
73
+ * Notes:
74
+ * - This interface remains internal to the mazeMovement module boundary.
75
+ * - Property descriptions are explicit to surface helpful tooltips in editors.
76
+ */
77
+ export interface SimulationState {
78
+ /** Current mutable agent position as [x, y]. */
79
+ position: [number, number];
80
+
81
+ /** Number of simulation steps executed so far (increments each loop). */
82
+ steps: number;
83
+
84
+ /** Number of entries in the recorded path (index into pooled PathX/PathY). */
85
+ pathLength: number;
86
+
87
+ /** Count of distinct cells visited during this run. */
88
+ visitedUniqueCount: number;
89
+
90
+ /** True when a precomputed distance map was supplied to the simulation. */
91
+ hasDistanceMap: boolean;
92
+
93
+ /** Optional precomputed distance map (rows × cols) used for fast heuristics. */
94
+ distanceMap?: number[][];
95
+
96
+ /** Minimum observed distance-to-exit reached so far (lower is better). */
97
+ minDistanceToExit: number;
98
+
99
+ /** Accumulated shaping reward derived from forward progress signals. */
100
+ progressReward: number;
101
+
102
+ /** Bonus accumulated when entering previously unvisited cells. */
103
+ newCellExplorationBonus: number;
104
+
105
+ /** Accumulated penalty from invalid moves, loops and other negative signals. */
106
+ invalidMovePenalty: number;
107
+
108
+ /** Index of the previous action/direction taken (-1 for no-move). */
109
+ prevAction: number;
110
+
111
+ /** Steps elapsed since the last observed improvement toward the goal. */
112
+ stepsSinceImprovement: number;
113
+
114
+ /** Last global distance-to-exit used for long-term improvement checks. */
115
+ lastDistanceGlobal: number;
116
+
117
+ /** Number of steps flagged as 'saturated' (network overconfident/flat outputs). */
118
+ saturatedSteps: number;
119
+
120
+ /** Recent positions sliding window used to detect local oscillation/stagnation. */
121
+ recentPositions: [number, number][];
122
+
123
+ /** Penalty applied when agent is oscillating in a tight local region. */
124
+ localAreaPenalty: number;
125
+
126
+ /** Counters of moves taken per direction index (N,E,S,W). */
127
+ directionCounts: number[];
128
+
129
+ /** Ring buffer storing recent visited cell indices for A↔B loop detection. */
130
+ moveHistoryRing: Int32Array;
131
+
132
+ /** Current number of populated entries in `moveHistoryRing`. */
133
+ moveHistoryLength: number;
134
+ /** Index pointer (head) into the circular moveHistoryRing. */
135
+ moveHistoryHead: number;
136
+ /** Current linearized cell index for the agent position. */
137
+ currentCellIndex: number;
138
+ /** Penalty accumulated for short A<->B oscillation detection. */
139
+ loopPenalty: number;
140
+ /** Penalty applied for returning to any recent cell (memory-based). */
141
+ memoryPenalty: number;
142
+ /** Dynamic revisit penalty scaled by per-cell visit counts. */
143
+ revisitPenalty: number;
144
+ /** Visit count at the current cell (derived from VisitCounts pool). */
145
+ visitsAtCurrent: number;
146
+ /** Current distance-to-goal measured at agent position. */
147
+ distHere: number;
148
+ /** Per-step perception/vision vector built for the network. */
149
+ vision: number[];
150
+ /** Network action statistics (softmax, entropy, etc.) populated each step. */
151
+ actionStats: DirectionSelectionStats | null;
152
+ /** Currently selected direction index (0..3) or #-NO_MOVE. */
153
+ direction: number;
154
+ /** Whether the agent moved on the last executed action. */
155
+ moved: boolean;
156
+ /** Distance value measured before executing the current action (previous step). */
157
+ prevDistance: number;
158
+
159
+ /** When true the simulation loop should terminate early due to safety triggers. */
160
+ earlyTerminate: boolean;
161
+ }
162
+
163
+ /**
164
+ * Result shape returned by `MazeMovement.simulateAgent`.
165
+ *
166
+ * This contract matches the legacy inline return annotation so callers can
167
+ * keep depending on the current fields while the dedicated module boundary is
168
+ * being extracted.
169
+ */
170
+ export interface MazeMovementSimulationResult {
171
+ /** Whether the run reached the maze exit. */
172
+ success: boolean;
173
+ /** Number of steps executed before success or failure finalization. */
174
+ steps: number;
175
+ /** Materialized path snapshot for the finished run. */
176
+ path: readonly [number, number][];
177
+ /** Final shaped fitness for the run. */
178
+ fitness: number;
179
+ /** Progress percentage toward the exit. */
180
+ progress: number;
181
+ /** Optional fraction of saturated steps observed during the run. */
182
+ saturationFraction?: number;
183
+ /** Optional action-entropy summary derived from direction counts. */
184
+ actionEntropy?: number;
185
+ }