Skip to content

Instantly share code, notes, and snippets.

@Nikolaj-K
Created May 25, 2021 11:40
Show Gist options
  • Save Nikolaj-K/72cf3acecd611f4b0091c236200baf2f to your computer and use it in GitHub Desktop.
Save Nikolaj-K/72cf3acecd611f4b0091c236200baf2f to your computer and use it in GitHub Desktop.
gambling_problems_simple
import random
# Set configuration in simulate() function
def naturals():
n = 0
while True:
yield n
n += 1
def sim_game(idx, p, Smin, Smax, k):
for num_tosses in naturals():
if num_tosses==0:
continue # skip zero
r = random.uniform(0, 1)
k += (1 if r < p else -1) # +1 if winning toss
win_game = k==Smax
if k==Smin or win_game:
break
#print(f"idx={idx}: End with {num_tosses} tosses. Win: {win_game}")
return num_tosses, win_game
def simulate():
p = 0.5
Smin = 0
k = 25
Smax = 30
NUM_SIMS = 10000
wins = 0
win_num_tosses = 0
for idx in range(NUM_SIMS):
num_tosses, win_game = sim_game(idx, p, Smin, Smax, k)
if win_game:
wins += 1
win_num_tosses += num_tosses
win_rate = wins / NUM_SIMS
win_num_tosses_rate = win_num_tosses / NUM_SIMS
analytic_win_rate = 1 - p_ruin_analytic(p, Smin, Smax, k)
print(f"\twin_rate: {win_rate}")
print(f"\twin_num_tosses_rate: {win_num_tosses_rate}")
print(f"\tanalytic_win_rate: {analytic_win_rate}")
print(f"\tdiff: {win_rate - analytic_win_rate}")
def p_ruin_analytic(p, Smin, Smax, k): # for comparison with the simulation
"""
:param p: Propabity of gain per transition for player.
:param Smin: Upper bound / goal.
:param Smax: Ruin.
:param k: Beginning capital owned by player.
"""
assert not Smin, "Smin must be 0." # TODO: generalize
assert Smin <= k <= Smax
if p==1:
return 0
if p==1/2:
return 1 - k / Smax
q = 1 - p
r = p / q
num = r**(Smax - k) - 1
denom = r**(Smax - 0) - 1
return num / denom
if __name__=="__main__":
simulate()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment