2016年12月2日こんにちは。プログラマーの尾関です。今回は基本的なテクニックですが、知っておくと便利なアルゴリズムを紹介します。くじを引いて以下のアイテムが手に入るとします。10%で金のコイン20%で銀のコイン70%で銅のコインこれをそのまま実装すると、以下のようなコードになると思います。eItem_CopperCoin;}}素直でわかりやすいコードですね。このやり方には2つの問題点があります。確率の合計が100になるようにしなければならない抽選する対象が増えると条件式が増える最初の問題点は、例えば、銀のコインを30%と設定だけして、他の確率を減らすのを忘れた場合です。10%で金のコイン30%で銀のコイン70%で銅のコインこの指定では、合計した確率が110%となり、おかしな抽選が行われる可能性があります。先ほどの関数を通すと、銅のコインの出現確率が60%になってしまいます。データ入力をミスしたときに確率計算が意図しないものになる危険性があります。1つの問題は、抽選対象が増えたときに、条件式が増えてしまうことです。レアアイテムとして「プラチナのコインが1%で出現する」という追加仕様が発生した場合、例としてあげた関数では、if文が増えることになってしまいます。これらの問題点を回避するには、「重み付け」で抽選を行うようにします。考え方としては、以下のようなイメージです。抽選箱に、金のコインが1つ、銀のコインが2つ、銅のコインが7つ、入っていると考えます。抽選箱に入っているコインの合計枚数を求めます。10その合計値で、それぞれを割ることで、その結果、確率は同じものになります。7÷10=70%そして、条件式を減らすには、合計値から抽選した値を、各対象の重み(枚数)で減算して比較すると、for文で記述することができます。10)}わかりやすくするために、for文で書くべき記述を展開しています。これを短くfor文で書いた処理は以下のとおりとなります。ItemNameTbl[result]);}この抽選を使った具体的な例として、趣味で作ったローグライクの入力データを紹介します。「ratio」という列が今回の話で言う「重み」にあたります。StickWood(木の棒)と、StickFire(火の棒)のratioが、100になっているので、一番出現しやすいアイテムです。逆にPortionHp10(HPを10回復する薬)やPortionDex10(命中率を10%上昇させる薬)、PortionEva10(回避率を10%上昇させる薬)のratioは「2」となっているので、レアアイテムという位置づけです。「start」「end」は出現するステージ番号です。startが1でendが3の場合、ステージ1~3でのみ出現するアイテムとなります。ローグライクはアイテムがランダムで出現しますが、序盤にいきなり強力なアイテムが手に入るとバランスが壊れてしまうので、序盤は弱い装備やアイテムを出現させるようにしています。ステージ1では、以下の4つのアイテムが出現します。100合計値は、100+50+10+100=260です。よって出現確率は以下の通りとなります。38.46%そしてステージ2へ進むと、別の装備やPortion系のアイテムが手に入るようになり、それらを含めた重み付けで抽選を行うようになります。いうことで、ローグライクのような抽選対象が増減するゲームでは、「重み付けの抽選」は非常に役に立つ、という話でした。today)PREVプラモデルについてNEXT【ボードゲーム部】MTG「デッキ紹介:霊気貯蔵器」コメント投稿は締め切りました。4で公開されている無料アセット気付いてしまったか...悪いが記憶を消させてもらうプランナーの仕事についてTrelloのススメ年末ポケモン大会が開かれた話。