2021年12月27日月曜日

D2メガテンの烙印の失敗がどの程度かモデルで検証してみた。

どうも、あまりにも失敗が目立って酷いので、コードを書いて検証してみることにした。

烙印のステータスアップの成功率 10% に対して40回以上失敗が連続するのは、どの程度で、最高何回ぐらい続くのか?
#include <iostream>
#include <random>
#include <array>
#include <algorithm>
#include <numeric>
#include <vector>

#define TRY_COUNT 10000

using seed_v_t = std::array<std::random_device::result_type, sizeof(std::mt19937)/sizeof(std::random_device::result_type)>;
seed_v_t create_seed_v() {
  std::random_device rnd;
  seed_v_t sed_v;
  std::generate(sed_v.begin(), sed_v.end(), std::ref(rnd));
  return sed_v;
}


std::mt19937 create_random_engine()
{
  const auto sed_v = create_seed_v();
  std::seed_seq seq(sed_v.begin(), sed_v.end());
  return std::mt19937(seq);
}

std::mt19937& random_engine()
{
  static thread_local std::mt19937 engine = create_random_engine();
  return engine;
}

int main() {
  std::mt19937& engine = random_engine();
  std::uniform_int_distribution<int> dist(0, 10);
  std::vector<int> cnts;
  int bingo = 0;
  int cnt = 0;
  for(int i = 0; i < TRY_COUNT; ++i) {
    int val = dist(engine);
    if( val != 0 ) ++cnt;
    else {
      cnts.push_back( cnt );
      cnt = 0;
    }
  }
  int acc = std::accumulate( cnts.begin(), cnts.end(), 0);
  std::cout << std::endl;
  std::cout << "成功回数         = " << cnts.size() << " / " << TRY_COUNT << std::endl;
  std::cout << "平均施行回数     = " << (acc / (double)cnts.size()) << std::endl;
  std::cout << "31回以上連続失敗 = " << std::count_if( cnts.begin(), cnts.end(), [](int x) { return (x > 30); } ) << std::endl;
  std::cout << "41回以上連続失敗 = " << std::count_if( cnts.begin(), cnts.end(), [](int x) { return (x > 40); } ) << std::endl;
  std::cout << "51回以上連続失敗 = " << std::count_if( cnts.begin(), cnts.end(), [](int x) { return (x > 50); } ) << std::endl;
  std::cout << "61回以上連続失敗 = " << std::count_if( cnts.begin(), cnts.end(), [](int x) { return (x > 60); } ) << std::endl;
  std::cout << "71回以上連続失敗 = " << std::count_if( cnts.begin(), cnts.end(), [](int x) { return (x > 70); } ) << std::endl;
  std::cout << "最大連続失敗回数 = " << *std::max_element( cnts.begin(), cnts.end() ) << std::endl;
  std::cout << "連続40回以上の失敗に出会う確率 = " << 
    std::count_if( cnts.begin(), cnts.end(), [](int x) { return (x > 40); } ) / (double)cnts.size() * 100.0 << "%" << std::endl;
}

結果は

成功回数         = 922 / 10000
平均施行回数     = 9.83406
31回以上連続失敗 = 50
41回以上連続失敗 = 20
51回以上連続失敗 = 8
61回以上連続失敗 = 3
71回以上連続失敗 = 0
最大連続失敗回数 = 70
連続41回以上の失敗に出会う確率 = 2.1692%

成功回数         = 883 / 10000
平均施行回数     = 10.3001
31回以上連続失敗 = 50
41回以上連続失敗 = 22
51回以上連続失敗 = 7
61回以上連続失敗 = 1
71回以上連続失敗 = 1
最大連続失敗回数 = 81
連続41回以上の失敗に出会う確率 = 2.49151%

成功回数         = 884 / 10000
平均施行回数     = 10.3032
31回以上連続失敗 = 60
41回以上連続失敗 = 27
51回以上連続失敗 = 11
61回以上連続失敗 = 5
71回以上連続失敗 = 2
最大連続失敗回数 = 84
連続41回以上の失敗に出会う確率 = 3.0543%


成功回数         = 881 / 10000
平均施行回数     = 10.3507
31回以上連続失敗 = 55
41回以上連続失敗 = 20
51回以上連続失敗 = 11
61回以上連続失敗 = 4
71回以上連続失敗 = 1
最大連続失敗回数 = 75
連続41回以上の失敗に出会う確率 = 2.27015%

成功回数         = 934 / 10000
平均施行回数     = 9.67024
31回以上連続失敗 = 46
41回以上連続失敗 = 20
51回以上連続失敗 = 5
61回以上連続失敗 = 0
71回以上連続失敗 = 0
最大連続失敗回数 = 57
連続41回以上の失敗に出会う確率 = 2.14133%

成功回数         = 947 / 10000
平均施行回数     = 9.55649
31回以上連続失敗 = 44
41回以上連続失敗 = 21
51回以上連続失敗 = 11
61回以上連続失敗 = 4
71回以上連続失敗 = 0
最大連続失敗回数 = 70
連続41回以上の失敗に出会う確率 = 2.21753%

ひどいケースは無くはないけど、プレイしていると、これよりは頻繁に40回以上連続失敗に遭遇していると思う。
また、思ったよりも連続失敗する事が多いのだなと思った。
しょっちゅう連続失敗でマッカが無くなるので、連続失敗の上限を設けてほしいです。
ユーザは、この仕様にかなりやる気を削がれていると思います

2022/1/10 追記: よくみたら、0-10じゃなくて、0-9で計算しないとあきませんやん。こうやって考えると d2の烙印の実装、バグっぽくありません?

0 件のコメント: