Martingale Bahis Simülatörü 2.0

Sep 22 2020

Bu, bir Martingale bahis simülatörü oluşturmanın ikinci aşamasıdır. Orijinal kod o kadar ağır bir yeniden düzenleme gerektiriyordu ki sıfırdan başladım.

Script, Martingale bahis stratejisini, bir kayıp meydana gelene kadar sabit bir miktarla bahis yapma stratejisini simüle eder; bu noktada, kaybı telafi etmek için bahis ikiye katlanır. Bu, bir kazanç oluşana kadar devam eder, bir galibiyetten sonra bahis orijinal bahis değerine sıfırlanır. Oranları Blackjack'i taklit edecek şekilde belirledim (% 49 kazanma şansı). Basit olması için, bir turda kazanılan veya kaybedilen miktar, bahse eşittir. Simülasyon, belirtilen tur sayısı geçtiğinde, bir sonraki bahsin boyutu mevcut mevcut fondan daha büyük olduğunda, mevcut fonlar 0'a ulaştığında veya hedef karı karşılandığında sona erer.

Python ve genel olarak kodlama konusunda yepyeni biriyim, bu nedenle herhangi bir geri bildirim takdir edilecektir.

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)

Yanıtlar

3 FMc Sep 22 2020 at 13:57

Alışılmadık bir koşullu yapıya sahip birkaç işleviniz var. Bir şeyi yanlış anlıyor olabilirim, ancak oyuncunun ya kazandığını ya da kaybettiğini varsayıyorum. Bu açıdan bakıldığında, ikinci koşullu kontrolün bir amacı yoktur: sadece kullanın else.

def winloss_generator(rng_v):
    if rng_v <= .49:            # win
        return 'win'
    if rng_v > .49:             # else loss
        return 'loss'

Bu, öğrenen insanlar arasındaki en yaygın problem değil, ancak hesaplamaları önemli ölçüde fazla faktörlendirdiniz ve anlaşılması zor olan basit bir şey. Rastgele bir sayı oluşturulur ve kazanç / kaybı belirleyecektir (ancak sonucu hatırlamıyoruz); daha sonra bu rastgele sayı, her biri çağıran birden çok adımdan geçer ve winloss_generator(RANDOM_NUM)bize (tekrar) bunun bir kazanç mı yoksa kayıp mı olduğunu söyler. Bunun yerine, doğrudan içeri, main()sadece sonucu hemen belirleyin.

won = (random.random() <= .49)

Bu değişken hatırlandığında, hesaplamaların geri kalanının tek bir yerde anlaşılması kolaydır. Hesaplamalar oldukça basit, yakından ilişkili ve bir grup olarak takip edilmesi kolay olduğunda, bunları genel bir kural olarak bir arada tutun:

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

Algoritmayı aşırı faktörlendirmeye ek olarak, kodu yan etkiler açısından eksik faktörlendirdiniz (burada yan etki yazdırma). Genel fikir, programın ince dış katmanındaki yan etkileri düzeltmektir. Kodun geri kalanı daha sonra tamamen veri döndüren işlevler alanında çalışabilir (en azından umut budur; gerçeklik zorluklar ortaya çıkarır). İşte bu ayrımı uygulamak için kodunuzun yeniden düzenlenmesinin bir yolu.

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

Bu tasarım daha iyidir çünkü onunla daha fazla şey yapabilirsiniz. Giriş parametrelerini tanımlamak için komut satırı bağımsız değişkenleri için destek ve ayrıca farklı analiz veya raporlama türleri için çeşitli seçenekler eklediğinizi hayal edin. Algoritmik kodu değiştirmeden hepsini ekleyebilirsiniz martingale(). Şimdi farklı bir bahis stratejisi uygulayan başka bir işlev yazmak da mümkün: o da geri dönecektir roundsve bunları kullanılan kodla analiz edebilirsiniz martingale(). Son olarak, isteyebileceğiniz başka bir şey de, bunun gibi bir işlevi test edebilmektir: otomatikleştirilmiş bir şekilde veya hata ayıklama oturumlarında geçici olarak. İşlevi çağırabilir ve bir yığın basılı metin yerine veri olarak yanıtla geri alırsanız her ikisi de daha kolaydır. Baskıyı daha sonrası için saklayın: önce verileri doğru şekilde alın.