Back to leaderboard

Ultimate Bot

Created 9/10/2026

Active

test of a AI generated bot

Avg score

5.742

Wins

10227

Losses

2664

Win rate

71.5%

Total battles: 14306

Score history

Score trend over the last 199 battles

Avg: 5.742

Recent battles

Source

export default function bot({ history, memory }) {
  memory = memory ?? {
    mode: "unknown",
    probes: 0,
    opponentDefects: 0
  };

  const n = history.length;

  // Primeira jogada: cooperação
  if (n === 0) {
    return ["C", memory];
  }

  const last = history.at(-1);
  const oppLast = last.opponent;

  if (oppLast === "D") {
    memory.opponentDefects++;
  }

  /*
   * =========================================================
   * 1. DETECTAR O TIPO DE ADVERSÁRIO
   * =========================================================
   */

  if (n >= 6) {
    let allC = true;
    let allD = true;

    for (const round of history) {
      if (round.opponent !== "C") allC = false;
      if (round.opponent !== "D") allD = false;
    }

    // Sempre coopera -> EXPLORAR
    if (allC) {
      memory.mode = "cooperator";
    }

    // Sempre defeta -> não vale a pena cooperar
    if (allD) {
      memory.mode = "defector";
    }
  }

  /*
   * =========================================================
   * 2. COOPERADOR PURO
   * =========================================================
   */

  if (memory.mode === "cooperator") {
    // Se sabemos que ele nunca retaliou, aproveitamos.
    return ["D", memory];
  }

  /*
   * =========================================================
   * 3. DEFETOR PURO
   * =========================================================
   */

  if (memory.mode === "defector") {
    return ["D", memory];
  }

  /*
   * =========================================================
   * 4. DETECTAR TIT-FOR-TAT / ADVERSÁRIO REATIVO
   * =========================================================
   */

  if (n >= 5) {
    let matches = 0;
    let comparisons = 0;

    /*
     * O adversário jogou na ronda anterior em resposta
     * à nossa jogada.
     */
    for (let i = 1; i < n; i++) {
      const ourPrevious = history[i - 1].you;
      const theirMove = history[i].opponent;

      comparisons++;

      if (ourPrevious === theirMove) {
        matches++;
      }
    }

    const reactionRate = matches / comparisons;

    if (reactionRate >= 0.8) {
      memory.mode = "reactive";
    }
  }

  /*
   * =========================================================
   * 5. CONTRA ADVERSÁRIOS REATIVOS
   * =========================================================
   */

  if (memory.mode === "reactive") {
    /*
     * Tit-for-Tat:
     * C -> C
     * D -> D
     *
     * Isto evita guerras desnecessárias.
     */
    return [oppLast, memory];
  }

  /*
   * =========================================================
   * 6. PADRÕES REPETITIVOS
   * =========================================================
   */

  if (n >= 6) {
    const a = history.at(-1).opponent;
    const b = history.at(-2).opponent;
    const c = history.at(-3).opponent;

    const d = history.at(-4).opponent;
    const e = history.at(-5).opponent;
    const f = history.at(-6).opponent;

    // Padrão ABABAB
    if (a === c && c === e && b === d && d === f && a !== b) {
      // Prevemos que ele vai alternar.
      // Se esperamos C, cooperamos; se esperamos D, defendemos.
      return [b, memory];
    }

    // Padrão AAA...
    if (a === b && b === c && c === d && d === e) {
      if (a === "C") {
        memory.mode = "cooperator";
        return ["D", memory];
      } else {
        memory.mode = "defector";
        return ["D", memory];
      }
    }
  }

  /*
   * =========================================================
   * 7. ESTRATÉGIA PADRÃO: PAVLOV / WIN-STAY LOSE-SHIFT
   * =========================================================
   *
   * Se a última ronda nos deu:
   *
   * 2 ou 3 pontos -> repetimos
   * 0 ou 1 ponto   -> mudamos
   */

  const ourLast = last.you;

  let myScore;

  if (ourLast === "C" && oppLast === "C") {
    myScore = 2;
  } else if (ourLast === "D" && oppLast === "C") {
    myScore = 3;
  } else if (ourLast === "C" && oppLast === "D") {
    myScore = 0;
  } else {
    myScore = 1;
  }

  // Resultado bom -> manter
  if (myScore >= 2) {
    return [ourLast, memory];
  }

  // Resultado mau -> mudar
  return [ourLast === "C" ? "D" : "C", memory];
}