Martingale Strategy

A martingale is a class of betting strategies that originated from and were popular in 18th-century France. The simplest of these strategies was designed for a game in which the gambler wins the stake if a coin comes up heads and loses if it comes up tails. The strategy had the gambler double the bet after every loss, so that the first win would recover all previous losses plus win a profit equal to the original stake. Thus the strategy is an instantiation of the St. Petersburg paradox.


#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>


typedef enum {
    HEADS,
    TAILS,
    NONE
} Choice;

char* choice_to_str(Choice choice)
{
    switch(choice)
    {
        case HEADS:
            return "HEADS";
        case TAILS:
            return "TAILS";
        default:
            return "NONE";
    }
}

typedef enum {
    WIN,
    LOSS,
    DRAW
} Result;

char* result_to_str(Result result)
{
    switch(result)
    {
        case WIN:
            return "WIN";
        case LOSS:
            return "LOSS";
        default:
            return "DRAW";
    }
}

typedef struct {
    Choice choice;
    int amount;
    Result result;
} Bet;

typedef struct {
    int cash;
    Bet (*strategy)(int cash, Bet last_round);
} Player;

Bet player_strategy(int cash, Bet last_round)
{
    Bet bet;
    
    if(last_round.result == LOSS)
    {
        bet.amount = last_round.amount * 2;
        bet.choice = HEADS;
    }
    else
    {
        bet.amount = 100;
        bet.choice = HEADS;
    }
    
    return bet;
}

void simulate(Player player)
{
    bool runlog = false;
    if(runlog == false)
    {
        freopen("nul", "w", stdout);
    }
    
    // 1) Setup.
    Bet round;
    round.choice = NONE;
    round.amount = 0;
    round.result = DRAW;
    
    int starting_cash = player.cash;
    int win_streak = 0, best_win_streak = 0;
    int loss_streak = 0, best_loss_streak = 0;
    
    int max_rounds = 5000;
    int round_number = 1;
    while(round_number <= max_rounds)
    {
        printf("===== Round %.4d =====\n", round_number);
        printf("Player has $%d.\n", player.cash);
        
        // 2) Get the player's bet.
        Bet player_bet = player.strategy(player.cash, round);
        
        printf("Player is betting %d on %s.\n", player_bet.amount, choice_to_str(player_bet.choice));
        
        if(player_bet.amount > player.cash)
        {
            // Player bet is greater than their cash. You lose!
            printf("Player went broke on round %d.\n", round_number);
            break;
        }
        else
        {
            // 3) Flip coin.
            round.choice = TAILS;
            if(rand() & 1)
            {
                round.choice = HEADS;
            }
            
            printf("House gives %s.\n", choice_to_str(round.choice));
            
            // 4) Payout.
            if(round.choice == player_bet.choice)
            {
                round.result = WIN;
                player.cash += player_bet.amount;
                
                loss_streak = 0;
                win_streak++;
                if(win_streak > best_win_streak)
                    best_win_streak = win_streak;
                
                printf("Player wins!\n");
            }
            else
            {
                round.result = LOSS;
                player.cash -= player_bet.amount;
                
                win_streak = 0;
                loss_streak++;
                if(loss_streak > best_loss_streak)
                    best_loss_streak = loss_streak;
                
                printf("Player loses!\n");
            }
            
            // Let the player know how much they bet this round.
            round.amount = player_bet.amount;
        }
        
        puts("");
        round_number++;
    }
    
    fprintf(stderr, "===== Game Over =====\n");
    fprintf(stderr, "Final round: %d\n", round_number - 1);
    fprintf(stderr, "Player cash: $%d\n", player.cash);
    fprintf(stderr, "Difference: ");
    if(starting_cash > player.cash)
    {
        fprintf(stderr, "- $%d\n", starting_cash - player.cash);
    }
    else
    {
        fprintf(stderr, "+ $%d\n", player.cash - starting_cash);
    }
    fprintf(stderr, "Highest win streak:  %d\n", best_win_streak);
    fprintf(stderr, "Highest loss streak: %d\n", best_loss_streak);
}

int main(int argc, char* argv[])
{
    srand(time(NULL));
    
    Player player;
    player.cash = 1000000;
    player.strategy = player_strategy;
    
    simulate(player);
    
    return EXIT_SUCCESS;
}

Code language: C++ (cpp)

Comments

One response to “Martingale Strategy”

  1. Aura Avatar

    Nice article. Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *