1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

雀魂の部屋別の戦績を確認する

Last updated at Posted at 2022-08-09

スクリプトの利用は、自己責任でお願いします。

雀魂の部屋別の戦績を取得するスクリプトです。開発者ツールで実行できます。
牌譜屋にないデータ(銅の間と銀の間での戦績や、被ツモ率、横移動率)の確認が可能です。1

window.to_stats = (res, is_recent) => {
    const room_names = "銅, 銀, 金, 玉, 王, 王".split(", ");
    const rule_names = "一, 東, 南, CPU, 一".split(", ");

    const stats = [];
    const types = mjcore.E_Round_Result;
    const all_types = Object.values(types).filter(Number.isInteger);
    const rank_stat = res.detail_data.rank_statistic;
    const st_name = is_recent ? "month_statistic" : "total_statistic";

    if (is_recent) {
        stats.since = new Date(rank_stat.month_refresh_time * 1000);
    }
    rank_stat[st_name].level_data_list.map(RankLevelData =>
        RankLevelData.statistic.game_mode.map(({
            mode,
            round_end,
            fly_count,
            game_final_position,
            game_count_sum,
            ming_count_sum,
            liqi_count_sum,
            xun_count_sum,
            dadian_sum,
        }) => {
            const sum = (..._types) => round_end
                .filter(r => _types.includes(r.type))
                .map(r => r.sum)
                .reduce((p, c) => p + c, 0);
            const rounds = sum(...all_types);
            const hora_sum = sum(types.zimo, types.rong);
            const rank = RankLevelData.rank_level - 1;

            return {
                _sort_index: rank * 2 + mode,
                is3: mode >= 10,
                games: game_count_sum,
                room_name: room_names[rank] + rule_names[mode % 10],

                heichaku: game_final_position.reduce((p, c, i) => p + c * (i + 1)) / game_count_sum,
                first: game_final_position[0] / game_count_sum,
                second: game_final_position[1] / game_count_sum,
                third: game_final_position[2] / game_count_sum,
                forth: game_final_position[3] / game_count_sum || 0,

                hora: hora_sum / rounds,
                hoju: sum(types.fangchong) / rounds,
                tsumo: sum(types.zimo) / hora_sum || 0,
                furo: ming_count_sum / rounds,
                riichi: liqi_count_sum / rounds,

                tobi: fly_count / game_count_sum,
                hitsumo: sum(types.beizimo) / rounds,
                ryukyoku: sum(types.liuju) / rounds,
                yokoido: sum(types.shaoji) / rounds,
                junsu: xun_count_sum / hora_sum || 0,
                daten: dadian_sum / hora_sum || 0,
            };
        })
    ).forEach(stat => stats.push(...stat));

    return stats.sort((a, b) => a._sort_index < b._sort_index ? -1 : 1);
};


window.show_stats = (stats, is3 = false) => {
    const chart_colors = [
        "hwb(134 36% 30%)",
        "hwb(188 29% 23%)",
        "hwb(208 62% 46%)",
        "hwb(354 41% 9%)",
    ];
    const chart_length = 20;

    if (stats.since) {
        console.log("since", stats.since.toLocaleString("ja-JP"));
    }
    for (const st of stats) {
        if (st.is3 === !is3) continue;
        const stat_values = Object.entries({
            "": `${st.games}戦`.padStart(6, " "),
            : st.hora,
            : st.hoju,
            : st.hitsumo,
            : st.ryukyoku,
            : st.yokoido,
            : st.tsumo,
            : st.furo,
            : st.riichi,
            : st.heichaku.toFixed(2),
            // 飛: st.tobi,
            // 巡: st.junsu.toFixed(1).padStart(4, " "),
            // 打: st.daten.toFixed(0).padStart(4, " "),
        }).map(([k, v]) => k + (
            typeof v === "string" ? v : (v * 100).toFixed(1).padStart(4, " ")
        ));
        const chart_ratios = st.is3
            ? [st.first, 0, st.second, st.third]
            : [st.first, st.second, st.third, st.forth];
        const chart_labels = chart_ratios.map(r =>
            `${Math.round(r * 100) || ""}`
        );
        const chart_styles = chart_ratios.map((r, i) => `
            padding: 0 ${(r * chart_length - chart_labels[i].length / 2) / 2}em;
            background-color: ${chart_colors[i]};
            color: white;
            line-height: 1.5;
        `);
        console.log(`${st.room_name}  %c${chart_labels.join("%c")}%c ${stat_values.join(" ")}`, ...chart_styles, "");
    }
};



window.get_stats = (account_id = 0, is3 = false, is_recent = false) => {
    account_id ||= GameMgr.Inst.account_id;

    const zone_icons = "Ⓒ, Ⓙ, Ⓔ".split(", ");
    const verified_icons = ", 🐾, 𝙋".split(", ");
    const rank_names = "初, 士, 傑, 豪, 聖, 魂, 魂".split(", ");
    const max_scores = [20, 80, 200, 600, 800, 1000, 1200, 1400, 2000, 2800, 3200, 3600, 4000, 6000, 9000];

    const zone = zone_icons[game.Tools.get_zone_id(account_id) - 1];
    const rule = is3 ? "三麻" : "四麻";

    app.NetAgent.sendReq2Lobby("Lobby", "fetchAccountInfo", {account_id}, (err, res) => {
        if (err || res.error) return;
        const verified = verified_icons[res.account.verified];
        const name = `${zone} ${res.account.nickname}${verified}`;

        const level = is3 ? res.account.level3 : res.account.level;
        const rank_id = `${level.id}`[2] - 1;
        const rank_lv = (level.id % 100) - 1;
        const rank = rank_names[rank_id] + (rank_lv + 1);

        const konten = rank_id === rank_names.length - 1;
        const score = level.score / (konten ? 100 : 1);
        const max_score = max_scores[rank_id * 3 + rank_lv] || 20;
        console.log(`%c${name}%c  ${rule}  ${rank} ${score}/${max_score}`, "font-size: 1.3em;", "");

        app.NetAgent.sendReq2Lobby("Lobby", "fetchAccountStatisticInfo", {account_id}, (_err, _res) => {
            if (_err || _res.error) return;
            show_stats(to_stats(_res, is_recent), is3);
        });
    });
};

get_stats();
// get_stats(0, true); // 三人麻雀の場合
  1. ただし、流局率と平均打点が、牌譜屋の値と異なります。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?