Коэффициенты в кости: имитация игры в кости

Моему брату исполнилось 21 год, и мы с родителями отправили его в Лас-Вегас. Для моего 21-го я принес 200 долларов, чтобы играть в Лас-Вегасе, и вернулся домой около 450 долларов, в основном из игры в кости. Я планирую снова принести 200 долларов за эту поездку, и, прежде чем я уйду, я подумал, что я запустил бы симуляции крэпов, чтобы посмотреть, могу ли я снова удвоить свои деньги.

Я читал из нескольких источников, что дом имеет наименьшее преимущество в крэпсе при размещении ставки пассива с максимальными шансами. Из моей памяти, и, как было опрошено Wizard of Odds, большинство казино на Strip составляют 3-4-5 шансов с минимумом $5. Учитывая это, вот симуляция сеанса craps (из 100 кубиков в кости) в PHP:

<?php

$stash = 200;
$bet = 5;

for($i=100; $i--;) {

    $dice1 = mt_rand(1, 6);
    $dice2 = mt_rand(1, 6);
    $total = $dice1 + $dice2;

    if(!$button) {
        if($total===7 || $total===11) {
            $stash += $bet;
        }
        elseif($total===2 || $total===3 || $total===12) {
            $stash -= $bet;
        }
        else {
            $button = $total;
            if($total===4 || $total===10) {
                $odds = $bet*3;
            }
            elseif($total===5 || $total===9) {
                $odds = $bet*4;
            }
            elseif($total===6 || $total===8) {
                $odds = $bet*5;
            }
        }
    }
    else {
        if($total===7) {
            $button = 0;
            $stash -= ($bet + $odds);
        }
        elseif($total===$button) {
            $button = 0;
            $stash += $bet;
            if($total===4 || $total===10) {
                $stash += $odds*2/1;
            }
            elseif($total===5 || $total===9) {
                $stash += $odds*3/2;
            }
            elseif($total===6 || $total===8) {
                $stash += $odds*6/5;
            }
        }
    }

    echo 'Stash: $'.$stash.'<br/>';

}

?>

Что-то не так с моей математикой здесь? Несмотря на то, что на каждой сессии есть пики и впадины, эта симуляция чаще удваивает свои деньги, прежде чем сломаться. Учитывая, что дом всегда имеет преимущество в крэпсе, даже если он составляет лишь часть процента, я озадачен этим результатом.

Ответ 1

Ну, сразу с места в карьер, я вижу, что у вас есть ошибка в простом случае с выигрышем 7 или 11: вы должны выиграть свою ставку, а не в два раза больше ставки.

Изменить: Я считаю, что выплата ставки шансов соизмерима с реальной вероятностью. Вы в два раза чаще бросаете 7 (теряете свои шансы), чем 10, поэтому вам следует получать 2: 1, когда вы выигрываете на 4 или 10; и только заплатил 6: 5, когда вы выигрываете на 6 или 8.

Ответ 2

Я был бы осторожен с любым фрагментом кода, написанным, чтобы "доказать", что вы, скорее всего, удвоете свои деньги в крэпсе (или любой другой азартной игре), прежде чем разойтись. Лас-Вегас - это раскинувшийся город в пустыне Невады как свидетельство двух вещей:

  • В конечном итоге дом всегда выигрывает
  • Люди плохо разбираются в математике

Нет никакой игры, которую казино наложило бы на их пол, чтобы не использовать оба правила. Если ваш код не согласен с Вегасом, я вкладываю свои деньги в Вегас.

Update:

Вот несколько С++, которые я написал на основе вашего исходного кода. Первоначальная проблема, которую вы опубликовали, заключалась в том, чтобы удвоить свои деньги, прежде чем вы разошлись чаще, чем нет. Я выполнил код, который я написал с некоторыми результатами.

#include <iostream>

int die_roll()
{
    return std::rand() % 6 + 1;
}

int win_count_g(0);
int loss_count_g(0);

