Tworzenie postaci do gry
Część sekcji Programowanie obiektowe ścieżki Python w Coddy. Lekcja 63 z 64.
Wyzwanie
ŚredniW tym wyzwaniu zaimplementujesz wieloplikowy system postaci RPG z kompleksowym zestawem testów.
character.py- Zaimplementuj bazową klasę Characterwarrior.py- Zaimplementuj podklasę Warriormage.py- Zaimplementuj podklasę Magerogue.py- Zaimplementuj podklasę Rogueability.py- Zaimplementuj klasę Ability
Każdy plik zawiera szczegółowe komentarze TODO, które wskazują, jak przeprowadzić implementację. Postępuj zgodnie z tymi komentarzami, aby mieć pewność, że Twój kod spełnia wszystkie wymagania.
Spróbuj swoich sił
from character import Character
from warrior import Warrior
from mage import Mage
from rogue import Rogue
from ability import Ability
# Kompleksowa obsługa przypadków testowych obejmująca wszystkie scenariusze i przypadki brzegowe
test_case = input()
if test_case == "character_creation":
# Test tworzenia różnych klas postaci
warrior = Warrior("Aragorn", 1)
mage = Mage("Gandalf", 1)
rogue = Rogue("Legolas", 1)
print(f"Warrior: {warrior.name}, HP: {warrior.health}, Mana: {warrior.mana}, Str: {warrior.strength}")
print(f"Mage: {mage.name}, HP: {mage.health}, Mana: {mage.mana}, Int: {mage.intelligence}")
print(f"Rogue: {rogue.name}, HP: {rogue.health}, Mana: {rogue.mana}, Agi: {rogue.agility}")
elif test_case == "character_levelup":
# Test awansowania na kolejny poziom dla różnych klas
warrior = Warrior("Aragorn")
mage = Mage("Gandalf")
rogue = Rogue("Legolas")
print("Before level up:")
print(f"Warrior - Level: {warrior.level}, HP: {warrior.max_health}, Str: {warrior.strength}")
print(f"Mage - Level: {mage.level}, Mana: {mage.max_mana}, Int: {mage.intelligence}")
print(f"Rogue - Level: {rogue.level}, Agi: {rogue.agility}")
warrior.level_up()
mage.level_up()
rogue.level_up()
print("\nAfter level up:")
print(f"Warrior - Level: {warrior.level}, HP: {warrior.max_health}, Str: {warrior.strength}")
print(f"Mage - Level: {mage.level}, Mana: {mage.max_mana}, Int: {mage.intelligence}")
print(f"Rogue - Level: {rogue.level}, Agi: {rogue.agility}")
elif test_case == "combat_basic":
# Test podstawowych mechanik walki
warrior = Warrior("Aragorn", 5)
enemy = Character("Orc", 3)
print(f"Initial HP - {warrior.name}: {warrior.health}, {enemy.name}: {enemy.health}")
# Wojownik atakuje wroga
warrior.attack(enemy)
print(f"After warrior attack - Enemy HP: {enemy.health}")
# Wróg kontratakuje
enemy.attack(warrior)
print(f"After enemy attack - Warrior HP: {warrior.health}")
# Sprawdź, czy postać żyje
print(f"Is warrior alive? {warrior.is_alive()}")
print(f"Is enemy alive? {enemy.is_alive()}")
elif test_case == "class_specific_attacks":
# Test implementacji ataków specyficznych dla poszczególnych klas
warrior = Warrior("Aragorn", 5)
mage = Mage("Gandalf", 5)
rogue = Rogue("Legolas", 5)
target = Character("Training Dummy", 10)
target.defense = 0 # Wyzeruj obronę, aby dokładnie porównać obrażenia
# Przywróć początkowe zdrowie celu między atakami
initial_health = target.health
warrior.attack(target)
warrior_damage = initial_health - target.health
target.health = initial_health
mage.attack(target)
mage_damage = initial_health - target.health
target.health = initial_health
rogue.attack(target)
rogue_damage = initial_health - target.health
print(f"Warrior damage: {warrior_damage:.1f}")
print(f"Mage damage: {mage_damage:.1f}")
print(f"Rogue damage: {rogue_damage:.1f}")
# Sprawdź regenerację many maga
initial_mana = mage.mana
mage.attack(target)
print(f"Mage mana before attack: {initial_mana}, after attack: {mage.mana}")
elif test_case == "abilities":
# Test systemu umiejętności
fireball = Ability("Fireball", 30, 25)
slash = Ability("Slash", 15, 20)
mage = Mage("Gandalf", 3)
warrior = Warrior("Aragorn", 3)
mage.learn_ability(fireball)
warrior.learn_ability(slash)
target = Character("Orc", 5)
initial_health = target.health
# Przetestuj użycie umiejętności przez maga
print(f"Mage mana before: {mage.mana}")
mage.use_ability(0, target)
print(f"Mage mana after: {mage.mana}")
print(f"Target health: {target.health}")
target.health = initial_health
# Przetestuj użycie umiejętności przez wojownika
print(f"Warrior mana before: {warrior.mana}")
warrior.use_ability(0, target)
print(f"Warrior mana after: {warrior.mana}")
print(f"Target health: {target.health}")
# Przetestuj sytuację, gdy brakuje many
mage.mana = 0
mage.use_ability(0, target)
elif test_case == "damage_calculation":
# Przetestuj obliczanie obrażeń z uwzględnieniem obrony
warrior = Warrior("Aragorn", 5)
low_defense = Character("Goblin", 3)
low_defense.defense = 2
high_defense = Character("Armored Knight", 3)
high_defense.defense = 15
# Zaatakuj cel o niskiej obronie
damage_to_low = warrior.attack(low_defense)
# Zaatakuj cel o wysokiej obronie
damage_to_high = warrior.attack(high_defense)
print(f"Damage to low defense target: {damage_to_low:.1f}")
print(f"Damage to high defense target: {damage_to_high:.1f}")
# Przetestuj zasadę minimalnych obrażeń
super_defense = Character("Impenetrable Shield", 1)
super_defense.defense = 100
damage_to_super = warrior.attack(super_defense)
print(f"Damage to extremely high defense: {damage_to_super:.1f}")
elif test_case == "full_battle_simulation":
# Przetestuj pełną walkę między postaciami
warrior = Warrior("Aragorn", 5)
mage = Mage("Saruman", 5)
fireball = Ability("Fireball", 30, 40)
ice_spike = Ability("Ice Spike", 25, 35)
cleave = Ability("Cleave", 20, 30)
warrior.learn_ability(cleave)
mage.learn_ability(fireball)
mage.learn_ability(ice_spike)
print(f"Battle begins: {warrior.name} vs {mage.name}")
print(f"{warrior.name}: {warrior.health}/{warrior.max_health} HP, {warrior.mana}/{warrior.max_mana} Mana")
print(f"{mage.name}: {mage.health}/{mage.max_health} HP, {mage.mana}/{mage.max_mana} Mana")
round_num = 1
while warrior.is_alive() and mage.is_alive():
print(f"\n--- Round {round_num} ---")
# Tura wojownika
if round_num % 3 == 0 and warrior.mana >= cleave.mana_cost:
warrior.use_ability(0, mage)
else:
warrior.attack(mage)
# Sprawdź, czy mag został pokonany
if not mage.is_alive():
print(f"{mage.name} has been defeated!")
break
# Tura maga
if mage.mana >= fireball.mana_cost:
mage.use_ability(0, warrior)
else:
mage.attack(warrior)
# Sprawdź, czy wojownik został pokonany
if not warrior.is_alive():
print(f"{warrior.name} has been defeated!")
break
print(f"Status: {warrior.name} ({warrior.health:.1f} HP, {warrior.mana} Mana) | {mage.name} ({mage.health:.1f} HP, {mage.mana} Mana)")
round_num += 1
# Ograniczenie zapobiegające nieskończonym pętlom
if round_num > 10:
print("Battle exceeded 10 rounds and was called a draw.")
break
print("\nBattle Results:")
print(f"{warrior.name}: {warrior.health:.1f}/{warrior.max_health} HP remaining")
print(f"{mage.name}: {mage.health:.1f}/{mage.max_health} HP remaining")
if warrior.is_alive() and not mage.is_alive():
print(f"{warrior.name} wins!")
elif mage.is_alive() and not warrior.is_alive():
print(f"{mage.name} wins!")
else:
print("The battle ended in a draw!")
elif test_case == "inheritance_validation_test":
# Kompleksowa weryfikacja dziedziczenia
objects = []
if 'Character' in locals():
objects.append(Character('test_param'))
if 'Warrior' in locals():
objects.append(Warrior('test_param'))
if 'Mage' in locals():
objects.append(Mage('test_param'))
if 'Rogue' in locals():
objects.append(Rogue('test_param'))
if 'Ability' in locals():
objects.append(Ability('test_param', 10, 20))
for obj in objects:
print(f'{type(obj).__name__}:')
print(f' MRO: {[cls.__name__ for cls in type(obj).__mro__]}')
print()
elif test_case == "method_overriding_test":
# Sprawdź działanie nadpisywania metod
print('Testing method overriding...')
# Utwórz instancje i przetestuj nadpisane metody
if 'Warrior' in locals():
obj = Warrior('test')
print(f'Warrior methods work correctly')
if 'Mage' in locals():
obj = Mage('test')
print(f'Mage methods work correctly')
if 'Rogue' in locals():
obj = Rogue('test')
print(f'Rogue methods work correctly')
elif test_case == "attribute_access_test":
# Sprawdź dostęp do atrybutów
print('Testing attribute access...')
if 'Character' in locals():
obj = Character('test')
print(f'Character attributes accessible')
if 'Warrior' in locals():
obj = Warrior('test')
print(f'Warrior attributes accessible')
if 'Mage' in locals():
obj = Mage('test')
print(f'Mage attributes accessible')
if 'Rogue' in locals():
obj = Rogue('test')
print(f'Rogue attributes accessible')
if 'Ability' in locals():
obj = Ability('test', 10, 20)
print(f'Ability attributes accessible')
elif test_case == "boundary_conditions_test":
# Sprawdź warunki brzegowe i wartości graniczne
print('Testing boundary conditions...')
# Sprawdź postać z 0 punktów zdrowia
char = Character("Test", 1)
char.health = 0
print(f"Character at 0 HP is alive: {char.is_alive()}")
# Sprawdź postać z 1 punktem zdrowia
char2 = Character("Test2", 1)
char2.health = 1
print(f"Character at 1 HP is alive: {char2.is_alive()}")
# Sprawdź nieprawidłowy indeks umiejętności (ujemny)
warrior = Warrior("Test", 1)
result = warrior.use_ability(-1, char)
print(f"Invalid negative ability index returns: {result}")
# Sprawdź nieprawidłowy indeks umiejętności (zbyt wysoki)
result = warrior.use_ability(999, char)
print(f"Invalid high ability index returns: {result}")
# Sprawdź minimalne obrażenia (1) przy bardzo wysokiej obronie
attacker = Character("Attacker", 1)
defender = Character("Defender", 1)
defender.defense = 1000
initial_hp = defender.health
attacker.attack(defender)
damage = initial_hp - defender.health
print(f"Minimum damage dealt: {damage}")
print('Boundary conditions test completed')
elif test_case == "error_handling_test":
# Sprawdź obsługę błędów i sytuacje wywołujące wyjątki
print('Testing error handling...')
# Przetestuj użycie zdolności przy niewystarczającej ilości many
mage = Mage("TestMage", 1)
ability = Ability("Expensive", 1000, 50)
mage.learn_ability(ability)
target = Character("Target", 1)
result = mage.use_ability(0, target)
print(f"Ability with insufficient mana returns: {result}")
# Przetestuj użycie zdolności, gdy nie nauczono się żadnych zdolności
warrior = Warrior("TestWarrior", 1)
result = warrior.use_ability(0, target)
print(f"Using non-existent ability returns: {result}")
# Sprawdź, czy zdrowie nie spada poniżej zera
char = Character("Test", 1)
char.take_damage(1000)
print(f"Health after massive damage: {char.health}")
print('Error handling test completed')
elif test_case == "polymorphic_behavior_test":
# Przetestuj zachowanie polimorficzne obiektów różnych typów
print('Testing polymorphic behavior...')
# Utwórz listę postaci różnych typów
characters = [
Character("Generic", 1),
Warrior("WarriorTest", 1),
Mage("MageTest", 1),
Rogue("RogueTest", 1)
]
# Sprawdź, czy wszystkie mogą być traktowane jako Character
for char in characters:
print(f"{char.name}: Type={type(char).__name__}, IsAlive={char.is_alive()}")
# Przetestuj polimorficzne wywołania metod
target = Character("Target", 10)
target.health = 1000 # Wysoki poziom zdrowia, aby przetrwać
for char in characters:
damage = char.attack(target)
print('Polymorphic behavior test completed')
elif test_case == "stress_test":
# Test obciążeniowy z wieloma obiektami
import time
start_time = time.time()
objects = []
for i in range(50):
try:
objects.append(Character(f'test_{i}'))
except:
pass # Obsłuż błędy tworzenia bez przerywania działania
try:
objects.append(Warrior(f'test_{i}'))
except:
pass # Obsłuż błędy tworzenia bez przerywania działania
try:
objects.append(Mage(f'test_{i}'))
except:
pass # Obsłuż błędy tworzenia bez przerywania działania
try:
objects.append(Rogue(f'test_{i}'))
except:
pass # Obsłuż błędy tworzenia bez przerywania działania
try:
objects.append(Ability(f'test_{i}', 10, 20))
except:
pass # Obsłuż błędy tworzenia bez przerywania działania
end_time = time.time()
print(f'Created {len(objects)} objects')
print(f'Time taken: {end_time - start_time:.4f} seconds')
print('Stress test completed')
elif test_case == "comprehensive_validation":
# Kompleksowy test poprawności
print('=== Comprehensive Validation Test ===')
# Test 1: Podstawowe tworzenie obiektów
print('1. Basic Object Creation:')
success_count = 0
classes = ['Character', 'Warrior', 'Mage', 'Rogue', 'Ability']
try:
obj = Character('test')
success_count += 1
print(f' Character: Created successfully')
except Exception as e:
print(f' Character: Creation failed - {e}')
try:
obj = Warrior('test')
success_count += 1
print(f' Warrior: Created successfully')
except Exception as e:
print(f' Warrior: Creation failed - {e}')
try:
obj = Mage('test')
success_count += 1
print(f' Mage: Created successfully')
except Exception as e:
print(f' Mage: Creation failed - {e}')
try:
obj = Rogue('test')
success_count += 1
print(f' Rogue: Created successfully')
except Exception as e:
print(f' Rogue: Creation failed - {e}')
try:
obj = Ability('test', 10, 20)
success_count += 1
print(f' Ability: Created successfully')
except Exception as e:
print(f' Ability: Creation failed - {e}')
print(f' Successfully created {success_count}/{len(classes)} classes')
print('=== Validation Complete ===')Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektyParametr selfMetodyAtrybutyMetoda konstruktora (__init__)Powtórzenie – prosty kalkulator4Dziedziczenie
Podstawy dziedziczeniaFunkcja super()Nadpisywanie metodDziedziczenie wielokrotneKolejność rozwiązywania metodPodsumowanie – hierarchia pracowników7Metody specjalne
Wprowadzenie do metod magicznychPrzeciążanie operatorówMagiczne metody kontenerówPowtórka – własna lista10Wzorce projektowe, część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec Strategy13Wyzwania końcowe
Platforma e-learningowaSystem bankowyTworzenie postaci do gryUsługa wynajmu pojazdów2Dekoratory
Wprowadzenie do dekoratorówDekorator propertyDekorator metody statycznejDekorator metody klasowej5Polimorfizm
Ponowne omówienie nadpisywania metodTypowanie kaczeKlasy i metody abstrakcyjneProjektowanie interfejsówPodsumowanie — kalkulator kształtów8Zaawansowane koncepcje programowania obiektowego
Kompozycja a dziedziczenieMiksyMetody statyczne i klasoweDekoratory klasMenedżery kontekstu11Wzorce projektowe, część 2
Wzorzec PolecenieWzorzec AdapterWzorzec DekoratorWzorzec Metoda szablonowaWzorzec StanWzorzec Kompozyt3Właściwości klas
Zmienne instancji a zmienne klasoweDekoratory właściwościAtrybuty prywatnePowtórzenie — menedżer kont bankowych6Hermetyzacja
Public, Protected, Private — pamięćModyfikatory dostępuUkrywanie informacjiDekoratory właściwości — zaawansowanePodsumowanie — system ewidencji uczniów12Projekt: System zarządzania biblioteką
Przegląd projektuKlasy Book i UserSystem wypożyczeńFunkcja wyszukiwaniaInterfejs administratoraTestowanie i integracjaPoćwicz samodzielnie: Kompilator Python online