マーチンゲール法を用いて手持ちの初期資金を２倍にする確率について

# 無敵だと勘違いされるギャンブル攻略法
勝率50%で配当金が２倍以上のゲーム（おそらくルーレット）で、マーチンゲール法という方法で賭けて行くと"理論的に"絶対に負けることがないと、高校生だった僕に教えてくれた先生がいました。


![image.png](https://vegasdocs.com/images/kouryaku/martin_index1.jpg)

"理論的に"というところに落とし穴があることまでその先生は教えてくれたのですが、
それ以降、世の中に「倍がけ最強説」を語る人が意外と多いなと感じたのでその解説と
現実世界では検証しずらいマーチンゲールで手持ちの資金を2倍にできる確率をRubyをつかって考察してみました。

#100円スタートでも20連敗すると1億485万7500円を失う
![スクリーンショット 2021-05-05 5.06.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1431442/1f90b2c2-c6a4-bfe0-fcd5-acca9e58909b.png)
たとえ１９連敗しようが20ターン目で当選する確率は50％です。
ちなみに２０連勝してもこの攻略法では2000円の利益しか生み出せません


#１/２でランダムに当選する計算式
0もしくは1をランダムに取得出来る仕組みをつくり、1を当選と今回は意味づけます。
まずは、当選確率が1/2程度であるか確かめていきましょう！

```ruby:ターミナルで実行時に440~550/1000と計算結果が表示される
def half_win
  result = 0
  hit_one = 0
  1000.times do |i|
    result = rand(0..1)
    if result == 1
      hit_one += 1
    end
    #puts "#{i}回目、結果:#{result}"
  end
  puts "#{hit_one}/1000"

end

half_win
```
20回ほどターミナルで計算させた結果502/1000でした。

#当選=1が出現するまでゲームを続ける(1)


```ruby
def loop_hit_one
  result = []
  10000.times do |i| #もし10000回以上試した結果「１」が表示されないとエラーになります
    result << rand(0..1)
    if result.include?(1)
      break
    end
  end
  puts "#{result}"
end

loop_hit_one
```
ターミナルでの計算結果は[1]もしくは[0,1][0,0,1]〜,の様に『１』でループが止まるようになります。

#当選=1が出現するまでゲームを続ける(2)
次は「１」が当選するまで賭け続けて手持ちの資金(my_money)が次のターンに参加出来るか判定できるようにしていきます

```ruby
def can_i_play
  my_money = 1000 #初期の手持ち金額
  result = []
  time = 1
  play_money = 100
    10000.times do |i|
      result << rand(0..1)
      if result.include?(1)
        my_money += 100
        time += i 
        puts "#{time}回目で当選、使用金額：#{play_money}円、  現在の手持ち資金：#{my_money}.#{result}"
        break
      elsif my_money >=  play_money + play_money + 100
        play_money = play_money + play_money + 100
      else
        puts "現在の手持ちの資金では次のターンに参加できません"
        break
      end
    end
end

can_i_play
```
初期の手持ち資金は１０００円なので、1~3回のターンで当選するか、４回目のターンに参戦出来ないメッセージが表示されます。

#繰り返して獲得賞金を増やす


```ruby
def lets_play
  err = 0
  my_money = 1000
  play_money = 100
  10.times do |a|
    10000.times do |i|
      if err == 0
        result = []
        result << rand(0..1)
        if result.include?(1)
          my_money += 100
          # puts "#{a}、#{i + 1}回目で当選、使用金額：#{play_money}円、  現在の手持ち資金：#{my_money}"
          play_money = 100
            if my_money == 2000
              puts "初期の手持ち資金が２倍達成しました"
            end
          break
        elsif my_money >=  play_money + play_money + 100 && err == 0
          play_money = play_money + play_money + 100
        else
          err += 1
          puts "現在の手持ちの資金では次のゲームに参加できません!"
          break
        end
      else
        break
      end
    end
  end
end

lets_play
```

#1000円をマーチンゲール法で2倍に増える確率計算

``` ruby
class MartingaleGames
  def initialize
    @success = 0
  end
  
  def lets_play
    err = 0
    my_money = 1000
    play_money = 100
    10.times do |a|
      10000.times do |i|
        if err == 0
          result = []
          result << rand(0..1)
          if result.include?(1)
            my_money += 100
            play_money = 100
              if my_money == 2000
                @success += 1
              end
            break
          elsif my_money >=  play_money + play_money + 100 && err == 0
            play_money = play_money + play_money + 100
          else
            err += 1
            break
          end
        else
          break
        end
      end
    end
  end

  def xloop
  
    10000.times do 
      lets_play
    end
    puts "#{@success}/10000"
  end

end

MartingaleGames.new.xloop
```
1000円をマーチンゲール法で2000円に増える確率は、36~38％と計算されるはずです。
あたりまえの事を言ってしまいますが、1000円を50％の確率で2倍に増えるところにベットすると、マーチンゲール法よりかなり少ない時間で50％の確率で手持ち資金を増やせます。

#もし手持ち資金が１千万円あったら確率は上がるのか？
```ruby
class MartingaleGames
  def initialize
    @success = 0
  end

  def lets_play
    err = 0
    my_money = 10000000

    play_money = 100
    1000000.times do |a|
      10000.times do |i|
        if err == 0
          result = []
          result << rand(0..1)
          if result.include?(1)
            my_money += 100
            play_money = 100
              if my_money == 20000000
                @success += 1
              end
            break
          elsif my_money >=  play_money + play_money + 100 && err == 0
            play_money = play_money + play_money + 100
          else
            err += 1
            break
          end
        else
          break
        end
      end
    end
  end

  def xloop
  
    100.times do 
      lets_play
    end
    puts "#{@success}/100"
  end

end

MartingaleGames.new.xloop
```
母数を1000にしてしまうと処理が止まってしまうのですが35%程度の確率で手持ち資金が倍に増えることがわかりました。
16連敗(0.0015%)は天文学的で現実的には起こり得ないと考えてしまいがちですが、1千万円をマーチンゲール法で２倍にしようとすると65%の確率で出現します。