official.ghost.logic
Deploy D&D Campaign Manager v2
71b378e
"""
Validation utilities for game objects
"""
from typing import List, Dict, Any, Tuple
from src.models.character import Character, DnDRace, DnDClass
from src.models.campaign import Campaign
def validate_character(character: Character) -> Tuple[bool, List[str]]:
"""
Validate character data
Returns:
Tuple of (is_valid, error_messages)
"""
errors = []
# Name validation
if not character.name or len(character.name.strip()) == 0:
errors.append("Character name cannot be empty")
# Stats validation
stats = character.stats
for stat_name in ['strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma']:
stat_value = getattr(stats, stat_name)
if stat_value < 1 or stat_value > 30:
errors.append(f"{stat_name.title()} must be between 1 and 30")
# HP validation
if character.current_hit_points < 0:
errors.append("Current HP cannot be negative")
if character.current_hit_points > character.max_hit_points:
errors.append("Current HP cannot exceed max HP")
if character.max_hit_points < 1:
errors.append("Max HP must be at least 1")
# AC validation
if character.armor_class < 1:
errors.append("Armor class must be at least 1")
# Level validation
if character.level < 1 or character.level > 20:
errors.append("Level must be between 1 and 20")
# XP validation
if character.experience_points < 0:
errors.append("Experience points cannot be negative")
return len(errors) == 0, errors
def validate_campaign(campaign: Campaign) -> Tuple[bool, List[str]]:
"""
Validate campaign data
Returns:
Tuple of (is_valid, error_messages)
"""
errors = []
# Name validation
if not campaign.name or len(campaign.name.strip()) == 0:
errors.append("Campaign name cannot be empty")
# Summary validation
if not campaign.summary or len(campaign.summary.strip()) == 0:
errors.append("Campaign summary cannot be empty")
# Main conflict validation
if not campaign.main_conflict or len(campaign.main_conflict.strip()) == 0:
errors.append("Main conflict cannot be empty")
# Party size validation
if campaign.party_size < 1 or campaign.party_size > 10:
errors.append("Party size must be between 1 and 10")
# Session validation
if campaign.current_session < 1:
errors.append("Current session must be at least 1")
if campaign.total_sessions < 0:
errors.append("Total sessions cannot be negative")
return len(errors) == 0, errors
def validate_stat_array(stats: Dict[str, int]) -> Tuple[bool, List[str]]:
"""Validate D&D ability score array"""
errors = []
required_stats = ['strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma']
for stat in required_stats:
if stat not in stats:
errors.append(f"Missing required stat: {stat}")
else:
value = stats[stat]
if value < 1 or value > 30:
errors.append(f"{stat.title()} must be between 1 and 30, got {value}")
return len(errors) == 0, errors
def is_valid_race(race: str) -> bool:
"""Check if race is valid"""
try:
DnDRace(race)
return True
except ValueError:
return False
def is_valid_class(character_class: str) -> bool:
"""Check if class is valid"""
try:
DnDClass(character_class)
return True
except ValueError:
return False
def get_available_races() -> List[str]:
"""Get list of available races"""
return [race.value for race in DnDRace]
def get_available_classes() -> List[str]:
"""Get list of available classes"""
return [cls.value for cls in DnDClass]