neuralAdapter V1
Created 9/7/2026
Active
Uses a tiny RNN model that gradually learns the opponent's bot strategy
Avg score
8.544
Wins
137
Losses
7834
Win rate
0.8%
Total battles: 17622
Score history
Avg: 8.544
Recent battles
- Tuff9 10 vs 10 neuralAdapter V1 Tie
- neuralAdapter V1 10 vs 10 Aura67 Tie
- neuralAdapter V1 9.61 vs 9.67 test 1e
- Test 10 vs 10 neuralAdapter V1 Tie
- neuralAdapter V1 6.23 vs 7.71 Defect Half v2
- neuralAdapter V1 5.17 vs 6.43 Reverse Tit for Tat
- neuralAdapter V1 5.57 vs 6.84 raju
- neuralAdapter V1 10 vs 10 Defected_Boy111 Tie
- fightAggression 10 vs 10 neuralAdapter V1 Tie
- crownbotv2 10 vs 10 neuralAdapter V1 Tie
- Tachyon-v1 9.99 vs 9.95 neuralAdapter V1
- neuralAdapter V1 9.81 vs 9.81 Columbus Tie
- kind detective 9.92 vs 9.92 neuralAdapter V1 Tie
- Sherlock Holmes 9.7 vs 9.64 neuralAdapter V1
- Number 1 9.75 vs 8.88 neuralAdapter V1
- Reactant V3.5.1 10 vs 10 neuralAdapter V1 Tie
- neuralAdapter V1 9.85 vs 9.85 RanBot3004 Tie
- neuralAdapter V1 5.1 vs 7.1 random
- BeeBot2 9.57 vs 9.5 neuralAdapter V1
- neuralAdapter V1 10 vs 10 GradualAdaptive Tie
- neuralAdapter V1 10 vs 10 Grudger Tie
- neuralAdapter V1 5.19 vs 6.52 Opportunist v3
- Smarty Pants V1 10 vs 10 neuralAdapter V1 Tie
- neuralAdapter V1 10 vs 10 big grim guy Tie
- take a fuckin' guess 8.71 vs 5.31 neuralAdapter V1
- neuralAdapter V1 10 vs 10 OmegaTFT Tie
- Cobra 10 vs 10 neuralAdapter V1 Tie
- neuralAdapter V1 10 vs 10 bigger memory Tie
- neuralAdapter V1 10 vs 10 big GRIM guy Tie
- DR MUNDO v0.2 10 vs 10 neuralAdapter V1 Tie
- neuralAdapter V1 9.63 vs 9.69 test 1e
- neuralAdapter V1 9.91 vs 9.91 ApexUltimate v8 Tie
- neuralAdapter V1 10 vs 10 playing.to.win Tie
- neuralAdapter V1 10 vs 10 Bot 1 Tie
- evil meow limited edition 10 vs 10 neuralAdapter V1 Tie
- kind but faster detective 9.92 vs 9.92 neuralAdapter V1 Tie
- neuralAdapter V1 9.91 vs 9.91 PureRandomBotTrust Tie
- tft bot 10 vs 10 neuralAdapter V1 Tie
- neuralAdapter V1 9.75 vs 9.75 llama(1.6) Tie
- neuralAdapter V1 10 vs 10 fightAggression Tie
- test(1.2) 10 vs 10 neuralAdapter V1 Tie
- detective grudger v1 9.88 vs 9.46 neuralAdapter V1
- neuralAdapter V1 10 vs 10 Reactant V3.2 Tie
- OmegaTFT 10 vs 10 neuralAdapter V1 Tie
- ٠new X 10 vs 10 neuralAdapter V1 Tie
- neuralAdapter V1 10 vs 10 Zeus 2 Tie
- Tieseeeeeeeeeeeeker v2 10 vs 10 neuralAdapter V1 Tie
- neuralAdapter V1 4.87 vs 6.03 AaravC Bot 1
- test 1c 9.61 vs 9.55 neuralAdapter V1
- Dilemma-Bot-Hackclub 10 vs 10 neuralAdapter V1 Tie
Source
export default function bot({ history, memory }) {
const H = 4;
const LR = 0.08;
// ---------------------------------------------------------
// ACTIVATION FUNCTIONS
// ---------------------------------------------------------
function sigmoid(x) {
return 1 / (1 + Math.exp(-x));
}
// ---------------------------------------------------------
// INITIALIZE RNN
// ---------------------------------------------------------
if (memory == null) {
// Deterministic small initial weights.
// Avoid Math.random() so every match starts identically.
memory = {
Wx: [
[ 0.10, -0.08],
[-0.06, 0.12],
[ 0.08, 0.05],
[-0.10, 0.07]
],
Wh: [
[ 0.05, -0.03, 0.02, 0.01],
[-0.02, 0.04, 0.01, -0.03],
[ 0.03, 0.01, -0.04, 0.02],
[ 0.01, -0.02, 0.03, 0.04]
],
bh: [0, 0, 0, 0],
Wo: [0.05, -0.05, 0.05, -0.05],
// Start slightly biased toward cooperation.
bo: -0.2,
// Current hidden state
h: [0, 0, 0, 0],
// Information required to train the previous prediction
lastH: null,
lastInput: null,
lastPrediction: null,
rounds: 0
};
}
// ---------------------------------------------------------
// TRAIN ON THE RESULT OF OUR PREVIOUS PREDICTION
// ---------------------------------------------------------
if (
history.length > 0 &&
memory.lastPrediction != null &&
memory.lastH != null
) {
const actualMove = history.at(-1).opponent;
// D = 1
// C = 0
const target = actualMove === "D" ? 1 : 0;
const prediction = memory.lastPrediction;
// For sigmoid + binary cross entropy:
//
// dL/dz = prediction - target
const outputError = prediction - target;
// Save the old output weights because they are required
// for calculating the hidden error.
const oldWo = memory.Wo.slice();
// -------------------------
// Train output layer
// -------------------------
for (let i = 0; i < H; i++) {
memory.Wo[i] -=
LR * outputError * memory.lastH[i];
}
memory.bo -= LR * outputError;
// -------------------------
// Train hidden layer
//
// This is ONE-STEP backprop.
// We are NOT yet propagating through the entire history.
// -------------------------
for (let i = 0; i < H; i++) {
const h = memory.lastH[i];
// derivative of tanh:
//
// d/dx tanh(x) = 1 - tanh(x)^2
const hiddenError =
outputError *
oldWo[i] *
(1 - h * h);
// Input -> hidden weights
for (let j = 0; j < 2; j++) {
memory.Wx[i][j] -=
LR *
hiddenError *
memory.lastInput[j];
}
// Hidden bias
memory.bh[i] -= LR * hiddenError;
}
}
// ---------------------------------------------------------
// FIRST ROUND
// ---------------------------------------------------------
// We have no history from which to predict anything.
if (history.length === 0) {
memory.rounds++;
return ["C", memory];
}
// ---------------------------------------------------------
// CONVERT THE MOST RECENT ROUND INTO RNN INPUT
// ---------------------------------------------------------
const lastRound = history.at(-1);
const input = [
lastRound.you === "D" ? 1 : 0,
lastRound.opponent === "D" ? 1 : 0
];
// ---------------------------------------------------------
// RNN FORWARD PASS
//
// h(t) = tanh(
// Wx*x(t)
// + Wh*h(t-1)
// + bh
// )
// ---------------------------------------------------------
const newH = new Array(H).fill(0);
for (let i = 0; i < H; i++) {
let sum = memory.bh[i];
// Input contribution
for (let j = 0; j < 2; j++) {
sum += memory.Wx[i][j] * input[j];
}
// Recurrent contribution
for (let j = 0; j < H; j++) {
sum += memory.Wh[i][j] * memory.h[j];
}
newH[i] = Math.tanh(sum);
}
// ---------------------------------------------------------
// OUTPUT
//
// prediction = P(opponent defects NEXT round)
// ---------------------------------------------------------
let z = memory.bo;
for (let i = 0; i < H; i++) {
z += memory.Wo[i] * newH[i];
}
const prediction = sigmoid(z);
// ---------------------------------------------------------
// SAVE INFORMATION FOR NEXT ROUND'S TRAINING
// ---------------------------------------------------------
memory.h = newH;
memory.lastH = newH.slice();
memory.lastInput = input.slice();
memory.lastPrediction = prediction;
memory.rounds++;
// ---------------------------------------------------------
// STRATEGY V1
// ---------------------------------------------------------
let move;
// During early learning, use Tit-for-Tat.
if (history.length < 8) {
move = lastRound.opponent;
} else {
// RNN predicts probability of opponent defecting.
//
// If it thinks defection is likely, defend ourselves.
// Otherwise cooperate.
//
// Conservative threshold for V1.
move = prediction > 0.55 ? "D" : "C";
}
return [move, memory];
}