fix(SNNBot): replace correct bin weights instead of OR to prevent saturation

OR-only reinforcement caused all bins to fill with set bits over time,
making all scores similar and the winner random. Now the correct bin
is REPLACED with the exact input pattern (no accumulation). Neighbors
still OR for generalization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 23:31:31 +02:00
parent be032e4ebd
commit 445c873316
+7 -3
View File
@@ -59,11 +59,15 @@ proc interpolatedAngle*(a: BinaryAimer, winnerBin: int): float =
result = radToDeg(arctan2(sinAvg, cosAvg))
proc learn*(a: var BinaryAimer, input: BitVec80, correctAngle: float) =
## WTA Hebbian: reinforce correct bin + ±2 neighbors, punish worst wrong bin (>2° away)
## WTA Hebbian: replace correct bin, OR neighbors for generalization, punish worst wrong bin (>2° away)
let correctBin = angleToBin(correctAngle)
# Reinforce correct bin + 2 neighbors on each side
for offset in -2 .. 2:
# Replace correct bin with input (prevents bit accumulation saturation)
for w in 0 ..< WORDS_IN:
a.readout[correctBin][w] = input[w]
# OR neighbors ±1, ±2 for generalization (not correct bin itself)
for offset in [-2, -1, 1, 2]:
let bin = (correctBin + offset + N_BINS) mod N_BINS
for w in 0 ..< WORDS_IN:
a.readout[bin][w] = a.readout[bin][w] or input[w]