Martingale Wett-Simulator 2.0
Dies ist ein zweiter Versuch, einen Martingale-Wett-Simulator zu erstellen. Der ursprüngliche Code musste so stark umgestaltet werden, dass ich gerade von vorne anfing.
Script simuliert die Martingale-Wettstrategie, einen festen Betrag zu setzen, bis ein Verlust auftritt. Zu diesem Zeitpunkt wird die Wette verdoppelt, um den Verlust auszugleichen. Dies wird so lange fortgesetzt, bis ein Gewinn eintritt. Nach einem Gewinn wird die Wette auf den ursprünglichen Einsatzwert zurückgesetzt. Ich habe die Gewinnchancen so festgelegt, dass sie Blackjack imitieren (49% Gewinnchance). Der Einfachheit halber entspricht der in einer Runde gewonnene oder verlorene Betrag dem Einsatz. Die Simulation endet, wenn die angegebene Anzahl von Runden verstrichen ist, die nächste Wette größer ist als das aktuell verfügbare Guthaben, das verfügbare Guthaben 0 erreicht oder der Zielgewinn erreicht ist.
Ich bin brandneu in Python und Codierung im Allgemeinen, daher wäre jedes Feedback willkommen.
import random
def main(rounds=10, bet=25, goal_profit=1000, each=False, end_script_prt=True):
"""Runs a simulation of the Martingale betting strategy over a specified number of rounds.
each = True will print a summary of each round's results. end_script_prt = True will
print a summary of the game's results"""
original_bet = bet
current_bet = bet
starting_funds = 5000
current_profit = 0
current_funds = starting_funds
round_n = 0
wins = 0
losses = 0
while current_profit < goal_profit\
and round_n < rounds\
and current_funds > 0\
and current_funds > current_bet:
round_n += 1
rng_v = rng()
current_funds += change_current_funds(current_bet, rng_v)
current_profit = current_profits(current_funds, starting_funds)
if winloss_generator(rng_v) == 'win':
wins += 1
elif winloss_generator(rng_v) == 'loss':
losses += 1
if each:
print('ROUND:', round_n, 'of', rounds)
print('BET:', current_bet)
print('OUTCOME:', winloss_generator(rng_v).capitalize())
print('WINS/LOSSES:', wins, 'Wins', losses, 'losses')
print('CURRENT FUNDS:', current_funds)
print('CURRENT PROFIT:', current_profit)
print()
current_bet = change_bet(original_bet, current_bet, rng_v)
print()
if end_script_prt:
end_script(round_n, wins, losses, starting_funds, current_funds, goal_profit, current_profit)
return change_iterated_winloss(current_profit, goal_profit)
def rng():
"""Returns random number"""
return random.random()
def winloss_generator(rng_v):
"""Returns win/loss condition"""
if rng_v <= .49:
return 'win'
if rng_v > .49:
return 'loss'
def change_current_funds(current_bet, rng_v):
"""Returns change in funds resulting from round outcome"""
if winloss_generator(rng_v) == 'win':
return current_bet
if winloss_generator(rng_v) == 'loss':
return current_bet * -1
def change_bet(original_bet, current_bet, rng_v):
"""Returns updated bet value
If outcome is a win, bet is reset to original value. If outcome is a loss bet is doubled"""
if winloss_generator(rng_v) == 'win':
return original_bet
if winloss_generator(rng_v) == 'loss':
return current_bet * 2
def current_profits(current_funds, starting_funds):
"""Returns current profit"""
return current_funds - starting_funds
def end_script(round_n, wins, losses, starting_funds, current_funds, goal_profit, current_profit):
"""Prints final outcome of the game and summary of the results"""
print('*************************')
if current_profit >= goal_profit:
print('YOU WIN!')
else:
print('YOU LOSE')
print('TOTAL ROUNDS:', round_n)
print('WIN/LOSS RECORD:', wins, 'Wins', losses, 'Losses')
print('STARTING FUNDS:', starting_funds)
print('ENDING FUNDS: ', current_funds)
print('GOAL PROFIT:', goal_profit)
print('ENDING PROFIT:', current_profit)
def change_iterated_winloss(current_profit, goal_profit):
"""Returns game's win/loss outcome as a string"""
if current_profit >= goal_profit:
w_l = 'w'
return w_l
else:
w_l = 'l'
return w_l
def iterated_winloss_count(iterations, each=False):
"""Returns a summary of the total win/loss record across game iterations. each = True will
print each game result individually"""
total_wins = 0
total_losses = 0
for x in range(iterations):
game_outcome = main(1000, 25, 5000, False, False)
if game_outcome == 'w':
total_wins += 1
if each:
print('WIN!')
if game_outcome == 'l':
total_losses += 1
if each:
print('LOSS')
print()
print('WINS/LOSSES OVER', iterations, 'ITERATIONS:', total_wins, 'Wins', total_losses, 'Losses')
# Single Game
if True:
main(1000, 25, 5000, True, True)
# Iterated Games
if False:
iterated_winloss_count(1000, False)
Antworten
Sie haben einige Funktionen mit einer ungewöhnlichen bedingten Struktur. Ich könnte etwas falsch verstehen, aber ich gehe davon aus, dass der Spieler entweder gewinnt oder verliert. In diesem Licht hat die zweite bedingte Prüfung keinen Zweck: einfach verwenden else.
def winloss_generator(rng_v):
if rng_v <= .49: # win
return 'win'
if rng_v > .49: # else loss
return 'loss'
Es ist nicht das häufigste Problem beim Lernen, aber Sie haben die Berechnungen erheblich überfaktorisiert, sodass eine einfache Sache schwer zu verstehen ist. Es wird eine Zufallszahl generiert, die den Gewinn / Verlust bestimmt (aber wir erinnern uns nicht an das Ergebnis). dann schlängelt sich diese Zufallszahl durch mehrere Schritte, von denen jeder anruft winloss_generator(RANDOM_NUM), was uns (erneut) sagt, ob es sich um einen Gewinn oder einen Verlust handelt. main()Bestimmen Sie stattdessen direkt das Ergebnis sofort.
won = (random.random() <= .49)
Wenn diese Variable gespeichert ist, sind die restlichen Berechnungen an einem Ort leicht zu verstehen. Wenn Berechnungen relativ einfach, eng miteinander verbunden und als Gruppe leicht zu verfolgen sind, halten Sie sie in der Regel zusammen:
current_funds += current_bet * (1 if won else -1)
current_profit = current_funds - starting_funds
wins += int(won)
losses += int(not won)
...
current_bet = original_bet if won else 2 * current_bet
Zusätzlich zum Über-Faktorisieren des Algorithmus haben Sie den Code unter dem Gesichtspunkt der Nebenwirkungen unterfaktorisiert (Druck ist hier der Nebeneffekt). Die allgemeine Idee ist, die Nebenwirkungen in der dünnen äußeren Schicht des Programms zu korrigieren. Der Rest des Codes kann dann nur im Bereich der Datenrückgabefunktionen ausgeführt werden (das ist zumindest die Hoffnung; die Realität stellt Herausforderungen dar). Hier ist eine Möglichkeit, wie Ihr Code überarbeitet werden kann, um diese Trennung zu erzwingen.
from collections import namedtuple
# A simple data object to store all relevant details
# for one round of play.
Round = namedtuple('Round', 'round_n won funds profit wins losses bet')
# Entry point.
def main():
# Run the rounds and get data back. No printing yet.
rounds = list(martingale(200, 25, 5000))
# Analyze the results as much as we like.
for r in rounds:
...
# Report the results. Printing OK here.
for r in rounds:
print(...)
# The algorithmic code of the betting strategy.
# It sticks fairly close to your original code, absent side effects.
def martingale(rounds=10, bet=25, goal_profit=1000):
funds = 5000
orig_bet = bet
orig_funds = funds
profit = 0
round_n = 0
wins = 0
losses = 0
while profit < goal_profit and round_n < rounds and funds > bet:
round_n += 1
won = (random.random() <= .49)
funds += bet * (1 if won else -1)
profit = funds - orig_funds
wins += int(won)
losses += int(not won)
yield Round(round_n, won, funds, profit, wins, losses, bet)
bet = orig_bet if won else 2 * bet
Dieses Design ist besser, weil Sie mehr damit machen können. Stellen Sie sich vor, Sie fügen Unterstützung für Befehlszeilenargumente zum Definieren der Eingabeparameter sowie verschiedene Optionen für verschiedene Arten von Analysen oder Berichten hinzu. Sie können all das hinzufügen, ohne den algorithmischen Code in zu ändern martingale(). Es ist jetzt auch möglich, eine andere Funktion zu schreiben, die eine andere Wettstrategie implementiert: Sie würde ebenfalls zurückkehren rounds, und Sie könnten sie mit demselben Code analysieren, der für verwendet wird martingale(). Schließlich möchten Sie möglicherweise eine Funktion wie diese testen können: entweder automatisiert oder ad hoc in Debugging-Sitzungen. Beides ist einfacher, wenn Sie die Funktion aufrufen und eine Antwort als Daten anstelle eines Stapels gedruckten Textes zurückerhalten können. Speichern Sie den Druck für später: Machen Sie zuerst die Daten richtig.