Snippets

sironekotoro dice_gambling.pl

You are viewing an old version of this snippet. View the current version.
Revised by sironekotoro 5280c19
use strict;
use warnings;
use feature qw/say/;
use Data::Dumper;

# https://twitter.com/xtetsuji/status/1088390124751056897

my $challenge_count = 10_000;    # 通算での結果を格納
my $wallet          = 0;         # 財布の中身
my $game_fee        = 500;       # 1回あたりのゲーム料金
my @history;    # サイコロの出た履歴を保存する配列
my $count = 0;  # 試行回数カウント用変数 兼 ボーナスフラグ
my $count_bonus = 0;     # ボーナス出た回数カウント用変数
my $result      = {};    # 結果表示用配列リファレンス

# サイコロの目を返すcoderef
my $dice = sub {
    my $roll = int( rand(5) + 1 );
    return $roll;
};

# 引数で与えられた配列の合計を返すcoderef
my $sum = sub {
    my @array = @_;
    my $sum   = 0;
    for my $num (@array) {
        $sum += $num;
    }
    return $sum;
};

# 引数で与えられた配列の最小値を返すcoderef
my $minimum_element = sub {
    my @array = @_;
    my @sorted = sort { $a <=> $b } @array;

    return $sorted[0];
};

# ゲーム本体のコード試行回数になるまで繰り返す
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; # ボーナス額
        }

        # サイコロの目の合計が12以上、
        # かつ
        # その配列の最小の要素が4以上の場合
        # ボーナス支給
        elsif ( $sum->(@history) >= 12 and $minimum_element->(@history) >= 4 )
        {
            $count_bonus++; # ボーナス支給回数をカウントアップ
            $bonus = 2000;  # ボーナス額
        }
    }

    # 結果表示用ハッシュリファレンスに結果を詰める
    push @{ $result->{history} }, {
        count     => $count,
        array_str => sprintf( "%5s", join( " ", @history ) ),
        roll      => $roll,
        bonus     => $bonus,
    };

    $result->{count}       = $count;
    $result->{count_bonus} = $count_bonus;

# ボーナスが支給された場合、サイコロの目が出た履歴を初期化
    if ($bonus) {
        @history = ();
    }

}

# 結果表示用ハッシュリファレンスから結果を取り出して整形して並べる
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);

    my $breakdown
        = "\tゲーム料金:$game_fee サイコロで得た金:"
        . $roll * 100
        . " ボーナス:$bonus";
    $wallet += $profit_loss;

    print
        "試行:$count回目 サイコロの目:$element->{roll} 1回前の目:$last1 2回前の目:$last2\n";
    print "損益:$profit_loss\n";
    print "$breakdown\n";
    print "通算:$wallet\n";
    print "-" x 10, "\n";

}

say "試行回数: ",       $count;
say "ボーナス回数: ", $count_bonus;
say "最終損益: ",       $wallet;

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.