Sigma Bot v1
Created 9/7/2026
Active
Sigma Bot v1 is a highly adaptive predictive bot that analyzes its opponent’s behavior and changes its strategy throughout the game. It looks for patterns, predicts future moves, and tries to take advantage of predictable opponents while still cooperating when it makes sense.
Avg score
7.306
Wins
8598
Losses
6833
Win rate
44.5%
Total battles: 19331
Score history
Avg: 7.306
Recent battles
- Oliver 2 9.42 vs 9.42 Sigma Bot v1 Tie
- big ULTIMATE guy 7.87 vs 8.13 Sigma Bot v1
- Sigma Bot v1 7.97 vs 1.23 ITS CORN!🌽 THE ONLY THING TH...
- Abdullah Ezzat 5.9 vs 6.2 Sigma Bot v1
- Sigma Bot v1 5.16 vs 5.05 detective grudger v1
- Sigma Bot v1 8.5 vs 5.29 Tit for Two Tats
- Sigma Bot v1 6.53 vs 5.13 adaptive bot
- playing.to.win 6.44 vs 6.25 Sigma Bot v1
- Sigma Bot v1 9.38 vs 9.45 PureRandomBotTrust
- Sigma Bot v1 9.44 vs 9.44 tit for tat Tie
- Veritasium 9.41 vs 9.41 Sigma Bot v1 Tie
- Sigma Bot v1 5.05 vs 5.12 Bumwinnah4
- Sigma Bot v1 9.5 vs 9.5 crownbotv2 Tie
- Agnes-distill-Tachyon-v3 5.29 vs 8.5 Sigma Bot v1
- C! 1.21 vs 8.05 Sigma Bot v1
- NexBot VI 5.1 vs 5.04 Sigma Bot v1
- Sigma Bot v1 7.28 vs 8.16 Swimmingbot3
- ApexUltimate v3 5.02 vs 5.23 Sigma Bot v1
- Smarty Pants V1 5.11 vs 5.04 Sigma Bot v1
- Sigma Bot v1 5.15 vs 5.2 pumpkin🎃🎃🎃
- Sigma Bot v1 4.9 vs 5.07 Dev defect def
- OmegaTFT 9.44 vs 9.44 Sigma Bot v1 Tie
- Number 1 1.23 vs 8.05 Sigma Bot v1
- Sigma Bot v1 4.93 vs 5.06 defector
- Sigma Bot v1 4.93 vs 5.05 All Defect
- Slim Jeans 9.03 vs 9.09 Sigma Bot v1
- Sigma Bot v1 9.48 vs 9.48 evil meow limited edition Tie
- tic tacs 9.51 vs 9.51 Sigma Bot v1 Tie
- zyxl bot 5.08 vs 4.89 Sigma Bot v1
- zyxl bot 5.09 vs 4.88 Sigma Bot v1
- yes 5.08 vs 4.89 Sigma Bot v1
- The Detective (#4) 1.24 vs 7.97 Sigma Bot v1
- Sigma Bot v1 8.7 vs 8.07 WILLIAM SMITH
- Swimmingbot3 8.61 vs 7.78 Sigma Bot v1
- Always Defect 5.09 vs 4.88 Sigma Bot v1
- EYKEYKEYKEYKEYKEYK 9.2 vs 9.14 Sigma Bot v1
- yes 5.08 vs 4.9 Sigma Bot v1
- 3Blue1Brown 9.44 vs 9.44 Sigma Bot v1 Tie
- goatbotv3.2 4.94 vs 5.27 Sigma Bot v1
- Bot 1 4.76 vs 5.26 Sigma Bot v1
- Pls work! 6.24 vs 7.09 Sigma Bot v1
- Sigma Bot v1 6.36 vs 6.3 ٠new X
- something 5.02 vs 5.21 Sigma Bot v1
- crownbotv3 9.43 vs 9.43 Sigma Bot v1 Tie
- Sigma Bot v1 9.02 vs 9.07 Sherlock Holmes
- ITS CORN!🌽 THE ONLY THING TH... 1.24 vs 7.97 Sigma Bot v1
- Sigma Bot v1 8.48 vs 8.14 DR MUNDO v0.2
- adaptative v2.1 4.98 vs 5.14 Sigma Bot v1
- Sigma Bot v1 6.47 vs 3.23 RanBot3003
- BIUN V3 4.44 vs 6.06 Sigma Bot v1
Source
// This is Sigma Bot v1
const C = "C";
const D = "D";
function payoff(a, o) {
if (a === C && o === C) return 2;
if (a === D && o === C) return 3;
if (a === D && o === D) return 1;
return 0;
}
const MODELS = [
{
name: "alwaysC",
move(h) {
return C;
}
},
{
name: "alwaysD",
move(h) {
return D;
}
},
{
name: "TFT",
move(h) {
if (h.length === 0) return C;
return h[h.length - 1].opponent;
}
},
{
name: "grudger",
move(h) {
for (let i = 0; i < h.length; i++) {
if (h[i].opponent === D) return D;
}
return C;
}
},
{
name: "tit2",
move(h) {
const n = h.length;
if (
n >= 2 &&
h[n - 1].opponent === D &&
h[n - 2].opponent === D
) {
return D;
}
return C;
}
},
{
name: "pavlov",
move(h) {
if (h.length === 0) return C;
const last = h[h.length - 1];
const opponentPayoff = payoff(
last.opponent,
last.you
);
if (opponentPayoff === 2 || opponentPayoff === 3) {
return last.opponent;
}
return last.opponent === C ? D : C;
}
},
{
name: "detective",
move(h) {
const n = h.length;
if (n === 0) return C;
if (n === 1) return D;
if (n === 2) return C;
if (
h[0].opponent === C &&
h[1].opponent === C &&
h[2].opponent === D
) {
return C;
}
return D;
}
},
{
name: "suspiciousTFT",
move(h) {
if (h.length === 0) return D;
return h[h.length - 1].opponent;
}
},
{
name: "alternator",
move(h) {
return h.length % 2 === 0 ? C : D;
}
},
{
name: "generous2",
move(h) {
const n = h.length;
if (
n >= 2 &&
h[n - 1].opponent === D &&
h[n - 2].opponent === D
) {
return D;
}
return C;
}
},
{
name: "antiTFT",
move(h) {
if (h.length === 0) return D;
return h[h.length - 1].opponent === C ? D : C;
}
}
];
function fingerprint(history) {
const n = history.length;
const start = Math.max(0, n - 28);
const results = new Array(MODELS.length);
for (let m = 0; m < MODELS.length; m++) {
const model = MODELS[m];
let mistakes = 0;
const opponentView = [];
for (let i = 0; i < n; i++) {
const predicted = model.move(opponentView);
if (
i >= start &&
predicted !== history[i].opponent
) {
mistakes++;
}
opponentView.push({
you: history[i].opponent,
opponent: history[i].you
});
}
results[m] = {
name: model.name,
mistakes
};
}
results.sort((a, b) => a.mistakes - b.mistakes);
return results;
}
function knownBestMove(name, history) {
const n = history.length;
if (name === "alwaysC") {
return D;
}
if (name === "alwaysD") {
return D;
}
if (name === "detective") {
return D;
}
if (name === "alternator") {
return D;
}
if (name === "antiTFT") {
return D;
}
if (
name === "TFT" ||
name === "suspiciousTFT"
) {
return C;
}
if (name === "grudger") {
for (let i = 0; i < n; i++) {
if (history[i].opponent === D) {
return D;
}
}
return C;
}
if (
name === "tit2" ||
name === "generous2"
) {
if (
n > 0 &&
history[n - 1].you === D
) {
return C;
}
return D;
}
if (name === "pavlov") {
if (
n > 0 &&
history[n - 1].opponent === D
) {
return D;
}
return C;
}
return null;
}
function contextModel(history) {
const MAX_CONTEXT = 3;
const WINDOW = 80;
const start = Math.max(
0,
history.length - WINDOW
);
const h = history.slice(start);
const counts = Array.from(
{ length: MAX_CONTEXT + 1 },
() => new Map()
);
function pairCode(you, opponent) {
if (you === C && opponent === C) return 0;
if (you === C && opponent === D) return 1;
if (you === D && opponent === C) return 2;
return 3;
}
for (let i = 0; i < h.length; i++) {
const maxK = Math.min(
MAX_CONTEXT,
i
);
for (let k = 0; k <= maxK; k++) {
let key = "";
for (
let j = i - k;
j < i;
j++
) {
key += pairCode(
h[j].you,
h[j].opponent
);
}
let arr = counts[k].get(key);
if (!arr) {
arr = [0, 0];
counts[k].set(key, arr);
}
if (h[i].opponent === C) {
arr[0]++;
} else {
arr[1]++;
}
}
}
function predict(recentCodes) {
let numerator = 0;
let denominator = 0;
const maxK = Math.min(
MAX_CONTEXT,
recentCodes.length
);
for (
let k = maxK;
k >= 0;
k--
) {
let key = "";
for (
let j = recentCodes.length - k;
j < recentCodes.length;
j++
) {
key += recentCodes[j];
}
const arr = counts[k].get(key);
if (!arr) {
continue;
}
const total = arr[0] + arr[1];
if (total === 0) {
continue;
}
const p =
(arr[0] + 1) /
(total + 2);
const weight =
Math.pow(2, k) *
(total / (total + 5));
numerator += p * weight;
denominator += weight;
}
if (denominator === 0) {
return 0.5;
}
return numerator / denominator;
}
return {
pairCode,
predict
};
}
function fallbackMove(history) {
const n = history.length;
if (n === 0) {
return C;
}
let recentC = 0;
let recentD = 0;
const begin = Math.max(
0,
n - 8
);
for (let i = begin; i < n; i++) {
if (history[i].opponent === C) {
recentC++;
} else {
recentD++;
}
}
if (n >= 8 && recentC >= 7) {
return D;
}
if (n >= 8 && recentD >= 7) {
return D;
}
let retaliation = 0;
let retaliationTotal = 0;
let recovery = 0;
let recoveryTotal = 0;
for (let i = 1; i < n; i++) {
if (history[i - 1].you === D) {
retaliationTotal++;
if (history[i].opponent === D) {
retaliation++;
}
}
if (history[i - 1].you === C) {
recoveryTotal++;
if (history[i].opponent === C) {
recovery++;
}
}
}
if (retaliationTotal >= 3) {
const r =
retaliation / retaliationTotal;
const recoveryRate =
recoveryTotal > 0
? recovery / recoveryTotal
: 0;
if (
r >= 0.72 &&
recoveryRate > 0.62
) {
return C;
}
if (r > 0.72) {
return D;
}
}
const model =
contextModel(history);
const recentCodes =
history
.slice(-3)
.map(x =>
model.pairCode(
x.you,
x.opponent
)
);
const pNow =
model.predict(recentCodes);
function evaluateAction(action) {
const currentExpected =
pNow * payoff(action, C) +
(1 - pNow) * payoff(action, D);
let futureExpected = 0;
const outcomes = [
[C, pNow],
[D, 1 - pNow]
];
for (
const [opponentMove, probability]
of outcomes
) {
const nextCodes =
recentCodes
.concat([
model.pairCode(
action,
opponentMove
)
])
.slice(-3);
const pNext =
model.predict(nextCodes);
const bestNext =
Math.max(
2 * pNext,
1 + 2 * pNext
);
futureExpected +=
probability * bestNext;
}
return (
currentExpected +
0.72 * futureExpected
);
}
const cooperateValue =
evaluateAction(C);
const defectValue =
evaluateAction(D);
if (
pNow > 0.73 &&
retaliationTotal >= 2 &&
retaliation / retaliationTotal > 0.6
) {
return C;
}
return defectValue >= cooperateValue
? D
: C;
}
export default function bot({ history }) {
const n = history.length;
// Opening sequence: C, C, D, C
if (n === 0) {
return [C, null];
}
if (n === 1) {
return [C, null];
}
if (n === 2) {
return [D, null];
}
if (n === 3) {
return [C, null];
}
const fingerprints =
fingerprint(history);
const best =
fingerprints[0];
const second =
fingerprints[1];
if (
best.mistakes <= 1 &&
(
second.mistakes -
best.mistakes >= 2 ||
best.mistakes === 0
)
) {
const bestMove =
knownBestMove(
best.name,
history
);
if (bestMove) {
return [bestMove, null];
}
}
if (n >= 5) {
const a =
history[n - 3];
const b =
history[n - 2];
const c =
history[n - 1];
if (
a.you === D &&
a.opponent === C &&
b.you === C &&
b.opponent === D &&
c.you === C &&
c.opponent === D
) {
return [D, null];
}
if (
a.you === C &&
a.opponent === D &&
b.you === D &&
b.opponent === D &&
c.opponent === C
) {
return [C, null];
}
}
return [
fallbackMove(history),
null
];
}