from dataclasses import dataclass, field
from typing import Dict, List, Optional
from enum import Enum
import random
class BuildingType(Enum):
"""All available building types"""
# Residential
SMALL_HOUSE = "small_house"
MEDIUM_HOUSE = "medium_house"
LARGE_HOUSE = "large_house"
# Commercial
SMALL_SHOP = "small_shop"
SUPERMARKET = "supermarket"
MALL = "mall"
# Industrial
SMALL_FACTORY = "small_factory"
LARGE_FACTORY = "large_factory"
# Infrastructure
ROAD = "road"
PARK = "park"
PLAZA = "plaza"
# Special
TOWN_HALL = "town_hall"
POWER_PLANT = "power_plant"
@dataclass
class BuildingConfig:
"""Configuration for each building type"""
name: str
cost: int
income: int # Per tick
population: int # Positive = adds population, negative = requires jobs
power_required: bool = False
requires_population: int = 0
description: str = ""
# Building configurations
BUILDING_CONFIGS = {
BuildingType.SMALL_HOUSE: BuildingConfig(
name="Small House",
cost=5000,
income=-50,
population=10,
description="Basic residential building"
),
BuildingType.MEDIUM_HOUSE: BuildingConfig(
name="Medium House",
cost=12000,
income=-120,
population=25,
description="Medium residential building"
),
BuildingType.LARGE_HOUSE: BuildingConfig(
name="Large House",
cost=25000,
income=-250,
population=50,
power_required=True,
description="Large residential building"
),
BuildingType.SMALL_SHOP: BuildingConfig(
name="Small Shop",
cost=8000,
income=100,
population=-5,
requires_population=20,
description="Small retail store"
),
BuildingType.SUPERMARKET: BuildingConfig(
name="Supermarket",
cost=25000,
income=300,
population=-15,
requires_population=50,
power_required=True,
description="Large grocery store"
),
BuildingType.MALL: BuildingConfig(
name="Shopping Mall",
cost=80000,
income=800,
population=-40,
requires_population=100,
power_required=True,
description="Large shopping center"
),
BuildingType.SMALL_FACTORY: BuildingConfig(
name="Small Factory",
cost=15000,
income=200,
population=-20,
power_required=True,
description="Small industrial building"
),
BuildingType.LARGE_FACTORY: BuildingConfig(
name="Large Factory",
cost=50000,
income=500,
population=-50,
power_required=True,
description="Large industrial complex"
),
BuildingType.ROAD: BuildingConfig(
name="Road",
cost=500,
income=0,
population=0,
description="Connects buildings for economy boost"
),
BuildingType.PARK: BuildingConfig(
name="Park",
cost=3000,
income=-20,
population=5,
description="Increases population happiness"
),
BuildingType.PLAZA: BuildingConfig(
name="Plaza",
cost=8000,
income=-40,
population=10,
description="Large public space"
),
BuildingType.TOWN_HALL: BuildingConfig(
name="Town Hall",
cost=50000,
income=-100,
population=100,
description="City administration building"
),
BuildingType.POWER_PLANT: BuildingConfig(
name="Power Plant",
cost=100000,
income=-500,
population=-30,
description="Provides power to buildings"
)
}
@dataclass
class Building:
"""A placed building in the game"""
building_type: BuildingType
x: int
y: int
owner_id: str
name: Optional[str] = None
placed_at: float = 0.0
def to_dict(self):
return {
"type": self.building_type.value,
"x": self.x,
"y": self.y,
"owner_id": self.owner_id,
"name": self.name
}
@dataclass
class Player:
"""Player data"""
player_id: str
nickname: str
money: int = 100000 # Starting money
population: int = 0
color: str = field(default_factory=lambda: f"#{random.randint(0, 0xFFFFFF):06x}")
last_online: float = 0.0
is_online: bool = True
def to_dict(self):
return {
"player_id": self.player_id,
"nickname": self.nickname,
"money": self.money,
"population": self.population,
"color": self.color,
"is_online": self.is_online
}
def can_afford(self, cost: int) -> bool:
return self.money >= cost
def deduct_money(self, amount: int):
self.money -= amount
def add_money(self, amount: int):
self.money += amount