Back to leaderboard

Slim Jeans

Created 9/14/2026

Active

Like a nerd with slim jeans.

Avg score

8.490

Wins

1766

Losses

2405

Win rate

18.3%

Total battles: 9657

Score history

Score trend over the last 199 battles

Avg: 8.490

Recent battles

Source

const TREE = [[0,1,110],[0,2,78],[0,3,65],[0,4,52],[0,5,41],[0,6,33],[0,7,26],[0,8,19],[0,9,18],[0,10,-1],[0,11,15],[0,12,-1],[0,13,14],[-1,2,-1],[-1,2,-1],[1,16,-1],[0,17,-1],[-1,0,-1],[-1,1,-1],[1,20,-1],[0,21,25],[0,22,-1],[0,23,-1],[0,24,-1],[-1,0,-1],[-1,2,-1],[1,27,28],[-1,3,-1],[1,-1,29],[0,-1,30],[1,31,32],[-1,2,-1],[-1,1,-1],[1,34,-1],[0,35,-1],[0,36,-1],[0,37,-1],[0,38,-1],[0,39,-1],[0,40,-1],[-1,0,-1],[0,42,-1],[0,43,44],[-1,0,-1],[0,45,51],[0,-1,46],[1,47,-1],[0,48,-1],[0,49,-1],[1,50,-1],[-1,4,-1],[-1,2,-1],[1,53,64],[0,54,-1],[0,55,-1],[0,56,-1],[0,57,-1],[0,58,-1],[1,59,63],[1,60,61],[-1,0,-1],[0,62,-1],[-1,2,-1],[-1,4,-1],[-1,1,-1],[0,66,-1],[0,67,68],[-1,0,-1],[1,69,77],[0,-1,70],[1,71,-1],[1,72,-1],[1,73,-1],[1,74,-1],[1,75,-1],[0,76,-1],[-1,0,-1],[-1,2,-1],[1,79,109],[0,80,98],[1,81,-1],[0,82,90],[1,83,-1],[1,84,-1],[1,85,-1],[1,86,-1],[1,87,-1],[1,88,-1],[1,89,-1],[-1,1,-1],[0,91,-1],[0,92,-1],[0,93,-1],[0,94,-1],[0,95,-1],[0,96,-1],[0,97,-1],[-1,0,-1],[0,99,-1],[1,100,108],[0,-1,101],[0,102,-1],[1,103,-1],[1,-1,104],[1,-1,105],[1,106,107],[-1,1,-1],[-1,0,-1],[-1,1,-1],[-1,1,-1],[1,111,136],[0,112,124],[1,113,-1],[0,114,115],[-1,1,-1],[0,116,-1],[0,117,-1],[0,118,-1],[0,119,-1],[0,120,-1],[0,121,-1],[0,122,-1],[0,123,-1],[-1,0,-1],[0,125,135],[0,126,-1],[0,127,-1],[0,128,-1],[0,129,-1],[0,130,-1],[0,131,-1],[0,132,-1],[0,133,-1],[0,134,-1],[-1,0,-1],[-1,1,-1],[0,137,142],[1,138,141],[1,139,140],[-1,2,-1],[-1,1,-1],[-1,1,-1],[0,143,153],[0,144,-1],[0,145,-1],[0,146,-1],[0,147,-1],[0,148,-1],[0,149,-1],[0,150,-1],[0,151,-1],[0,152,-1],[-1,1,-1],[1,154,163],[0,-1,155],[0,-1,156],[0,157,-1],[0,158,-1],[0,159,-1],[0,160,-1],[0,161,-1],[0,162,-1],[-1,0,-1],[1,-1,164],[1,-1,165],[1,-1,166],[1,-1,167],[1,-1,168],[1,-1,169],[1,-1,170],[1,-1,171],[-1,1,-1]];
const WEIGHTS = {"W1":[[-0.3112476172772456,-1.10104513719832,-2.267832483975167,-0.01910208006130487,1.3611926359008708,-2.7871573642175616,-0.07788723842419762],[2.945755081977242,-1.066726911620305,-2.672827090786731,-0.9782359056682042,-1.5202391892048885,4.3983918235484625,-0.4288550690727308],[2.8362358325330037,0.19770917999391824,1.3480129467245505,-1.372417333212501,3.997020152903984,-2.672741445879556,0.2761888825611258],[-2.9599853262297473,-2.0356914722698445,-2.602392838733512,2.951554382379807,-1.664686750224209,2.006644856815207,-4.3353166134415915],[1.8842182619291052,-1.2560873785985929,1.4207929945231494,1.2777440347099782,0.75870664601506,-0.6134854634468593,0.3991268836146747]],"W2":[2.7661018169451035,2.1793055738088256,0.8153239520429725,-2.5013104326876263,2.3971889901676726],"b":-4.907675734184572};

const CANDIDATES = [
    () => "C",
    () => "D",
    (h) => h.length ? h.at(-1).opponent : "C",
    (h) => h.length >= 2 && h.at(-1).opponent === "D" && h.at(-2).opponent === "D" ? "D" : "C",
    (h) => { 
        if (!h.length) return "C";
        const last = h.at(-1);
        return last.opponent === "C" ? last.you : (last.you === "C" ? "D" : "C");
    }
];

function features(history) {
    const n = history.length !== 0 ? history.length : 0.1;

    const last = history.at(-1)?.opponent;
    
    let oppDefected = 0;          
    let theyBurnedMe = 0;
    let iBurnedThem = 0;  
    for (const round of history) {
        if (round.opponent === "D") oppDefected++;
        
        if (round.opponent !== round.you)
        {
            if (round.opponent === "D") theyBurnedMe++;
            else iBurnedThem++;
        }
    }

    let streak = 0;
    for (let i = history.length - 1; i >= 0; i--)
    {
        if (history[i].opponent !== last) break;
        streak++;
    }

    if (last === "D") streak = -streak;

    return [
        1,
        last === "C" ? 1 : -1,
        2 * (oppDefected / n) - 1,
        oppDefected > 0 ? 1 : -1,
        2 * (theyBurnedMe / n) - 1, 
        2 * (iBurnedThem / n) - 1,
        Math.max(-1, Math.min(1, streak / 5)),
    ];
}

function forward(weights, x)
{
    const hidden = []
    for (let i = 0; i < weights.W1.length; i++)
    {
        let s = 0;
        
        for (let j = 0; j < x.length; j++)
        {
            s += weights.W1[i][j] * x[j];
        }

        hidden.push(Math.tanh(s));
    }
    
    let out = weights.b;
    for (let i = 0; i < weights.W2.length; i++)
    {
        out += weights.W2[i] * hidden[i]
    }
    
    return out > 0 ? "C" : "D"
}

function champ({ history })
{
    const x = features(history);
    const move = forward(WEIGHTS, x);
    return [move, null];
}

export default function bot({ history })
{
    try
    {
        let k = 0;

        for (const round of history)
        {
            const node = TREE[k];

            if (node[0] === -1) return [CANDIDATES[node[1]](history), null];
            if (round.you !== (node[0] ? "D" : "C")) return champ({ history });

            k = node[round.opponent === "D" ? 2 : 1];
            if (k < 0) return champ({ history });
        }

        const node = TREE[k];

        if (node[0] === -1) return [CANDIDATES[node[1]](history), null];
        return [node[0] ? "D" : "C", null];
    }
    catch
    {
        return ["C", null];
    }
}