// return true when double our money.
// return false when we can't bet anymore.
bool test_loop(int cash)
{
    static const int bet_k(5);

    int goal(cash * 2);
    int button(0);

    while (true)
    {
        if (cash >= goal)
            return true;
        else if (cash < bet_k)
            return false;

        int roll(die_roll() + die_roll());
        int odds(0); // additional odds bet

        if (button == 0)
        {
            if (roll == 7 || roll == 11)
            {
                ++win_count_g;
                cash += bet_k;
            }
            else if (roll == 2 || roll == 3 || roll == 12)
            {
                ++loss_count_g;
                cash -= bet_k;
            }
            else
            {
                button = roll;

                if (roll == 4 || roll == 10)
                {
                    odds = std::min(cash - bet_k, bet_k * 3);
                }
                else if (roll == 5 || roll == 9)
                {
                    odds = std::min(cash - bet_k, bet_k * 4);
                }
                else // if (roll == 6 || roll == 8)
                {
                    odds = std::min(cash - bet_k, bet_k * 5);
                }
            }
        }
        else
        {
            if (roll == 7)
            {
                ++loss_count_g;
                button = 0;
                cash -= bet_k + odds;
            }
            else if (roll == button)
            {
                ++win_count_g;
                button = 0;
                cash += bet_k;

                if (roll == 4 || roll == 10)
                {
                    cash += odds * 2;
                }
                else if (roll == 5 || roll == 9)
                {
                    cash += odds * 3 / 2;
                }
                else // if (roll == 6 || roll == 8)
                {
                    cash += odds * 6 / 5;
                }
            }
        }
    }
}

void test(int cash)
{
    win_count_g = 0;
    loss_count_g = 0;

    int doubled(0);
    int broke(0);

    for (int i(0); i < 10000; ++i)
        if (test_loop(cash))
            ++doubled;
        else
            ++broke;

    float win_percentage(static_cast<float>(doubled) / (doubled + broke) * 100.0);

    std::cout << "starting cash: $" << cash
              << "; doubled: " << doubled
              << "; broke: " << broke
              << " (" << win_percentage << "% win)"
              << "; loop wins: " << win_count_g
              << "; loop losses: " << loss_count_g
              << std::endl;
}

int main ()
{
    static const int cash_set_k[] =
    {
        5,
        10,
        20,
        50,
        100,
        200,
        400,
        800,
        1000
    };
    static const int cash_set_size_k(sizeof(cash_set_k) / sizeof(cash_set_k[0]));

    std::for_each(&cash_set_k[0], &cash_set_k[cash_set_size_k], &test);

    return 0;
}

Результаты:

starting cash: $5; doubled: 4944; broke: 5056 (49.44% win); loop wins: 4944; loop losses: 5056
starting cash: $10; doubled: 4862; broke: 5138 (48.62% win); loop wins: 19706; loop losses: 20258
starting cash: $20; doubled: 4755; broke: 5245 (47.55% win); loop wins: 78360; loop losses: 80320
starting cash: $50; doubled: 4345; broke: 5655 (43.45% win); loop wins: 489406; loop losses: 502506
starting cash: $100; doubled: 3553; broke: 6447 (35.53% win); loop wins: 1914393; loop losses: 1972273
starting cash: $200; doubled: 2468; broke: 7532 (24.68% win); loop wins: 7172464; loop losses: 7375024
starting cash: $400; doubled: 861; broke: 9139 (8.61% win); loop wins: 22615369; loop losses: 23277609
starting cash: $800; doubled: 112; broke: 9888 (1.12% win); loop wins: 54556881; loop losses: 56121041
starting cash: $1000; doubled: 31; broke: 9969 (0.31% win); loop wins: 69308617; loop losses: 71296217

Ответ 3

Вы не проверяете, есть ли у вас достаточно оставшегося в тайнике, чтобы поставить ставку на ваши шансы. Фактически, вы вообще не проверяете размер своего кошелька. Неудивительно, что эта симуляция будет иметь возможность чаще бить дом, если вы можете делать ставки, даже если ваш размер закладок отрицательный.

Кстати, я провел 50 000 итераций вашего моделирования из 100 кубиков (с моей модификацией максимальной ставки останова) и придумал следующее:

побед: 23807

потери: 25465

нажмите (вы выходите с $200): 728

Средн. выигрыши: $109,07