Game of Oligarchy

I came across a post from Brewster Kahle before Christmas where he was talking about a new game he had invented illustrating the problem of wealth accumulation and redistribution along the lines of Thomas Piketty.

There was also a php implementation of the game by Neal Krawetz to illustrate how easy it is for one individual to accumulate all the wealth. Alongside that is a "socialism" extension to show how redistribution of wealth through taxation doesn't stop the accumulation of wealth but puts a brake on the super-concentration of wealth without completely forcing everyone to have the same income - a frequently levelled argument for not doing wealth redistribution. See the links above for the rules as they were implemented.

Neal's implementation creates a table-based turn by turn simulation of the game but I wondered if I could use a different tool to give it a more interactive feel. Of course, I thought of my new favourite multi-media programming tool - Processing!

I implemented the whole "game" in one python file but split it up into a class for the Player and the game logic was left in the default application drawing code.

grid

Player

grid

The player has a location on the board, a number for identification, and a sum of money. All players start with the same amount. Rather than getting too fancy to begin with, I represent each player as a square with their number in the centre and use colour coding to denote how well they are doing. Bright green for lots of money, darker green for modest amounts, red for close to losing, and grey for out of the game.


from decimal import *

class Player(object):
    
    def __init__(self, number, x, y):
        self.number = number
        self.xpos = x
        self.ypos = y
        self.money = 100
       
    def __str__(self):
        return 'player ' + str(self.number) + ' has ' + str(self.money)
    
    def display(self):
        
        rectMode(CENTER)
        
        colour = color(128, 128, 128)
        if self.money > 0:
            if self.money > 10:
                if self.money > 100:
                    colour = color(0, 255, 0)
                else:    
                    colour = color(0, 128, 0)
            else:
                colour = color(128, 0, 0)
                
        fill(colour)
        box_size = 48
        rect(self.xpos, self.ypos, box_size, box_size)
        textSize(24)
        fill(color(255))
        text(str(self.number), self.xpos, self.ypos)
        
    def is_playing(self):
        return self.money > 0
    
    def stake(self):
        amount = Decimal(self.money / 2).to_integral_value()
        amount = max(amount, 1)
        println(str(self) + ' stakes ' + str(amount))
        return amount
    
    def lose(self, amount):
        println(str(self) + ', loses ' + str(amount))
        self.money = max(self.money - amount, 0)
            
    def win(self, amount):
        println(str(self) + ', wins ' + str(amount))
        self.money += amount

The rules also call for each player to declare how much they are willing to bet (half their pot of money) and be able to win or lose that amount.

grid

Simple Game

Once the player was done, I moved onto the game logic itself. I created an array of 9 players and laid them out in a grid. The frame rate for the game is super slow at 1 fps just because I am using the draw method as the turn indicator and didn't want the game to be over before you could blink.

grid

The original game calls for players to play against a random opponent selected from the other players. For this initial version, I elected not to do that but just to try things out with a simple coin toss for each player and award a win or a loss depending on whether heads or tails was returned.


coin_options = 'heads', 'tails'

players = [ ]
                
def setup():
  # super slow so we can see the 
  # game progress in real time  
  frameRate(1)
  size(200, 200)
  
  # create all the players
  player_number = 1
  for column in range(1, 4):
      for row in range(1, 4):
          p = Player(player_number, column * 50, row * 50)
          players.append(p)
          player_number += 1

def draw():
  background(255)
  
  for p in players:
    if p.is_playing():
        amount = p.stake()
        
        # toss a coin
        pick = int(random(len(coin_options)))
        heads_or_tails = coin_options[pick]
        println('coin is ' + heads_or_tails)  
        if heads_or_tails == 'tails':
            p.lose(amount)
        else:
            p.win(amount)    
    
    p.display()
  
  saveFrame("grid-######.png")

I also added in some code to capture each frame so you can see how the game proceeds through each turn.

grid

Enhancements

Next I think we should make the players play against each other with a more sophisticated selection routine and maybe illustrate the winning and losing more explicitly, perhaps by increasing and decreasing the size of the player's avatar depending on whether they are winning or losing. There could be some interesting animations to try with that.

grid