Created
April 17, 2025 05:54
-
-
Save dan070/701c8639d86ccc4116c2a6018932b9d2 to your computer and use it in GitHub Desktop.
Monopoly solo simulation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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