Content
2004/11/15 05:08:38Dice.pm - 一群のサイコロを再現し、その結果をシミュレートするモジュール
■ Dice.pm - 一群のサイコロを再現し、その結果をシミュレートするモジュール
- NAME 名称
- SYNOPSIS 概要
- DESCRIPTION 説明
- BASE METHODS 基本メソッド
- CALC METHODS 計算メソッド
- MODE METHODS モードメソッド
- LOG METHODS ログメソッド
- last_log
- get_log
- shift_log
- unshift_log
- push_log
- pop_log
- shift_log, unshift_log, push_log, pop_log
- flush_log
- log_size
- all_log
- STATISTICS METHODS 統計メソッド
- INFO METHODS 情報メソッド
- $Dice::default_mode
NAME 名称
Dice.pm - 一群のサイコロを再現し、その結果をシミュレートするモジュール
SYNOPSIS 概要
# 6面体サイコロ三つの組を作り、それを振って同じ出目の組み合わせから
# 様々な結果を表示するCGI
use Dice;
$d = Dice->new(6, 6, 6);
$d->roll;
print "Content-type: text/html\n";
print "<html>";
print "<head><title>3d6</title></head>";
print "<body>";
print "<dl>";
print "<dt>出目</dt><dd>".join ('/', $d->array )."</dd>";
print "<dt>出目分布</dt><dd><table border=\"1\">";
%hash = $d->hash;
foreach $k ( sort {$a<=>$b} keys %hash ) {
print "<tr><th>$k</th><td>$hash{$k}</td></tr>";
}
print "</table></dd>";
print "<dt>出目の合計</dt><dd>".$d->sum."</dd>";
print "<dt>出目の掛け合わせ</dt><dd>".$d->multiply."</dd>";
print "<dt>出目の最小値</dt><dd>".$d->min."</dd>";
print "<dt>出目の最大値</dt><dd>".$d->max."</dd>";
print "<dt>出目の平均値</dt><dd>".$d->avg."</dd>";
print "<dt>出目の中央値</dt><dd>".$d->mid."</dd>";
print "<dt>出目の最頻値</dt><dd>".join ('/', $d->mode )."</dd>";
print "</dl>";
print "</body>";
print "</html>";
DESCRIPTION 説明
このPerlライブラリは、各種のサイコロとその組み合わせを再現します。
その組み合わせのサイコロを振って結果を返すだけでなく、 それらの出目の、合計、掛け合わせ、最小値、最大値、平均値、中央値、最頻値などを 計算して返すことができます。
それらの数字をどのように扱うかは、開発者の一存にまかされています。
また、サイコロの出目(の組み合わせ)はオブジェクト内部に保存され、 いつでも参照することができ、さらにはその過去の出目に対しても各種計算ができます。
過去の出目を利用した統計機能と、過去の出目によらない純粋な確率計算も可能です。
BASE METHODS 基本メソッド
new
引数に数字を与えた場合、「1からその数字までが面数に書かれたサイコロ」と解釈します。
Diceオブジェクトを与えた場合、そのDiceオブジェクトそのものを一つのサイコロと解釈します。サイコロを振った場合、そのDiceオブジェクトに対しrollメソッドを引数なしで実行した返値を、出た目として解釈します。
サイコロの面数を統一する必要はありません。(berserkメソッドを使用する場合は、統一する必要があります)
自然界に存在しない面数(3とか5とか)を指定しても構いませんが、0やマイナスは無視されます。
引数の中のDiceオブジェクトとその子クラスでないリファレンスは、無視されます。(判別にはis_diceメソッドを使用します)
なお、循環参照処理をしていませんので、オブジェクトを直接いじって無限ループに陥らないように注意をしてください。
サンプルスクリプト
$d3 = Dice->new(6, 6, 6); # 6面体サイコロ三つ
$d_merge = Dice->new($d3, 8, 8); # 6面体サイコロ三つ+8面体サイコロ二つ
roll
- 説明:オブジェクトに設定されたサイコロを振り、出目を記録する。
- mode_listメソッドで得られる文字列のどれか)一つ。
- 返値:サイコロを振った結果を、引数で与えたモードで計算した結果。
- 解説
もし、引数を省略したならば、set_modeメソッドで指定したモードが使われます。
さらにset_modeメソッドで設定をしていなければ、default_modeメソッドで指定したモードが使われます。
default_modeメソッドの返値は、$Dice::default_modeに設定されており、初期値は'sum'です。
出目の組み合わせ(セットと呼びます)は、オブジェクト内部にどんどん保存されます。過去のセットが欲しい場合には、get_logメソッドを使用してください。
サンプルスクリプト
$d3 = Dice->new(6, 6, 6); # 6面体サイコロ三つ
$sum = $d3->roll; # デフォルト設定のままの場合、rollメソッドを実行すると、合計値が返ってきます。
$d3->set_mode('max'); # サイコロ三つの最大値を返すように設定しました。
$max = $d3->roll; # また別にサイコロを振り、その中の最大値を返します。
$min = $d3->roll('min'); # また別にサイコロを振り、強制的にその中の最小値を返します。
$d3->set_mode('object'); # 計算結果を返さずに、オブジェクトそのものを返すモードに設定します。
$avg = $d3->roll->avg; # すると、このようなことができます。
berserk
- 説明:オブジェクトに設定されたサイコロをバーサーカー式に振り、出目を記録する。
- 引数:モード(mode_listメソッドで得られる文字列のどれか)一つ。
- 返値:サイコロをバーサーカー式に振り、引数で与えたモードで計算した結果
- 解説
rollメソッドの全ての注意事項がそのまま当てはまります。
バーサーカー式とは、TRPG「T&T」で使用される特殊なルールのことです。これがわからなければ、この項目は飛ばしてください。
このルールの性質上、サイコロの面数は統一されなければなりません。ので、サイコロの面数は、最初に登録されたサイコロのものが使われます。
最初に登録されたサイコロがDiceオブジェクトだった場合は、もちろんそれが使われます。(それに意味があるかどうかはわかりませんが)
出目のセットが保存される空間はrollメソッドと共有しています。従って、rollとberserkメソッドの両方を使った後でのstatisticsメソッドは意味のある結果を返さない可能性があります。
サンプルスクリプト
$ten_dice_sword = Dice->new(map{6}(1..10)); # 10ダイスソード!
$hit = $ten_dice_sword->berserk; # 10ダイスソードでバーサークしてみる。
$hit += $character->bonus; # それにキャラクターの能力値ボーナスを足して最終的な攻撃力とする。
$saving_roll = Dice->new(6, 6); # セービングロールはダイス2個によるバーサーク
$roll = $saving_roll->berserk; # 振ってみる。
if ( $roll < 5 ) { print 'ファンブル!'; } # 数値が5よりも小さければ、ファンブル。
CALC METHODS 計算メソッド
rollメソッドやberserkメソッドの引数に与えられるモードは、下記の種類があります。
| CALC METHODS 計算メソッド | 意味 |
| sum | 合計 |
| multiply | セット全ての掛け合わせ |
| min | セットの最小値 |
| max | セットの最大値 |
| avg | セットの平均値 |
| mid | セットの中央値(大きさ順に並べて真中) |
| mode | セットの種類と頻度を調べ、最も多く出た出目 |
| array | セットを計算せずに、配列として受け取る。 |
| arrayref | 上記をリファレンスにして受け取る。 |
| hash | セットを(出目の種類=>出た回数)の形のハッシュとして受け取る。 |
| hashref | 上記をリファレンスにして受け取る。 |
| object | 何もせず、オブジェクトを返す。 |
これらは同時にメソッド名でもあります。以下にその共通の仕様を記します。
- 説明:メソッド名で定められた計算を行い結果を返す。
- 引数:数値のみを要素とする配列リファレンス、もしくは整数。
- 返値:引数によって指定された数値群に対し計算を行った結果。基本的にはスカラー値だが、中には他の形式で返すものもある。詳しくはそれぞれのメソッドを参照のこと。
引数に数値のみを含む配列リファレンスを与えると、その数値をセットとして計算を行います。
数値を与えた場合は、その数値はget_logメソッドの引数として扱われ、それによって得られた配列リファレンスが使われます。通常は、マイナスの数値が使われるでしょう。例えば、-1を与えた場合、最新のセットの一つ前のセットが使われることになります。
もし引数を省略した場合は、自動的に最新のセットが使われます。これが最も普通の使い方でしょう。
sum
CALC METHODS 計算メソッドの一つです。 セットの合計値を求めます。 最も普通の使用方法です。
$d3 = Dice->new(6, 6, 6); # 6面体サイコロ三つを組にする。
$d3->set_mode('object');
print $d3->roll->sum; # これ(サイコロ三つ)を振り、その結果を合計して表示する。
multiply
CALC METHODS 計算メソッドの一つです。 セットの数値を掛け合わせた数値を返します。 あんまり使い道がないです。
$d3 = Dice->new(6, 6, 6); # 6面体サイコロ三つを組にする。
$d3->roll;
print join ( '/', $d3->array ); # 例えば、3/4/5
print "\n";
print $d3->multiplay; # 60 ( 3 * 4 * 5 )
min
CALC METHODS 計算メソッドの一つです。 セットの中で最小の数値を返します。 ……メガテンTRPGでNPCの行動を決める時か、ワースブレイドでの判定くらいしか使い道がないです。
$action_num = Dice->new(6, 6); # 6面体サイコロ三つを組にする。
$action_num->set_mode('min'); # 最小値モードにする。
$action = $character->action($action_num->roll);
max
CALC METHODS 計算メソッドの一つです。 セットの中で最大の数値を返します。 ますます使い道がないです。
avg
CALC METHODS 計算メソッドの一つです。 セットの算術平均値を返します。算術平均とは、要素全てを合計して要素数で割った数値のことです。 統計以外では使い道がないです。
mid
CALC METHODS 計算メソッドの一つです。 セットの中央値を返します。中央値とは、各要素を数値の大小順に並べたその真中の数値のことです。真中がない場合は、真中二つの算術平均を使います。 統計以外では使い道がないです。
mode
CALC METHODS 計算メソッドの一つです。 セットの最頻値を返します。最頻値とは、各要素を分類した中で、最も出現数の多い要素のことです。同点一位が複数ある場合は、それらの配列を返します。 従って、このメソッドを使う時は、念のため配列で受けるようにしてください。 統計以外では使い道がないです。
array
CALC METHODS 計算メソッドと言いつつ、実は何も計算しません。 セットの数字を各要素に持つ配列を返します。
arrayref
CALC METHODS 計算メソッドと言いつつ、実は何も計算しません。 セットの数字を各要素に持つ配列リファレンスを返します。
hash
CALC METHODS 計算メソッドと言いつつ、実は何も計算しません。 セットの数値をハッシュにして返します。 ハッシュの中身は、(数値=>その数値がセットの中に出現した回数)になります。
hashref
CALC METHODS 計算メソッドと言いつつ、実は何も計算しません。 セットの数値をハッシュリファレンスにして返します。 ハッシュリファレンスの中身は、{数値=>その数値がセットの中に出現した回数}になります。
object
CALC METHODS 計算メソッドと言いつつ、実は何も計算しません。 オブジェクト自身を返します。 なんでこんなものが? 一応、内部的に意味があるので存在しています。
$d3 = Dice->new(6, 6, 6);
$d3->set_mode('object');
print $d3->roll->avg; # 一応、こういう形式も取れると言うことで。
MODE METHODS モードメソッド
set_mode
- 説明:オブジェクトの基本モードを変更する。
- 引数:モード(mode_listメソッドで得られる文字列のどれか)一つ。
- 返値:変更前のモード。
- 解説
もし、引数を省略したならば、変更は行われません。不正な引数を与えた場合も同様です。
サンプルスクリプト
# 一時的にモードを変更するスクリプト
$d = Dice->new(6, 6, 6);
$old_mode = $d->set_mode($new_mode); # $new_modeに変更しつつ、現在のモードは$old_modeに保管する。
$d->set_mode($old_mode); # 元のモードに戻す。
default_mode
- 説明:クラス全体の基本モードを変更する。
- 引数:モード(mode_listメソッドで得られる文字列のどれか)一つ。
- 返値:変更前のモード。
- 解説
もし、引数を省略したならば、変更は行われません。不正な引数を与えた場合も同様です。
サンプルスクリプト
# 一時的にモードを変更するスクリプト
$d = Dice->new(6, 6, 6);
$old_mode = $d->set_mode($new_mode); # $new_modeに変更しつつ、現在のモードは$old_modeに保管する。
$d->set_mode($old_mode); # 元のモードに戻す。
mode_list
あるモードが使えるかどうかの判定は、is_modeメソッドを使用します。
サンプルスクリプト
# テスト的なスクリプト
# オブジェクトをつくり、可能な計算メソッドを全て試し、結果を表示する。
$d = Dice->new(6, 6, 6);
$d->roll;
@mode = $d->mode_list;
use Data::Dumper;
foreach $mode ( @mode ) {
$result = $d->$mode;
if ( ref $result ) {
print Data::Dumper->Dump([$result], ['res']);
} else {
print "$result\n";
}
}
is_mode
- 説明:使用可能なモードのリストをハッシュリファレンスの形で返す。
- 引数:なし。
- 返値:使用可能なモードをキーとするハッシュリファレンス。
- 解説
このメソッドは使い方が特殊なので、サンプルをよく読んでください。 どんなモードがあるかリストを取得するには、mode_listメソッドを使用します。
サンプルスクリプト
$d = Dice->new(6, 6, 6);
if ( $d->is_mode->{$mode} ) {
print "$mode は使用可能です。";
} else {
print "$mode は使用できません。";
}
LOG METHODS ログメソッド
ログ関係のメソッドです。
last_log
最後にrollもしくはberserkした時のセットを返します。CALC METHODS 計算メソッドを引数なしで実行した時、内部でこのメソッドが呼ばれます。
get_log
- 説明:指定されたセットを返す
- 引数:セットを持つ配列への添字
- 返値:数値のみを要素に持つ配列リファレンス
- 解説
内部的にセットのログは配列リファレンスの形で保持されています。その配列リファレンスに与える添字を引数として与えると、それに対応したセットを返します。 「最新の物の一つ前」が必要な時は、-1を引数に与えるといいでしょう。
サンプルスクリプト
$d3 = Dice->new(6, 6, 6);
map { $d3->roll } ( 1..10 ); # 10回意味もなく振ってみる。
$first = $d3->get_log(0); # 最初の一回目のセットを取得。
$last_three = $d3->get_log(-2); # 最後から三番目のセットを取得。
$sum = $d3->sum($first); # 取得したセットは様々な加工が可能。
shift_log
- 説明:セットのログに対してshiftを行う。
- 引数:なし。
- 返値:数値のみを要素に持つ配列リファレンス
- 解説
shift_log, unshift_log, push_log, pop_logを参照。
unshift_log
- 説明:セットのログに対してunshiftを行う。
- 引数:数値のみを要素に持つ配列リファレンス
- 返値:追加後の要素数
- 解説
shift_log, unshift_log, push_log, pop_logを参照。
push_log
- 説明:セットのログに対してpushを行う。
- 引数:数値のみを要素に持つ配列リファレンス
- 返値:追加後の要素数
- 解説
shift_log, unshift_log, push_log, pop_logを参照。
pop_log
- 説明:セットのログに対してpopを行う。
- 引数:なし。
- 返値:数値のみを要素に持つ配列リファレンス
- 解説
shift_log, unshift_log, push_log, pop_logを参照。
shift_log, unshift_log, push_log, pop_log
このオブジェクトが持つセットのログに対して、shift, unshift, push, popを行います。全て取り扱われるべきは「数値のみを要素に持つ配列リファレンス」です。注意してください。
ログをいじることで何が起きるか、各自の責任で処理してください。
flush_log
- 説明:ログを全て削除する。
- 引数:なし。
- 返値:空配列
- 解説
このオブジェクトが持つログを全て削除します。
log_size
- 説明:ログの長さを取得する。
- 引数:なし。
- 返値:ログの長さ
- 解説
このオブジェクトが持つログの長さを返します。ログに対して何も特別なことをしていなければ、この数値は、rollとberserkの実行回数になります。
all_log
- 説明:全てのログを取得する
- 引数:なし。
- 返値:全てのセットをおさめた配列リファレンス
- 解説
このオブジェクトが持つ全てのログを返します。
STATISTICS METHODS 統計メソッド
statistics
- 説明:モードを指定して計算し、その結果をさらに計算する。
- 引数:モードを二つ。さらにオプションで数値のみを要素とする配列リファレンスの配列リファレンスを第三引数に指定できる。
- 返値:第二引数のモードで指定したもの
- 解説
統計メソッドです。 rollやberserkを行って蓄積したログに対し、統計処理を行ってその結果を返すメソッドです。 全てのログのセットに対し、第一引数で指定したモードで計算を行い、その全ての結果に対して第二引数のモードで統計処理を行います。
サンプルスクリプト
# 10ダイスソードの期待値を計算する。
$ten_dice_sword = Dice->new(map{6}(1..10)); # 10ダイスソードを作る。
# 10ダイスソードを10000回振っておく。
foreach ( 1..10000 ) {
$ten_dice_sword->berserk;
}
# 一回のロール合計の平均を取る。
$expectation = $ten_dice_dword->statistics('sum'=>'avg');
# これを期待値の近似値として扱ってもあながちまちがいではなかろうと。
また、第三引数に数値のみを構成要素とする配列リファレンスの配列リファレンスを指定すれば、それに対して統計をとることができます。
なお、rollメソッドとberserkメソッドの両方が一つのオブジェクトで行われていた場合、 結果は何も信頼できないものになるでしょう。
statistics_by_calc
- 説明:モードを指定して計算し、その結果をさらに計算する。
- 引数:モードを二つ。
- 返値:第二引数のモードで指定したもの
- 解説
statisticsメソッドの変形です。実際に振ってみたログではなく、そのオブジェクトのサイコロが論理的にとりうる値の範囲で、同様の処理をするものです。 平均値を求めるのにちょうどいいでしょう。
サンプルスクリプト
$d3 = Dice->new(6, 6, 6); # 6面体サイコロ三つ
$avg = $d3->statistics_by_calc('sum'=>'avg'); # その合計の平均値
print $avg; # 結果は10.5になる。
INFO METHODS 情報メソッド
num
そのオブジェクトが持つサイコロの数を返します。 Diceオブジェクトが含まれていた場合は、それを一つと数えます。
サンプルスクリプト
$d1 = Dice->new(6, 6, 6); # 6面体サイコロ三つ
$d2 = Dice->new(6, 6, $d1); # 6面体サイコロ二つと$d1
print $d->num; # 3になる。
full_num
- 説明:そのオブジェクトが持つサイコロの数を数える。
- 引数:なし。
- 返値:そのオブジェクトが持つサイコロの数
- 解説
そのオブジェクトが持つサイコロの数を返します。 Diceオブジェクトが含まれていた場合は、それが持つサイコロも調べて数えます。
サンプルスクリプト
$d1 = Dice->new(6, 6, 6); # 6面体サイコロ三つ
$d2 = Dice->new(6, 6, $d1); # 6面体サイコロ二つと$d1
print $d->full_num; # 5になる。
is_dice
- 説明:そのオブジェクトがDiceオブジェクトかその子クラスであるかどうか。
- 引数:なし。
- 返値:1かundef
- 解説
Diceオブジェクトは、$self->{is_dice}が1になっていますので、この部分を調べるとそのオブジェクトがDiceオブジェクトかその子クラスのオブジェクトかどうか判明します。これはそのパラメータにアクセスするためのメソッドです。
継承した時や、オブジェクトの確認をしたい時などに使ってください。
$Dice::default_mode
全てのオブジェクトに共通の、デフォルトのモードです。 変更には、default_modeメソッドを使うようにしてください。これは、存在しないモード名が入るのを防ぐためです。
AUTHOR 作者
むいむい <band@room.ne.jp> 2004.07.20-
BUG バグ
If there is, Please, teach Me. あったら教えてください。
COPYRIGHT 著作権
The Dice module is Copyright (c) 2004 Muimui.
You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file.