Back to leaderboard

bigger memory

Created 9/13/2026

Active

yh

Avg score

8.668

Wins

521

Losses

4647

Win rate

4.6%

Total battles: 11213

Score history

Score trend over the last 200 battles

Avg: 8.668

Recent battles

Source

// Game Payoffs
const PAYOFF_REWARD = 2;       // Mutual Cooperation (C, C)
const PAYOFF_SUCKER = 0;       // Sucker's Payoff (C, D)
const PAYOFF_TEMPTATION = 3;   // Temptation to Defect (D, C)
const PAYOFF_PUNISHMENT = 1;   // Mutual Defection (D, D)

const PAYOFFS = {
  C: { C: PAYOFF_REWARD, D: PAYOFF_SUCKER },
  D: { C: PAYOFF_TEMPTATION, D: PAYOFF_PUNISHMENT }
};

// Strategy Settings
const INITIAL_COOP_PROB = 0.8;
const LOW_COOP_PROB = 0.0;
const MAX_COOP_PROB = 1.0;
const PROB_INCREMENT = 0.05;

const INITIAL_INTERVAL = 10;
const SCORE_BENCHMARK = 1.5;
const TRUST_THRESHOLD = 0.5;

// Weight Multiplier for the most recent round
const LAST_ROUND_WEIGHT = 3;

// Move Constants
const MOVE_COOPERATE = "C";
const MOVE_DEFECT = "D";

export default function bot({ history, memory }) {
  const round = history.length;

  // Warm-up phase: Strict Tit-for-Tat
  if (round < INITIAL_INTERVAL) {
    if (round === 0) {
      return [MOVE_COOPERATE, memory];
    }
    const lastOpponentMove = history.at(-1).opponent;
    return [lastOpponentMove, memory];
  }

  // Initialize or restore state
  const state = memory ?? { prob: INITIAL_COOP_PROB };

  // Window for the most recent INITIAL_INTERVAL rounds
  const recentWindow = history.slice(-INITIAL_INTERVAL);
  const totalWindowWeight = (recentWindow.length - 1) + LAST_ROUND_WEIGHT;

  // Calculate weighted trust rating over the last INITIAL_INTERVAL rounds
  let weightedCoopSum = 0;
  for (let i = 0; i < recentWindow.length; i++) {
    const weight = i === recentWindow.length - 1 ? LAST_ROUND_WEIGHT : 1;
    if (recentWindow[i].opponent === MOVE_COOPERATE) {
      weightedCoopSum += weight;
    }
  }
  const weightedTrustScore = weightedCoopSum / totalWindowWeight;

  // Calculate weighted average score over the last INITIAL_INTERVAL rounds
  let weightedPointsSum = 0;
  for (let i = 0; i < recentWindow.length; i++) {
    const weight = i === recentWindow.length - 1 ? LAST_ROUND_WEIGHT : 1;
    const roundScore = PAYOFFS[recentWindow[i].you][recentWindow[i].opponent];
    weightedPointsSum += roundScore * weight;
  }
  const weightedAvgScore = weightedPointsSum / totalWindowWeight;

  // Decision logic evaluated every single round
  if (weightedTrustScore < TRUST_THRESHOLD) {
    // Trust takes absolute priority
    state.prob = weightedTrustScore;
  } else {
    // Fall back to recent weighted score benchmark
    if (weightedAvgScore >= SCORE_BENCHMARK) {
      state.prob = Math.min(MAX_COOP_PROB, Math.max(state.prob, INITIAL_COOP_PROB) + PROB_INCREMENT);
    } else {
      state.prob = LOW_COOP_PROB;
    }
  }

  // Roll move based on current calculated probability
  const move = Math.random() < state.prob ? MOVE_COOPERATE : MOVE_DEFECT;

  return [move, state];
}