A Yard Sale model.

Posted on Wed 16 August 2023 in analysis

Using jupyter notebook, to figure out unfairness in the world.

A Yard Sale Model

An interesting phenoma, that even playing a "fair" game, one player ( could be any ) alsways end up with all the money. I am trying to simulate this, with python. This is very inspired by this article from the Pudding: https://pudding.cool/2022/12/yard-sale/

First creating an individual

In [1]:
import random


class Person:
  def __init__(self, name, wealth):
    self.name = name
    self.wealth = wealth
    self.win = 0
    self.gamesplayed = 0
    self.ratio = 0
    self.max_bet_ratio = 0.25
    #Maximum bet limited to 25% of the wealth
    #Rounded to
    self.max_bet = round(self.max_bet_ratio*self.wealth)
  def __str__(self):
    self.ratio = 0 if self.gamesplayed == 0 else self.win/ self.gamesplayed
    return f"{self.name}\t(Wealth:{self.wealth})\tWin Ratio:{self.ratio}\tGames Played:{self.gamesplayed}"
  def gain(self,gain):
        self.wealth += gain
        self.gamesplayed += 1
        if gain > 0:
            self.win +=1
        elif gain == 0:
            #Compensating when one player is ruined and cannot bet any more moeny
            self.gamesplayed -= 1
        self.max_bet = round(self.max_bet_ratio*self.wealth)       

Now coding the game, a simple flip the coin.

In [2]:
def flip(player1, player2):
    #Making sure that player are betting affordable bets.
    bet = min(player1.max_bet,player2.max_bet)
    winner = random.choice(["H","T"])
    if winner == "H":
        player1.gain(bet)
        player2.gain(-bet)
    else:
        player2.gain(bet)
        player1.gain(-bet)  

Let's test that with 2 players, and playing 50 times

In [3]:
p1 = Person('chris',1000)
p2 = Person('dave',1000)

for i in range(50):   
    flip(p1,p2)


print(p1)
print(p2)
chris  (Wealth:1890)   Win Ratio:0.56  Games Played:50
dave    (Wealth:110)    Win Ratio:0.44  Games Played:50

Note that the game is fair as each player win roughly half of the time, however all the money end up in one player hands only.

Trying with 1000 games

In [4]:
p1 = Person('chris',1000)
p2 = Person('dave',1000)

for i in range(1000):   
    flip(p1,p2)


print(p1)
print(p2)
chris  (Wealth:2)  Win Ratio:0.44537815126050423   Games Played:119
dave    (Wealth:1998)   Win Ratio:0.5546218487394958    Games Played:119

Note that the betting stopped after few iterations iteration as one player is ruined.

In [5]:
players = [Person(str(i),1000) for i in range(10)]

And let them play against each others, many many times..

In [6]:
number_players = len(players)

print('Number of players',number_players )

for g in range(10000):
    team = random.sample(players[:], 2)
    for t in team:
        flip(team[0],team[1])

for p in players:
    print(p)
Number of players 10
0   (Wealth:9982)   Win Ratio:0.5015151515151515    Games Played:660
1   (Wealth:2)  Win Ratio:0.4909090909090909    Games Played:165
2   (Wealth:2)  Win Ratio:0.47058823529411764   Games Played:221
3   (Wealth:2)  Win Ratio:0.5311143270622286    Games Played:691
4   (Wealth:2)  Win Ratio:0.5284090909090909    Games Played:352
5   (Wealth:2)  Win Ratio:0.4425531914893617    Games Played:235
6   (Wealth:2)  Win Ratio:0.4840182648401826    Games Played:219
7   (Wealth:2)  Win Ratio:0.5158371040723982    Games Played:442
8   (Wealth:2)  Win Ratio:0.46464646464646464   Games Played:198
9   (Wealth:2)  Win Ratio:0.4482758620689655    Games Played:145

One player ended up with all the money, some were ruined only after 62 games...

So looks like ultra-rich are inevitable, even without taking talent into account.

In [ ]: