File size: 3,809 Bytes
71b378e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
"""
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]