+# https://twitter.com/xtetsuji/status/1088390124751056897
+my $challenge_count = 10_000; # 通算での結果を格納
+my $game_fee = 500; # 1回あたりのゲーム料金
+my @history; # サイコロの出た履歴を保存する配列
+my $count = 0; # 試行回数カウント用変数 兼 ボーナスフラグ
+my $count_bonus = 0; # ボーナス出た回数カウント用変数
+my $result = {}; # 結果表示用配列リファレンス
+ my $roll = int( rand(5) + 1 );
+# 引数で与えられた配列の合計を返すcoderef
+# 引数で与えられた配列の最小値を返すcoderef
+my $minimum_element = sub {
+ my @sorted = sort { $a <=> $b } @array;
+# ゲーム本体のコード試行回数になるまで繰り返す
+while ( $count < $challenge_count ) {
+ $count++; # ゲームの回数カウントアップ
+ my $bonus = 0; # ボーナス金額をリセット
+ my $roll = $dice->(); # サイコロを振った値を格納
+ push @history, $roll; # サイコロの目が出た履歴を作る
+# サイコロの目が出た履歴の数が3以上かどうかで条件分岐
+ if ( ( scalar @history ) > 3 ) {
+ shift @history; # 先頭の要素を取り除く
+ # サイコロの目の合計が3、つまり1のゾロ目の場合
+ if ( $sum->(@history) == 3 ) {
+ $count_bonus++; # ボーナス支給回数をカウントアップ
+ $bonus = 10000; # ボーナス額
+ elsif ( $sum->(@history) >= 12 and $minimum_element->(@history) >= 4 )
+ $count_bonus++; # ボーナス支給回数をカウントアップ
+ # 結果表示用ハッシュリファレンスに結果を詰める
+ push @{ $result->{history} }, {
+ array_str => sprintf( "%5s", join( " ", @history ) ),
+ $result->{count} = $count;
+ $result->{count_bonus} = $count_bonus;
+# ボーナスが支給された場合、サイコロの目が出た履歴を初期化
+# 結果表示用ハッシュリファレンスから結果を取り出して整形して並べる
+for my $element ( @{ $result->{history} } ) {
+ my $count = sprintf( "%5d", $element->{count} );
+ my $last1 = substr( $element->{array_str}, 2, 1 );
+ my $last2 = substr( $element->{array_str}, 0, 1 );
+ my $roll = $element->{roll};
+ my $bonus = $element->{bonus};
+ my $profit_loss = ( $game_fee * -1 ) + $roll * 100 + $bonus;
+ $profit_loss = '+' . $profit_loss if ($profit_loss > 0);
+ = "\tゲーム料金:$game_fee サイコロで得た金:"
+ $wallet += $profit_loss;
+ "試行:$count回目 サイコロの目:$element->{roll} 1回前の目:$last1 2回前の目:$last2\n";
+ print "損益:$profit_loss\n";
+say "ボーナス回数: ", $count_bonus;