前に自作ゲームを作っており、ガチャっぽいものを作成しようとしたときに、
本来はデータベースから結果等を取得する必要があるのですが、
プログラムだけで実現できないかと検討した結果を備忘録として残します
また、追加でDLLを追加したりせず、既存の機能のみで作成しています
C++ではMap、C#ではDictionaryで作成できます。今回の例はすべてC++になります
いくつかの中から結果をひとつだけ返却する
全確率の累計値を算出
確率の累計値を求めておきます、後ほど使用します
for (auto per = targetDict.begin(); per != targetDict.end(); per++)
{
total += per->second;
}
累計確率までの乱数を生成
上記で求めた累計値を上限とした値の乱数生成する
C++ではメルセンヌ・ツイスターという理論で乱数を作成しています
メルセンヌ・ツイスターについては以下参考リンク先を確認してください
-
メルセンヌ・ツイスターは必要か? #アルゴリズム - Qiita
#今回の話題人類にMTはでかすぎる#疑似乱数とはコンピュータでは擬似乱数しか作ることは出来ません。本の1ページ毎にランダ ...
続きを読む
std::random_device rand_device;
std::mt19937 mersenne(rand_device());
std::uniform_real_distribution<float> rand(0.0f, total);
float randomResult = rand(mersenne);
結果を返却する
上記で生成した乱数から個々の確立を引いていき、0以下になった時点の値を返却します
for (auto per = targetDict.begin(); per != targetDict.end(); per++)
{
randomResult -= per->second;
// 0以下になった時点でのKeyを返す
if (randomResult < 0.0f)
{
return per->first;
}
}
確率でTrue、Falseを返却する
小数点をなくす倍率を求める
小数点をなくすためにべき乗する
// 少数以下の桁数(現在は第1まで)
int decimalPoint = 1;
// 小数点を消すための倍率
float rate = powf(10, decimalPoint);
乱数の上限と判定ボーダーを設定
乱数値と判定ボーダーを比較して判定ボーダーより乱数値が低いかどうか判定を返却します
// 乱数の上限と判定ボーダーを設定
float randomLimit = 100 * rate;
float border = rate * percent;
// 乱数を生成
std::random_device rand_device;
std::mt19937 mersenne(rand_device());
std::uniform_real_distribution<float> rand(0.0f, randomLimit);
float randomResult = rand(mersenne);
// 低いかどうか判定を返却
return randomResult < border;
精度について
上記で紹介した2のそれぞれの制度は以下です
100連を1万回実行した平均になります。それぞれ誤差がありますが許容範囲内だと思います
値 | 確率 | 100連を1万回実行した際の平均値 |
---|---|---|
hoge.png | 20.0 | 20.000 |
huga.png | 25.0 | 25.000 |
piyo.png | 15.0 | 15.000 |
Biyo.png | 40.0 | 39.000 |
True | 20.0 | 19.000 |
False | 80.0 | 80.000 |
最後に
今回紹介したプログラムの全体をGitへアップしています
また、例ではC++しか記載していませんがC#版もアップしています
それぞれ参考にしてください
-
BlogSampleCodeProjects/Probability at main · nasuton/BlogSampleCodeProjects · GitHub
Project for sample code used in the blog.(Blogで記載しているサンプルコード ...
続きを読む
会社紹介
私が所属しているアドバンスド・ソリューション株式会社(以下、ADS)は一緒に働く仲間を募集しています
会社概要
「技術」×「知恵」=顧客課題の解決・新しい価値の創造
この方程式の実現はADSが大切にしている考えで、技術を磨き続けるgeekさと、顧客を思うloveがあってこそ実現できる世界観だと思っています
この『love & geek』の精神さえあれば、得意不得意はno problem!
技術はピカイチだけど顧客折衝はちょっと苦手。OKです。技術はまだ未熟だけど顧客と知恵を出し合って要件定義するのは大好き。OKです
凸凹な社員の集まり、色んなカラーや柄の個性が集まっているからこそ、常に新しいソリューションが生まれています
ミッション
私たちは、テクノロジーを活用し、業務や事業の生産性向上と企業進化を支援します
-
アドバンスド・ソリューション株式会社
アドバンスド・ソリューションは主にMicrosoft製品を使用して、企業の生産性向上に取り組んでいます。要件定義から導入 ...
サイトへ移動
-
お問い合わせ | アドバンスド・ソリューション株式会社
お問い合わせはこちら