reorder function definitions so dataclasses come first
This commit is contained in:
parent
0ecb6ef192
commit
6c16d2986b
@ -120,143 +120,6 @@ ALIASES = {
|
|||||||
CHIP_VALUES = {0.25, 0.5, 1, 5, 10, 25, 50, 100}
|
CHIP_VALUES = {0.25, 0.5, 1, 5, 10, 25, 50, 100}
|
||||||
|
|
||||||
|
|
||||||
def expected(bet: Bet) -> float:
|
|
||||||
"""
|
|
||||||
Returns the expected value of a bet.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
bet : Bet
|
|
||||||
The bet to calculate the expected value of.
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
float
|
|
||||||
The expected value of the bet.
|
|
||||||
"""
|
|
||||||
bets = list(bet.spread.values())
|
|
||||||
cond_bets = filter(lambda x: x > 0, bets)
|
|
||||||
amt = sum(bets)
|
|
||||||
payout = amt * 36 / 38
|
|
||||||
print(
|
|
||||||
f"bet: {amt:.2f}, expected: {payout:.2f}: {payout/amt:2.4f}"
|
|
||||||
+ f"with std {stdev(bets*36)} mean win of"
|
|
||||||
+ f"{36*mean(cond_bets)} {sum(filter(lambda x: x > 0, bets))}/38 times."
|
|
||||||
)
|
|
||||||
return payout
|
|
||||||
|
|
||||||
|
|
||||||
def place_bet(bet: Bet, on: int, amount: float) -> Bet:
|
|
||||||
"""
|
|
||||||
Places a bet on a number.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
bet : Bet
|
|
||||||
The bet to place.
|
|
||||||
on : int
|
|
||||||
The number to bet on.
|
|
||||||
amount : float
|
|
||||||
The amount to bet.
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
Bet
|
|
||||||
A dictionary representing the bet with the new bet placed.
|
|
||||||
"""
|
|
||||||
bet = bet.copy()
|
|
||||||
bet[on] += amount
|
|
||||||
return bet
|
|
||||||
|
|
||||||
|
|
||||||
def interpret_bet(on="red", amount=0, bet=Optional[Bet]) -> Bet:
|
|
||||||
"""
|
|
||||||
Interprets a bet and returns a dictionary representing the bet.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
on : str
|
|
||||||
The type of bet to place.
|
|
||||||
amount : float
|
|
||||||
The amount to bet.
|
|
||||||
bet : Bet
|
|
||||||
The bet to add to.
|
|
||||||
(default is None, which creates a new bet)
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
Bet
|
|
||||||
A dictionary representing the bet.
|
|
||||||
"""
|
|
||||||
assert (on in FEASIBLE_MOVES) or (
|
|
||||||
on in ALIASES
|
|
||||||
), f"Bet `{on}` not understood. Choose from feasible moves:\n {FEASIBLE_MOVES}"
|
|
||||||
if bet is None:
|
|
||||||
bet = Bet()
|
|
||||||
else:
|
|
||||||
bet = bet.copy()
|
|
||||||
REDS = {1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36}
|
|
||||||
BLACKS = set(range(37)) - REDS
|
|
||||||
NUMS = {}
|
|
||||||
on = on.strip().replace(" ", "-")
|
|
||||||
div = 18
|
|
||||||
if on in ("red", "reds"):
|
|
||||||
NUMS = REDS
|
|
||||||
if on in ("black", "blacks"):
|
|
||||||
NUMS = BLACKS
|
|
||||||
if on in ("odd", "odds"):
|
|
||||||
NUMS = {i for i in range(1, 37) if i % 2 == 0}
|
|
||||||
if on in ("even", "evens"):
|
|
||||||
NUMS = {i for i in range(1, 37) if i % 2}
|
|
||||||
if on in ("1-18", "first-18", "first-half"):
|
|
||||||
NUMS = set(range(1, 19))
|
|
||||||
if on in ("19-36", "last-18", "last-half", "second-half", "second-18"):
|
|
||||||
NUMS = set(range(19, 37))
|
|
||||||
if on in ("1-12", "13-24", "25-36"):
|
|
||||||
low, high = on.split("-")
|
|
||||||
NUMS = set(range(int(low), int(high) + 1))
|
|
||||||
div = 12
|
|
||||||
if on in ["triple-0", "triple-00"]:
|
|
||||||
NUMS = {0, 1, 2} if on == "triple-0" else {-1, 2, 3}
|
|
||||||
div = 3
|
|
||||||
if not NUMS:
|
|
||||||
other_bet = on.split("-")
|
|
||||||
if other_bet[0] == "street":
|
|
||||||
street = int(other_bet[1]) - 1
|
|
||||||
assert street in list(range(13))
|
|
||||||
NUMS = {i for i in range(street + 1, street + 4)}
|
|
||||||
div = 3
|
|
||||||
elif other_bet[0] == "col":
|
|
||||||
col = int(other_bet[1]) - 1
|
|
||||||
assert col in list(range(0, 3))
|
|
||||||
NUMS = {i for i in range(1, 37) if (i - 1) % 3 == col}
|
|
||||||
div = 12
|
|
||||||
elif (
|
|
||||||
other_bet[0] == "split"
|
|
||||||
): # TODO: validate choices, for now we disallow these.
|
|
||||||
num_1, num_2 = int(other_bet[1]), int(other_bet[2])
|
|
||||||
NUMS = {num_1, num_2}
|
|
||||||
div = 2
|
|
||||||
elif other_bet[0] == "corner":
|
|
||||||
num_1, num_2 = int(other_bet[1]), int(other_bet[2])
|
|
||||||
num_3, num_4 = int(other_bet[3]), int(other_bet[4])
|
|
||||||
NUMS = {num_1, num_2, num_3, num_4}
|
|
||||||
div = 4
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
NUMS = {int(on)}
|
|
||||||
div = 1
|
|
||||||
except ValueError as e:
|
|
||||||
raise e(
|
|
||||||
f"Bet `{on}` not understood."
|
|
||||||
+ f"Choose from feasible moves:\n {set(range(-1, 37))}"
|
|
||||||
)
|
|
||||||
|
|
||||||
bet = reduce(lambda bet, num: place_bet(bet, num, amount / div), NUMS, bet)
|
|
||||||
|
|
||||||
return bet
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Placement:
|
class Placement:
|
||||||
"""
|
"""
|
||||||
@ -454,6 +317,143 @@ class Player:
|
|||||||
return self.id < other.id
|
return self.id < other.id
|
||||||
|
|
||||||
|
|
||||||
|
def expected(bet: Bet) -> float:
|
||||||
|
"""
|
||||||
|
Returns the expected value of a bet.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
bet : Bet
|
||||||
|
The bet to calculate the expected value of.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
float
|
||||||
|
The expected value of the bet.
|
||||||
|
"""
|
||||||
|
bets = list(bet.spread.values())
|
||||||
|
cond_bets = filter(lambda x: x > 0, bets)
|
||||||
|
amt = sum(bets)
|
||||||
|
payout = amt * 36 / 38
|
||||||
|
print(
|
||||||
|
f"bet: {amt:.2f}, expected: {payout:.2f}: {payout/amt:2.4f}"
|
||||||
|
+ f"with std {stdev(bets*36)} mean win of"
|
||||||
|
+ f"{36*mean(cond_bets)} {sum(filter(lambda x: x > 0, bets))}/38 times."
|
||||||
|
)
|
||||||
|
return payout
|
||||||
|
|
||||||
|
|
||||||
|
def place_bet(bet: Bet, on: int, amount: float) -> Bet:
|
||||||
|
"""
|
||||||
|
Places a bet on a number.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
bet : Bet
|
||||||
|
The bet to place.
|
||||||
|
on : int
|
||||||
|
The number to bet on.
|
||||||
|
amount : float
|
||||||
|
The amount to bet.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Bet
|
||||||
|
A dictionary representing the bet with the new bet placed.
|
||||||
|
"""
|
||||||
|
bet = bet.copy()
|
||||||
|
bet[on] += amount
|
||||||
|
return bet
|
||||||
|
|
||||||
|
|
||||||
|
def interpret_bet(on="red", amount=0, bet=Optional[Bet]) -> Bet:
|
||||||
|
"""
|
||||||
|
Interprets a bet and returns a dictionary representing the bet.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
on : str
|
||||||
|
The type of bet to place.
|
||||||
|
amount : float
|
||||||
|
The amount to bet.
|
||||||
|
bet : Bet
|
||||||
|
The bet to add to.
|
||||||
|
(default is None, which creates a new bet)
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Bet
|
||||||
|
A dictionary representing the bet.
|
||||||
|
"""
|
||||||
|
assert (on in FEASIBLE_MOVES) or (
|
||||||
|
on in ALIASES
|
||||||
|
), f"Bet `{on}` not understood. Choose from feasible moves:\n {FEASIBLE_MOVES}"
|
||||||
|
if bet is None:
|
||||||
|
bet = Bet()
|
||||||
|
else:
|
||||||
|
bet = bet.copy()
|
||||||
|
REDS = {1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36}
|
||||||
|
BLACKS = set(range(37)) - REDS
|
||||||
|
NUMS = {}
|
||||||
|
on = on.strip().replace(" ", "-")
|
||||||
|
div = 18
|
||||||
|
if on in ("red", "reds"):
|
||||||
|
NUMS = REDS
|
||||||
|
if on in ("black", "blacks"):
|
||||||
|
NUMS = BLACKS
|
||||||
|
if on in ("odd", "odds"):
|
||||||
|
NUMS = {i for i in range(1, 37) if i % 2 == 0}
|
||||||
|
if on in ("even", "evens"):
|
||||||
|
NUMS = {i for i in range(1, 37) if i % 2}
|
||||||
|
if on in ("1-18", "first-18", "first-half"):
|
||||||
|
NUMS = set(range(1, 19))
|
||||||
|
if on in ("19-36", "last-18", "last-half", "second-half", "second-18"):
|
||||||
|
NUMS = set(range(19, 37))
|
||||||
|
if on in ("1-12", "13-24", "25-36"):
|
||||||
|
low, high = on.split("-")
|
||||||
|
NUMS = set(range(int(low), int(high) + 1))
|
||||||
|
div = 12
|
||||||
|
if on in ["triple-0", "triple-00"]:
|
||||||
|
NUMS = {0, 1, 2} if on == "triple-0" else {-1, 2, 3}
|
||||||
|
div = 3
|
||||||
|
if not NUMS:
|
||||||
|
other_bet = on.split("-")
|
||||||
|
if other_bet[0] == "street":
|
||||||
|
street = int(other_bet[1]) - 1
|
||||||
|
assert street in list(range(13))
|
||||||
|
NUMS = {i for i in range(street + 1, street + 4)}
|
||||||
|
div = 3
|
||||||
|
elif other_bet[0] == "col":
|
||||||
|
col = int(other_bet[1]) - 1
|
||||||
|
assert col in list(range(0, 3))
|
||||||
|
NUMS = {i for i in range(1, 37) if (i - 1) % 3 == col}
|
||||||
|
div = 12
|
||||||
|
elif (
|
||||||
|
other_bet[0] == "split"
|
||||||
|
): # TODO: validate choices, for now we disallow these.
|
||||||
|
num_1, num_2 = int(other_bet[1]), int(other_bet[2])
|
||||||
|
NUMS = {num_1, num_2}
|
||||||
|
div = 2
|
||||||
|
elif other_bet[0] == "corner":
|
||||||
|
num_1, num_2 = int(other_bet[1]), int(other_bet[2])
|
||||||
|
num_3, num_4 = int(other_bet[3]), int(other_bet[4])
|
||||||
|
NUMS = {num_1, num_2, num_3, num_4}
|
||||||
|
div = 4
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
NUMS = {int(on)}
|
||||||
|
div = 1
|
||||||
|
except ValueError as e:
|
||||||
|
raise e(
|
||||||
|
f"Bet `{on}` not understood."
|
||||||
|
+ f"Choose from feasible moves:\n {set(range(-1, 37))}"
|
||||||
|
)
|
||||||
|
|
||||||
|
bet = reduce(lambda bet, num: place_bet(bet, num, amount / div), NUMS, bet)
|
||||||
|
|
||||||
|
return bet
|
||||||
|
|
||||||
|
|
||||||
def simulate_random_strategy(min_num_games=1, total_budget=200) -> Strategy:
|
def simulate_random_strategy(min_num_games=1, total_budget=200) -> Strategy:
|
||||||
"""
|
"""
|
||||||
Simulates a random strategy based on the minimum number of games that
|
Simulates a random strategy based on the minimum number of games that
|
||||||
|
2
setup.py
2
setup.py
@ -10,7 +10,7 @@ with open(BASEDIR.joinpath("README.md"), "r") as fp:
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="pyroulette",
|
name="pyroulette",
|
||||||
version="0.0.1rc4",
|
version="0.0.1rc5",
|
||||||
description="A package for exploring roulette strategies.",
|
description="A package for exploring roulette strategies.",
|
||||||
long_description=LONG_DESCRIPTION,
|
long_description=LONG_DESCRIPTION,
|
||||||
long_description_content_type="text/markdown",
|
long_description_content_type="text/markdown",
|
||||||
|
Loading…
Reference in New Issue
Block a user