[過去ログ] 【ゲームで、この処理ってどーやってんの?】 (125レス)
前次1-
抽出解除 レス栞

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
29
(3): 1 [] 2018/05/31(木) 09:15:43.81 ID:N+l2Be6d(1) AAS
>>27
スレチですが。

乱数関係だと。

一定の確率で複数の分岐処理を扱う時。

1番最初は
select case 0to0.2
〜case 0.6to0.7みたく直接数字書いたけど、もっと楽にできないかと考えました。

で、分岐させたい数の配列t(n)を作り、
その中に確率の大小を入れ(合計が100にならなくても良い)
、t(n)の値の合計sumを出し、それを使ってt2(n)に0.0〜1.0の範囲として割り振る。
例えば3つの分岐で、1つめが45、2つめが90、3つめが15だとすると、合計150なので、1は30%、2は60%、3は10%
なので、0.3,0.6,0.1となり、t2(0)は0.0と0.3
t(1)は0.3と0.9、t2(2)は0.9と1.0の開始値と終了値を格納。
ここらへんは、ちょっと冗長。終了値だけで事足りそう。

で、乱数を出し、
n回だけ繰り返してそれがどの範囲かの番号を返す。

その後それぞれの処理へ。

要約すると、、、
t(n)にそれぞれの当たり確率を適当な整数で示せば、その内のどれに当たるかを返してくれる関数。

分岐の確率を手書きしなくて済むことと、合計100にしなくても良くなった瞬間でした。
34: 名前は開発中のものです。 [sage] 2018/05/31(木) 21:24:38.84 ID:afJ9Cg6n(1) AAS
>>29
ごめん、言葉だけだとよくわからん。

もし29に書いてあるようなことを俺がやるとすると、こんな感じかなぁ。。。
(C#失礼)

static T SelectByRandom<T>(Dictionary<T, int> dic) {
 //荷重合計までの乱数を発生
 int n = MyRandom(dic.Sum(x => x.Value));
 //乱数に応じたオブジェクト選択
 foreach(var kv in dic) {
  if ((n -= kv.Value) < 0) {
   //選択
   return kv.Key;
  }
 }
 throw new Exception();//エラー
}

実際はDictionary使わないし、関数化もしないけど、とりあえずイメージで。
ループ回して乱数値に応じた選択をするのが、俺的に定番。
コンパイラ通してないのでエラーでるかもw

呼び出し方はこんな感じ

//準備
var weightDic = new Dictionary<MyClass, int>();
weightDic[objA] = 30;//30の確率でobjAを選択
weightDic[objB] = 90;//90の確率でobjBを選択
weightDic[objC] = 40;//40の確率でobjCを選択
//選択そして実行
var selectedObject = SelectByRandom<MyClass>(weightDic);
38
(1): 29 [sage] 2018/06/01(金) 16:13:07.09 ID:0NO1muzn(1/2) AAS
えー、すいません。

>>29は、
えーと、?分岐させたいケースごとに適当な数をセットし、?その合計でそれぞれ割ると、それぞれの確率、重み?になるので、その確率を順に足すことで、0.0〜1.0に収まる範囲に分岐の確率を設定できるので、そこに乱数値を与えて分岐のIDを返す。

?だけ渡せば良く、?以降を関数化したもの、です。

前述したように、分岐数も自由だし、分岐に用いる割合の合計を100とか1.0にしなくてもよい点が、自分ではなかなか閃いたなあ、というもの、でした。
m(_ _)m
39: 29 [sage] 2018/06/01(金) 16:22:47.28 ID:0NO1muzn(2/2) AAS
>>38のメリットは、関数化によるものは当然ですが、?を変更するだけで、分岐を増やしたりそれぞれの確率を変えたり出来る修正の簡略性でしょうか。

関数の中では、分岐IDを返すのはforとかdo loopになってますが、
普通にselectを使う場合の分岐を増やしたり確率を変更したりする時より修正の手間が減るかと。
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.641s*