[抱負]
久しぶりに、ダブルクロスの達成値の平均値を求めるプログラムをschemeで書く、です。
なんかもう久しぶり過ぎて良く覚えていない上に、色々考え方が変わってきたので、別手法でいくことにします。
…気にするな、きっとこういう方向転換がまだまだある(もしくは抱負自体が風化する)。
ファンブル時の計算を忘れていたため、修正。
ダブルクロスで能力値1、技能0、クリティカル値10、エフェクトは使用しない。
上記の場合、達成値の平均値は以下のように算出される。
出た目が1〜9の場合、その目が出る確率に出た目を掛け合わせる。
プログラムで書くと以下の様になる。
(+ (/ 1 10) (/ 2 10) (/ 3 10) (/ 4 10) (/ 5 10) (/ 6 10) (/ 7 10) (/ 8 10) (/ 9 10) )
出た目が10の場合、その目が出る確率に出た目を掛け合わせたものに、クリティカル分が加算される。
(+ (/ 10 10) (/ x 10)) ; xがクリティカル分
まとめると下記の様になる
(+ (/ 1 10) (/ 2 10) (/ 3 10) (/ 4 10) (/ 5 10) (/ 6 10) (/ 7 10) (/ 8 10) (/ 9 10) (/ 10 10) (/ x 10)) ; xがクリティカル分
↓
(+ (/ (+ 1 2 3 4 5 6 7 8 9 10) 10.0) (/ x 10.0)) ; xがクリティカル分
↓
(+ 5.5 (/ x 10.0)) ; xがクリティカル分
ここで、xはもとめる平均値そのものである。
(再帰的にずっと続く)
…なんかよくまとまんないんだけど、下記の様になる。
(+ 5.5 (/ 5.5 10 ) (/ 5.5 100 ) (/ 5.5 1000 ) (/ 5.5 10000 ) ; ずっと続く。 )
↓
(+ (/ 5.5 (expt 10 0)) (/ 5.5 (expt 10 1)) (/ 5.5 (expt 10 2)) (/ 5.5 (expt 10 3)) (/ 5.5 (expt 10 4)) ; ずっと続く。 )
このexptは累乗関数。
これは初項5.5、公比0.1の無限等比級数に等しくなる。
無限等比級数の和の公式から、
(/ 5.5 (- 1 0.1)) ; => 6.111111111111111
が求める平均値になる。
で、実際の判定では最初の1回で1が出た場合はファンブルである。
(1回でもクリティカルした後の1はファンブルでは無い)
ファンブル(絶対失敗)時の扱いをとりあえず達成値0とすると(異論はあるかもしれないけど1ではないのは確か)、
最初の1回で1が出る可能性×その時の出目(当然1)をこの平均値から引く。
(- (/ 5.5 (- 1 0.1)) (/ 1 10.0)) ; => 6.011111111111111
これが正しい平均値である。
同様に能力値1、技能0、クリティカル値9、エフェクトは使用しないケース。
これは初項5.6(ダイス目9の場合は10として扱うため)、公比0.2(クリティカル率があがる)の無限等比級数に等しくなる。
(/ 5.6 (- 1 0.2)) ; => 6.999999999999999
となる。
同様に、上記とクリティカル値のみが異なるケースを列挙する。
(/ (+ 1 2 3 4 5 6 7 8 9 10) 10.0) ;クリティカル値が10の場合の初項 5.5 (/ (+ 1 2 3 4 5 6 7 8 10 10) 10.0) ;クリティカル値が9 の場合の初項 5.6 (/ (+ 1 2 3 4 5 6 7 10 10 10) 10.0) ;クリティカル値が8 の場合の初項 5.8 (/ (+ 1 2 3 4 5 6 10 10 10 10) 10.0) ;クリティカル値が7 の場合の初項 6.1 (/ (+ 1 2 3 4 5 10 10 10 10 10) 10.0) ;クリティカル値が6 の場合の初項 6.5 (/ (+ 1 2 3 4 10 10 10 10 10 10) 10.0) ;クリティカル値が5 の場合の初項 7.0 (/ (+ 1 2 3 10 10 10 10 10 10 10) 10.0) ;クリティカル値が4 の場合の初項 7.6 (/ (+ 1 2 10 10 10 10 10 10 10 10) 10.0) ;クリティカル値が3 の場合の初項 8.3 (/ (+ 1 10 10 10 10 10 10 10 10 10) 10.0) ;クリティカル値が2 の場合の初項 9.1
(/ 5.5 (- 1 0.0)) ;クリティカル値が11の場合の平均値 => 5.5 (/ 5.5 (- 1 0.1)) ;クリティカル値が10の場合の平均値 => 6.111111111111111 (/ 5.6 (- 1 0.2)) ;クリティカル値が9 の場合の平均値 => 6.999999999999999 (/ 5.8 (- 1 0.3)) ;クリティカル値が8 の場合の平均値 => 8.285714285714286 (/ 6.1 (- 1 0.4)) ;クリティカル値が7 の場合の平均値 => 10.166666666666666 (/ 6.5 (- 1 0.5)) ;クリティカル値が6 の場合の平均値 => 13.0 (/ 7.0 (- 1 0.6)) ;クリティカル値が5 の場合の平均値 => 17.5 (/ 7.6 (- 1 0.7)) ;クリティカル値が4 の場合の平均値 => 25.33333333333333 (/ 8.3 (- 1 0.8)) ;クリティカル値が3 の場合の平均値 => 41.500000000000014 (/ 9.1 (- 1 0.9)) ;クリティカル値が2 の場合の平均値 => 91.00000000000001
(面倒なのでファンブル時の修正は後回し)
次に、もう少し一般化する。
公比は(/ (- 11 cr) 10.0)である(crはクリティカル値)。
初項は5.5に、以下の等比数列の和の十分の一を加算したものである。
- 初項0、項数(- 10 cr)、公差1
- 等比数列の和の公式から、この部分は(/ (* (- 10 cr) (+ (- 10 cr) 1)) 2)になる
すなわち、初項は(+ 5.5 (/ (/ (* (- 10 cr) (+ (- 10 cr) 1)) 2) 10.0))となる
と言うわけで、クリティカル値を引数にとる関数を定義してみる。
(define (roll-1dice cr) (/ (+ 5.5 (/ (/ (* (- 10 cr) (+ (- 10 cr) 1)) 2) 10.0)) ; 初項の部分 (- 1 (/ (- 11 cr) 10.0) ; 公比の部分 )))
実行結果
gosh> (define (roll-1dice cr) (- (/ (+ 5.5 (/ (/ (* (- 10 cr) (+ (- 10 cr) 1)) 2) 10.0)) ; 初項の部分 (- 1 (/ (- 11 cr) 10.0) ; 公比の部分 ) ) (/ 1 10.0) ; ファンブル時の分を減算する ) ) roll-1dice gosh> (roll-1dice 10) 6.011111111111111 gosh> (roll-1dice 9) 6.8999999999999995 gosh> (roll-1dice 8) 8.185714285714287 gosh> (roll-1dice 7) 10.066666666666666 gosh> (roll-1dice 6) 12.9 gosh> (roll-1dice 5) 17.4 gosh> (roll-1dice 4) (roll-1dice 4) 25.233333333333327 gosh> (roll-1dice 3) 41.40000000000001 gosh> (roll-1dice 2) 90.90000000000002
参考書籍
っつーか、読んだだけとか実は通読してないとか含む。
- 作者: 遠山啓
- 出版社/メーカー: 岩波書店
- 発売日: 1959/11/17
- メディア: 新書
- 購入: 34人 クリック: 234回
- この商品を含むブログ (62件) を見る
- 作者: 遠山啓
- 出版社/メーカー: 岩波書店
- 発売日: 1960/10/20
- メディア: 新書
- 購入: 26人 クリック: 49回
- この商品を含むブログ (43件) を見る
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2005/03/24
- メディア: 大型本
- 購入: 41人 クリック: 707回
- この商品を含むブログ (387件) を見る
- 作者: 結城浩
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2007/06/27
- メディア: 単行本
- 購入: 58人 クリック: 1,055回
- この商品を含むブログ (967件) を見る
- 作者: R.ケントディヴィグ,R.Kent Dybvig,村上雅章
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2000/05
- メディア: 単行本
- 購入: 2人 クリック: 71回
- この商品を含むブログ (20件) を見る