Francesco149 / ojsama

pure javascript implementation of https://github.com/Francesco149/oppai-ng
The Unlicense
26 stars 7 forks source link

n300, n100 & n50 mixed up / shifted #7

Open ghost opened 6 years ago

ghost commented 6 years ago

I'm having a weird ojsama bug which shifts values. 300 ->50, 50 -> 100, which results in wrong calculations.

Code:

download("https://osu.ppy.sh/osu/" + mostRecentBMID, dlOptions, (error) => {
    if (error) throw error;

    fs.readFile('./beatmaps/tmp_beatmap.osu', 'utf8', (fsError, fsData) => {
        if (fsError) throw fsError;

        const beatmapData = fsData;
        var beatmapParser = new ojsama.parser().feed(beatmapData);
        var beatmapStars = new ojsama.diff().calc({
            map: beatmapParser.map,
            mods: userRecentResults[0].enabled_mods
        });
        var beatmapPP = ojsama.ppv2({
            stars: beatmapStars,
            combo: userRecentResults[0].maxcombo,
            nmiss: userRecentResults[0].countmiss,
            acc_percent: parseFloat(beatmapRecentAcc)
        });

        var max_combo = beatmapParser.map.max_combo();

        console.log(beatmapPP.computed_accuracy.toString());
        console.log(userRecentResults[0].maxcombo + "/" + max_combo);
        console.log(beatmapPP.toString());
        console.log(parseFloat(beatmapRecentAcc));
    });

});

My accuracy calculation:

const beatmapRecentAcc = (((
        (parseInt(userRecentResults[0].count300) * 300) +
        (parseInt(userRecentResults[0].count100) * 100) +
        (parseInt(userRecentResults[0].count50) * 50) +
        (parseInt(userRecentResults[0].countmiss) * 0)) /
    ((
        parseInt(userRecentResults[0].count300) +
        parseInt(userRecentResults[0].count100) +
        parseInt(userRecentResults[0].count50) +
        parseInt(userRecentResults[0].countmiss)
    ) * 300)) * 100).toFixed(2);

I obtain most of the dynamic data directly from the osu! API. An example result:

0.17% 0x100 1364x50 11xmiss

922/2105

59.01 pp (24.51 aim, 31.56 speed, 0.00 acc)

97.88

Am I just massively stupid and miss something or is there something wrong?

Thanks in advance!

Francesco149 commented 6 years ago

i see you're using accuracy percent. ppv2 accepts n300, n100, n50, nmiss and it saves calculations that approximates n100/n50, so i recommend using that instead of calculating % accuracy

if switching to n300, n100, n50, nmiss fixes it then it might be an obscure issue with the 100/50 approximation. give me some example scores where this happens so i can reproduce and test

ghost commented 6 years ago

Hey, sorry to bug you with it, but giving the 300s, 100s and 50s directly didn't work either, same behaviour (dynamic data from osu! API: /api/get_user_recent):

download("https://osu.ppy.sh/osu/" + mostRecentBMID, dlOptions, (error) => {
    if (error) throw error;

    fs.readFile('./beatmaps/tmp_beatmap.osu', 'utf8', (fsError, fsData) => {
        if (fsError) throw fsError;

        const beatmapData = fsData;
        var beatmapParser = new ojsama.parser().feed(beatmapData);
        var beatmapStars = new ojsama.diff().calc({
            map: beatmapParser.map,
            mods: 0
        });
        var beatmapPP = ojsama.ppv2({
            stars: beatmapStars,
            combo: userRecentResults[0].maxcombo,
            n300: userRecentResults[0].count300,
            n100: userRecentResults[0].count100,
            n50: userRecentResults[0].count50,
            nmiss: userRecentResults[0].countmiss,
        });

        var max_combo = beatmapParser.map.max_combo();

        console.log(beatmapPP.computed_accuracy.toString());
        console.log(userRecentResults[0].maxcombo + "/" + max_combo + "x");
        console.log(beatmapPP.toString());

    });

});

Trying the same with local prepped data works for me though as intended:

// Download Beatmap
download("https://osu.ppy.sh/osu/1343792", dlOptions, (error) => {
    if (error) throw error;

    fs.readFile('./beatmaps/tmp_beatmap.osu', 'utf8', (fsError, fsData) => {
        if (fsError) throw fsError;

        const beatmapData = fsData;
        var beatmapParser = new ojsama.parser().feed(beatmapData);
        var beatmapStars = new ojsama.diff().calc({
            map: beatmapParser.map,
            mods: 24
        });
        var beatmapPP = ojsama.ppv2({
            stars: beatmapStars,
            combo: 1452,
            n300: 1021,
            n100: 32,
            n50: 0,
            nmiss: 4,
        });

        var max_combo = beatmapParser.map.max_combo();

        console.log(beatmapPP.computed_accuracy.toString());
        console.log("1452/" + max_combo + "x");
        console.log(beatmapPP.toString());

    });

});

Results:

97.60% 32x100 0x50 4xmiss

251/1471x

390.09 pp (182.74 aim, 123.14 speed, 76.77 acc)

Any idea why this behaviour is present? I already tried type casting the results from the API with no results either

Francesco149 commented 6 years ago

can you print out the userRecentResults object for one of these failed calls before and after ojsama calls? I suspect it's just the data that's broken