Opportunist v3
Created 9/13/2026
Active
Plays nice by default, forgives the occasional betrayal so grudges don't spiral, cuts off anyone who's clearly hostile and quietly tests soft targets to see if they'll let it get away with defecting for good.
Avg score
5.733
Wins
6712
Losses
3270
Win rate
64.0%
Total battles: 10494
Score history
Avg: 5.733
Recent battles
- Opportunist v3 4.9 vs 5.25 ITS CORN!🌽 THE ONLY THING TH...
- Opportunist v3 4.92 vs 5.21 Sherlock Holmes
- Opportunist v3 6.43 vs 3.68 RanBot3003
- Opportunist v3 6.5 vs 5.25 fightAggression
- Chicken banana 🐔 🍌 5.92 vs 6.41 Opportunist v3
- ThisIsRandom 3.37 vs 6.4 Opportunist v3
- Test 5.37 vs 5.21 Opportunist v3
- Opportunist v3 5.45 vs 5.41 Královecký kraj
- Opportunist v3 5.66 vs 5.49 JustBeatIt V5
- Opportunist v3 5.36 vs 5.36 test 1c Tie
- adaptative v2.1 5.86 vs 6.14 Opportunist v3
- Opportunist v3 4.85 vs 5.11 Firstborn v3.2
- Opportunist v3 5.15 vs 5.25 The Ultimate Bot v3
- ApexUltimate v3 5.32 vs 5.19 Opportunist v3
- detective 5.25 vs 4.9 Opportunist v3
- Opportunist v3 5.72 vs 5.65 OmegaTitForTat
- Opportunist v3 5.67 vs 5.36 ICY EXODILED AIC A-TRONICS
- neuralAdapter V1 5.19 vs 6.52 Opportunist v3
- Opportunist v3 6.13 vs 5.87 ٠new X
- Opportunist v3 5.51 vs 5.51 PureRandomBotTrust+ Tie
- Opportunist v3 5.68 vs 5.62 tieseeker v5
- JBot-2 5.4 vs 5.13 Opportunist v3
- Opportunist v3 8.46 vs 3.08 Always cooperates
- Smarty Pants V1 5.58 vs 5.64 Opportunist v3
- Opportunist v3 5.12 vs 5.19 Mark3
- Královecký kraj 5.53 vs 5.58 Opportunist v3
- evil meow limited edition 5.17 vs 5.77 Opportunist v3
- always defect 5.1 vs 4.86 Opportunist v3
- Opportunist v3 5.94 vs 5.52 Not my bot
- Opportunist v3 8.14 vs 2.21 RanBot3004
- better 4.96 vs 6.57 Opportunist v3
- Defender 3.0v 5.55 vs 5.6 Opportunist v3
- Opportunist v3 5.71 vs 5.65 slash
- Opportunist v3 5.21 vs 5.35 Test
- Opportunist v3 5.7 vs 5.64 Tuff9
- Forgiver 5.06 vs 4.88 Opportunist v3
- Opportunist v3 5.56 vs 5.5 OmegaTFT
- Opportunist v3 6.24 vs 3.59 ThisIsRandom
- playing.to.win 5.54 vs 5.37 Opportunist v3
- Opportunist v3 4.9 vs 5.05 Forgiver
- no 2.62 vs 8.36 Opportunist v3
- Opportunist v3 5.7 vs 5.64 tit for tat
- PureRandomBotTrust 5.43 vs 5.43 Opportunist v3 Tie
- Bot 1 5.47 vs 5.67 Opportunist v3
- Opportunist v3 8.2 vs 3.7 detective grudger v1
- Opportunist v3 5.2 vs 5.33 jingolfika
- Opportunist v3 6.46 vs 3.3 FlippityFloppity v3
- Opportunist v3 5.21 vs 5.35 jingolfika
- Cooperate2 5.67 vs 5.74 Opportunist v3
- Redgux 5.5 vs 5.55 Opportunist v3
Source
export default function bot({ history, memory }) {
memory = memory ?? {
oppD: 0,
confidence: 0,
probing: false,
nextProbe: 8,
probes: 0,
brutal: false,
stalemate: 0,
forgiving: false,
rejections: 0,
}
const round = history.length
if (round === 0) return ["C", memory]
const last = history.at(-1)
if (last.opponent === "D") memory.oppD++
if (last.opponent !== "D") memory.stalemate = 0
if (memory.forgiving) {
memory.forgiving = false
if (last.opponent === "D") memory.rejections++
else memory.rejections = 0
}
if (memory.brutal) return ["D", memory]
const prevOpponent = round >= 2 ? history.at(-2).opponent : null
const isolatedDefect = last.opponent === "D" && prevOpponent !== "D"
if (isolatedDefect) memory.probes++
if (memory.probes >= 3) {
memory.brutal = true
return ["D", memory]
}
if (memory.probing) {
memory.probing = false
if (last.opponent === "D") {
memory.confidence = 0
memory.nextProbe = round + 20
} else {
memory.confidence++
memory.nextProbe = round + Math.max(2, 6 - memory.confidence)
}
}
if (memory.confidence >= 6) return ["D", memory]
const rate = memory.oppD / round
if (round >= 10 && rate > 0.75) {
if (memory.rejections >= 2 || Math.random() >= 0.05) return ["D", memory]
memory.forgiving = true
return ["C", memory]
}
if (last.opponent === "D" && prevOpponent === "D") {
memory.stalemate++
if (memory.rejections >= 2) return ["D", memory]
const forgiveChance = Math.min(0.4, 0.1 + memory.stalemate * 0.02)
if (Math.random() < forgiveChance) {
memory.stalemate = 0
memory.forgiving = true
return ["C", memory]
}
return ["D", memory]
}
if (last.opponent !== "D" && round >= memory.nextProbe) {
memory.probing = true
return ["D", memory]
}
return ["C", memory]
}