Skip to content

Instantly share code, notes, and snippets.

@ShlomoAbraham
Last active July 25, 2018 17:09
Show Gist options
  • Save ShlomoAbraham/b698cf5d9de09b3546eb886187ac5af7 to your computer and use it in GitHub Desktop.
Save ShlomoAbraham/b698cf5d9de09b3546eb886187ac5af7 to your computer and use it in GitHub Desktop.
import random
import itertools
# solution is a dictionary:
# - Key is a tuple of (score: int, cards_remaining: int)
# - Value is a tuple of (continue_drawing: bool, expected_value: float)
solution = {
(-1, 1): (True, 0),
(1, 1): (False, 1)
}
# build up solution (dynamic programming)
def calculate(current, total_remain, b_remain, r_remain):
if (current, total_remain) not in solution:
if b_remain == 0 or total_remain == 0:
solution[(current, total_remain)] = (False, current)
else:
b_ev = calculate(current + 1, total_remain - 1, b_remain - 1, r_remain)
r_ev = calculate(current - 1, total_remain - 1, b_remain, r_remain - 1)
b_pct = b_remain / total_remain
r_pct = r_remain / total_remain
ev_draw = (b_ev * b_pct) + (r_ev * r_pct)
do_draw = ev_draw > current
ev = ev_draw if do_draw else current
solution[(current, total_remain)] = (do_draw, ev)
return solution[(current, total_remain)][1]
def do_strategy(deck, score, cards_remaining, verbose):
if cards_remaining <= 0:
return 0
next_step = solution[(score, cards_remaining)]
if verbose:
print('{0}: {1}'.format((score, cards_remaining), next_step))
if next_step[0]:
card = deck[-1 * cards_remaining]
new_score = score + 1 if card[1] == 'black' else score - 1
return do_strategy(deck, new_score, cards_remaining - 1, verbose)
else:
return score
COLORS = ['red', 'red', 'black', 'black']
RANKS = '23456789TJQKA'
DECK = tuple(card for card in itertools.product(RANKS, COLORS))
my_deck = random.sample(DECK, 52)
calculate(0, 52, 26, 26)
result = do_strategy(my_deck, 0, 52, True)
print(result)
import random
import itertools
import functools
import numpy as np
solution = {
(-1, 1): (True, 0),
(1, 1): (False, 1)
}
def calculate(current, total_remain, b_remain, r_remain):
if (current, total_remain) not in solution:
if b_remain == 0 or total_remain == 0:
solution[(current, total_remain)] = (False, current)
else:
b_ev = calculate(current + 1, total_remain - 1, b_remain - 1, r_remain)
r_ev = calculate(current - 1, total_remain - 1, b_remain, r_remain - 1)
b_pct = b_remain / total_remain
r_pct = r_remain / total_remain
ev_draw = (b_ev * b_pct) + (r_ev * r_pct)
do_draw = ev_draw > current
ev = ev_draw if do_draw else current
solution[(current, total_remain)] = (do_draw, ev)
return solution[(current, total_remain)][1]
def do_strategy(deck, score, cards_remaining, verbose):
if cards_remaining <= 0:
return 0
next_step = solution[(score, cards_remaining)]
if verbose:
print('{0}: {1}'.format((score, cards_remaining), next_step))
if next_step[0]:
card = deck[-1 * cards_remaining]
new_score = score + 1 if card[1] == 'black' else score - 1
return do_strategy(deck, new_score, cards_remaining - 1, verbose)
else:
return score
SIM_LENGTH = 1000
def calc_eval(deck: np.ndarray):
total = 0
vector = np.array(deck.copy())
for i in range(SIM_LENGTH):
np.random.shuffle(vector)
total += vector.cumsum().max()
return total / SIM_LENGTH
def choice(deck):
return calc_eval(deck) > 0
def run_mo(deck):
total = 0
for i in range(52):
c = choice(deck[i:])
if c:
total += deck[i]
else:
return total
return total
COLORS = ['red', 'red', 'black', 'black']
RANKS = '23456789TJQKA'
DECK = tuple(card for card in itertools.product(RANKS, COLORS))
calculate(0, 52, 26, 26)
results = []
for i in range(100):
my_deck = random.sample(DECK, 52)
mod_deck = [1 if t[1] == 'black' else -1 for t in my_deck]
result = do_strategy(my_deck, 0, 52, False)
mo_result = run_mo(mod_deck)
results.append((result, mo_result))
import statistics
mean = statistics.mean([r[0] for r in results])
mo_mean = statistics.mean([r[1] for r in results])
outperforms = len([r for r in results if r[0] > r[1]])
ties = len([r for r in results if r[0] == r[1]])
mo_outperforms = len([r for r in results if r[0] < r[1]])
# print(result)
# print('mo_result {0}'.format(mo_result))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment