Skip to content

Instantly share code, notes, and snippets.

@dan070
Created April 17, 2025 05:54
Show Gist options
  • Save dan070/701c8639d86ccc4116c2a6018932b9d2 to your computer and use it in GitHub Desktop.
Save dan070/701c8639d86ccc4116c2a6018932b9d2 to your computer and use it in GitHub Desktop.
Monopoly solo simulation
import random
from collections import defaultdict, namedtuple
# Define the board positions
BoardPosition = namedtuple('BoardPosition', ['name', 'type'])
board = [
BoardPosition("Gå. Inkassera 4000.", None), ## 0
BoardPosition("Västerlånggatan (BRUN)", None),
BoardPosition("Card A - 1", "A"),
BoardPosition("Hornsgatan (BRUN)", None),
BoardPosition("Inkomstskatt", None),
BoardPosition("Södra station", None),
BoardPosition("Folkungagatan (BLÅ)", None),
BoardPosition("Card C - 2", "C"),
BoardPosition("Götgatan (BLÅ)", None),
BoardPosition("Ringvägen (BLÅ)", None),
BoardPosition("Fängelse", "prison"), ## 10
BoardPosition("St Eriksgatan (LILA)", None),
BoardPosition("Elverket", None),
BoardPosition("Odengatan (LILA)", None),
BoardPosition("Valhallavägen (LILA)", None),
BoardPosition("Östra station", None), ## 15
BoardPosition("Sturegatan (ORANGE)", None),
BoardPosition("Card A - 3", "A"),
BoardPosition("Karlavägen (ORANGE)", None),
BoardPosition("Narvavägen (ORANGE)", None),
BoardPosition("Fri Parkering", None), ## 20
BoardPosition("Strandvägen (RÖD)", None),
BoardPosition("Card C - 4", "C"),
BoardPosition("Kungsträdgårdsgatan (RÖD)", None),
BoardPosition("Hamngatan (RÖD)", None), ## 24
BoardPosition("Centralstation", None),
BoardPosition("Vasagatan (GUL)", None),
BoardPosition("Kungsgatan (GUL)", None),
BoardPosition("Vattenledningsverket", None),
BoardPosition("Stureplan (GUL)", None),
BoardPosition("Gå i fängelse", "goto_prison"), ## 30
BoardPosition("Gustav Adolfs torg (GRÖN)", None),
BoardPosition("Drottninggatan (GRÖN)", None),
BoardPosition("Card A - 5", "A"),
BoardPosition("Diplomatstaden (GRÖN)", None),
BoardPosition("Norra station", None),
BoardPosition("Card C - 6", "C"),
BoardPosition("Centrum (MÖRKBLÅ)", None),
BoardPosition("Lyxskatt", None),
BoardPosition("Normalmstorg (MÖRKBLÅ)", None), ## 39
]
# Define the cards
Card = namedtuple('Card', ['destination', 'probability'])
cards_A = [
Card(None, 14/16), # Många kort
Card(0, 1/16), # Gå
Card(10, 1/16), # Fängelse
]
cards_C = [
Card(None, 8/16), # Många kort
Card(0, 1/16), # Gå
Card(11, 1/16), # St erik
Card(39, 1/16), # Norrm torg
Card(24, 1/16), # Hamngatan
Card(15, 1/16), # Östra station
Card(1, 1/16), # Västerlånggatan
Card(10, 1/16), # Fängelse
Card(-3, 1/16), # Gå tilbaka 3 steg!!
]
def draw_card(pile):
r = random.random()
cumulative_probability = 0.0
for card in pile:
cumulative_probability += card.probability
if r < cumulative_probability:
return card
return pile[-1] # Fallback, should not happen
def roll_dice():
return random.randint(1, 6), random.randint(1, 6)
def simulate_movement(num_simulations, verbose = False):
position = 0
double_count = 0
landings = defaultdict(int)
timeseries = []
for _ in range(num_simulations):
dice1, dice2 = roll_dice()
timeseries.append((position, board[position].name))
if(verbose):
print(f"pos = {position} + {dice1} {dice2} = {position + dice1 + dice2}")
if dice1 == dice2:
double_count += 1
if double_count == 3:
position = 10 # Go to prison
double_count = 0
else:
pass
position = (position + dice1 + dice2) % len(board)
square = board[position]
if square.type == "A":
card = draw_card(cards_A)
if card.destination is not None:
position = card.destination
elif square.type == "C":
card = draw_card(cards_C)
if card.destination is not None:
if card.destination < 0 :
position = position + card.destination ## 'Gå tillbaka 3 steg'-kortet
else:
position = card.destination
elif square.type == "goto_prison":
timeseries.append((position, board[position].name)) # Registrera att man landat på gå i fängelse
landings[position] += 1 # Registrera
position = 10 # Go to prison
landings[position] += 1
double_count = 0
return landings, timeseries
# Simulate the game
num_simulations = 1000000
landings, timeseries = simulate_movement(num_simulations, verbose=False)
# Output the results
print("Landings distribution:")
for position, count in landings.items():
print(f"{board[position].name}: {count / num_simulations * 100:.2f}%")
print("\nTimeseries of movements:")
for move in timeseries[:10]: # Print first 10 movements for brevity
print(f"Position: {move[0]}, Square: {move[1]}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment