59 lines
1.6 KiB
Python
59 lines
1.6 KiB
Python
import re
|
|
from datetime import datetime, timezone
|
|
from typing import List, Optional
|
|
from pydantic import BaseModel, Field, field_validator
|
|
|
|
|
|
class PlayerCreate(BaseModel):
|
|
name: str = Field(..., min_length=1, max_length=32, description="Display name of the player")
|
|
color: str = Field(..., description="Hex color code (e.g. #FF5733) or valid CSS color name")
|
|
|
|
@field_validator("name")
|
|
@classmethod
|
|
def validate_name(cls, v: str) -> str:
|
|
cleaned = v.strip()
|
|
if not cleaned:
|
|
raise ValueError("Player name cannot be empty or only whitespace")
|
|
return cleaned
|
|
|
|
@field_validator("color")
|
|
@classmethod
|
|
def validate_color(cls, v: str) -> str:
|
|
cleaned = v.strip()
|
|
# Accept #RRGGBB, #RGB, or standard alphanumeric color names
|
|
if re.match(r"^#(?:[0-9a-fA-F]{3}){1,2}$", cleaned):
|
|
return cleaned.upper()
|
|
if re.match(r"^[a-zA-Z]{3,20}$", cleaned):
|
|
return cleaned.lower()
|
|
raise ValueError("Color must be a valid hex code (e.g. #FF4444) or color name (e.g. crimson)")
|
|
|
|
|
|
class Player(BaseModel):
|
|
id: str
|
|
name: str
|
|
color: str
|
|
x: int
|
|
y: int
|
|
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
|
|
|
|
|
class BoardConfig(BaseModel):
|
|
min_x: int = 0
|
|
max_x: int = 64
|
|
min_y: int = 0
|
|
max_y: int = 64
|
|
grid_cells_x: int = 64
|
|
grid_cells_y: int = 64
|
|
|
|
|
|
class BoardState(BaseModel):
|
|
config: BoardConfig
|
|
player_count: int
|
|
players: List[Player]
|
|
|
|
|
|
class ApiResponse(BaseModel):
|
|
success: bool
|
|
message: str
|
|
data: Optional[dict] = None
|