|
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
|