jako jo jo
This commit is contained in:
commit
7037378cbe
111
character.py
Normal file
111
character.py
Normal file
@ -0,0 +1,111 @@
|
||||
from weapon import *
|
||||
|
||||
class Character:
|
||||
"""
|
||||
Character reprezentuje postavu v RPG hre
|
||||
|
||||
@Author: zbyv
|
||||
@Date: 15.11.2023
|
||||
"""
|
||||
|
||||
HAND_LEFT = 0
|
||||
"""
|
||||
Leva ruka postavy
|
||||
"""
|
||||
|
||||
HAND_RIGHT = 1
|
||||
"""
|
||||
Prava ruka postavy
|
||||
"""
|
||||
|
||||
def __init__(self, name: str, strength: int, agility: int, vitality: int) -> None:
|
||||
"""
|
||||
Args:
|
||||
name: Nazev postavy
|
||||
strength: Utocna sila postavy
|
||||
agility: Hbitost postavy
|
||||
vitality: Zdravi postavi
|
||||
"""
|
||||
|
||||
self.__name: str = name
|
||||
self.__strength: int = strength
|
||||
self.__agility: int = agility
|
||||
self.__vitality: int = vitality
|
||||
self.__weapons: list[Weapon|None] = [None, None]
|
||||
|
||||
|
||||
def attack(self) -> int:
|
||||
"""
|
||||
Zjisti utocnou silu postavy
|
||||
|
||||
Returns:
|
||||
Utocna sila postavy
|
||||
"""
|
||||
|
||||
ret = self.__strength
|
||||
|
||||
for weapon in self.__weapons:
|
||||
if weapon:
|
||||
ret += weapon.attack
|
||||
|
||||
return ret
|
||||
|
||||
def __defense(self) -> int:
|
||||
defense = self.__agility
|
||||
|
||||
for weapon in self.__weapons:
|
||||
if weapon:
|
||||
defense += weapon.defense
|
||||
|
||||
return defense
|
||||
|
||||
def defend(self, attack: int) -> int:
|
||||
"""
|
||||
Vystavi postavu utoku
|
||||
|
||||
Args:
|
||||
attack: Utocna sila nepritele
|
||||
|
||||
Returns:
|
||||
Zdravi ztracene pri utoku
|
||||
"""
|
||||
|
||||
loss = attack - self.__defense()
|
||||
|
||||
if loss < 0:
|
||||
return 0
|
||||
|
||||
loss = min(self.__vitality, loss)
|
||||
self.__vitality -= loss
|
||||
return loss
|
||||
|
||||
def is_alive(self) -> bool:
|
||||
"""
|
||||
Zjisti, jestli je postava nazivu
|
||||
|
||||
Returns:
|
||||
True pokud (zdravi > 0), jinak False
|
||||
"""
|
||||
|
||||
return self.__vitality > 0
|
||||
|
||||
def take_weapon(self, weapon: Weapon|None, hand: int) -> bool:
|
||||
"""
|
||||
Vlozi postave do ruky zbran, pokud v teto ruce doposud zadnou zbran nema
|
||||
|
||||
Args:
|
||||
weapon: Zbran, ktera bude vlozena postave do ruky
|
||||
hand: Ruka, do ktere postave bude zbran vlozena
|
||||
|
||||
Returns:
|
||||
True pokud si postava zbran vzala, jinak False
|
||||
"""
|
||||
|
||||
if not self.__weapons[hand]:
|
||||
self.__weapons[hand] = weapon
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.__name} [{self.__vitality}] ({self.attack()}/{self.__defense()})"
|
||||
98
rpg.py
Normal file
98
rpg.py
Normal file
@ -0,0 +1,98 @@
|
||||
from character import *
|
||||
|
||||
class RPG:
|
||||
"""
|
||||
Hlavni trida RPG hry
|
||||
|
||||
@Author: zbyv
|
||||
@Date: 15.11.2023
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
|
||||
def input_character(self) -> Character:
|
||||
"""
|
||||
Vytvori postavu na zaklade udaju nactenych ze standartniho vstupu
|
||||
|
||||
Returns:
|
||||
vytvorena postava
|
||||
"""
|
||||
|
||||
return Character(input("Jmeno postavy: "), int(input("Sila: ")), int(input("Hbitost: ")), int(input("Zdravi: ")))
|
||||
|
||||
def input_weapon(self) -> Weapon|None:
|
||||
"""
|
||||
Vytvori zbran na zaklade udaju nactenych ze standartniho vstupu
|
||||
|
||||
Returns:
|
||||
vytvorena zbran, nebo None, pokud byl nazev zbrane prazdny
|
||||
"""
|
||||
|
||||
name = input("Nazev zbrane: ")
|
||||
if name == "":
|
||||
return None
|
||||
|
||||
return Weapon(name, int(input("Utok: ")), int(input("Obrana: ")))
|
||||
|
||||
def equip_character(self, character: Character, left: Weapon|None, right: Weapon|None) -> None:
|
||||
"""
|
||||
Vyzbroji postavu zadanymi zbranemi, avsak stavajici zbrane nebudou nahrazeny.
|
||||
|
||||
Args:
|
||||
character: Postava pro vyzbrojeni
|
||||
left: Zbran do leve ruky
|
||||
right: Zbran do prave ruky
|
||||
"""
|
||||
|
||||
character.take_weapon(left, Character.HAND_LEFT)
|
||||
character.take_weapon(right, Character.HAND_RIGHT)
|
||||
|
||||
@staticmethod
|
||||
def __process_attack(attacker: Character, defender: Character) -> bool:
|
||||
dmg = defender.defend(attacker.attack())
|
||||
print(f"utoci {attacker} a dava {dmg} zraneni")
|
||||
return not defender.is_alive()
|
||||
|
||||
|
||||
def fight(self, character1: Character, character2: Character) -> Character:
|
||||
"""
|
||||
Spusti souboj mezi postavami
|
||||
|
||||
Args:
|
||||
character1: postava souboje, ktera utoci jako prvni
|
||||
character2: postava souboje, ktera brani jako prvni
|
||||
|
||||
Returns:
|
||||
postava, ktera souboj vyhrala
|
||||
"""
|
||||
|
||||
|
||||
while True:
|
||||
if RPG.__process_attack(character1, character2):
|
||||
return character1
|
||||
|
||||
if RPG.__process_attack(character2, character1):
|
||||
return character2
|
||||
|
||||
def run(self) -> None:
|
||||
"""
|
||||
Spusti hru
|
||||
"""
|
||||
|
||||
character1 = self.input_character()
|
||||
self.equip_character(character1, self.input_weapon(), self.input_weapon())
|
||||
|
||||
character2 = self.input_character()
|
||||
self.equip_character(character2, self.input_weapon(), self.input_weapon())
|
||||
|
||||
winner = self.fight(character1, character2)
|
||||
|
||||
print(f"Vitez: {winner}")
|
||||
|
||||
def main() -> None:
|
||||
rpg = RPG()
|
||||
rpg.run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
90
tests/character_test.py
Normal file
90
tests/character_test.py
Normal file
@ -0,0 +1,90 @@
|
||||
import random
|
||||
import unittest
|
||||
from character import Character
|
||||
from weapon import Weapon
|
||||
|
||||
class CharacterTest(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
self.strength = random.randrange(1,50)
|
||||
self.attackL = random.randrange(1,50)
|
||||
self.attackR = random.randrange(1,50)
|
||||
self.agility = random.randrange(1,50)
|
||||
self.defenseL = random.randrange(1,50)
|
||||
self.defenseR = random.randrange(1,50)
|
||||
self.vitality = random.randrange(1,50)
|
||||
|
||||
def assertCharacter(self, char:Character, name:str, vitality:int, attack:int, defense:int, msg:str):
|
||||
text = f"{name} [{vitality}] ({attack}/{defense})"
|
||||
self.assertEqual(text, char.__str__(), msg)
|
||||
|
||||
def test_init(self):
|
||||
name = "Postava"
|
||||
text = f"{name} [{self.vitality}] ({self.strength}/{self.agility})"
|
||||
char = Character(name,self.strength,self.agility,self.vitality)
|
||||
self.assertCharacter(char, name, self.vitality, self.strength, self.agility,"|Postava o sobe nepodava spravne informace.")
|
||||
|
||||
|
||||
def test_take_weapon(self):
|
||||
name = "vezmiZbran"
|
||||
left = Weapon("LEVA", self.attackL, self.defenseL)
|
||||
right = Weapon("PRAVA", self.attackR, self.defenseR)
|
||||
char = Character(name, self.strength, self.agility, self.vitality)
|
||||
|
||||
self.assertTrue(char.take_weapon(left,Character.HAND_LEFT),"|Postava tvrdi, ze si nemuze vzit zbran do prazdne leve ruky")
|
||||
self.assertCharacter(char,name,self.vitality,self.strength + self.attackL, self.agility + self.defenseL, "|Postava o sobe nepodava spravne informace")
|
||||
|
||||
self.assertFalse(char.take_weapon(left,Character.HAND_LEFT),"|Postava tvrdi, ze si muze vzit zbran do plne leve ruky")
|
||||
self.assertCharacter(char,name,self.vitality,self.strength + self.attackL, self.agility + self.defenseL, "|Postava o sobe nepodava spravne informace")
|
||||
|
||||
self.assertTrue(char.take_weapon(right,Character.HAND_RIGHT),"|Postava tvrdi, ze si nemuze vzit zbran do prazdne prave ruky")
|
||||
self.assertCharacter(char,name,self.vitality,self.strength + self.attackR + self.attackL, self.agility + self.defenseR + self.defenseL, "|Postava o sobe nepodava spravne informace")
|
||||
|
||||
char = Character(name, self.strength, self.agility, self.vitality)
|
||||
|
||||
self.assertTrue(char.take_weapon(right,Character.HAND_RIGHT),"|Postava tvrdi, ze si nemuze vzit zbran do prazdne prave ruky")
|
||||
self.assertCharacter(char,name,self.vitality,self.strength + self.attackR, self.agility + self.defenseR, "|Postava o sobe nepodava spravne informace")
|
||||
|
||||
self.assertFalse(char.take_weapon(right,Character.HAND_RIGHT),"|Postava tvrdi, ze si muze vzit zbran do plne prave ruky")
|
||||
self.assertTrue(char.take_weapon(left,Character.HAND_LEFT), "|Postava tvrdi, ze si nemuze vzit zbran do prazdne leve ruky")
|
||||
|
||||
def test_defend(self):
|
||||
name = "branSe"
|
||||
attack = random.randint(1,10)
|
||||
|
||||
left = Weapon("LEVA", 0, self.defenseL)
|
||||
right = Weapon("PRAVA", 0, self.defenseR)
|
||||
|
||||
char = Character(name, 0, self.agility, self.vitality)
|
||||
char.take_weapon(left,Character.HAND_LEFT)
|
||||
char.take_weapon(right, Character.HAND_RIGHT)
|
||||
|
||||
self.assertTrue(0==char.defend(self.agility+self.defenseL+self.defenseR-1), "|Postava tvrdi, ze utrpela zraneni, i kdyz je utok mensi nez obrana")
|
||||
self.assertCharacter(char, name, self.vitality,0,self.agility+self.defenseL+self.defenseR,"|Postava o sobe nepodava spravne informace")
|
||||
|
||||
self.assertTrue(0==char.defend(self.agility+self.defenseL+self.defenseR), "|Postava tvrdi, ze utrpela zraneni, i kdyz je utok mensi nez obrana")
|
||||
self.assertCharacter(char, name, self.vitality,0,self.agility+self.defenseL+self.defenseR,"|Postava o sobe nepodava spravne informace")
|
||||
|
||||
self.assertTrue(attack==char.defend(self.agility+self.defenseL+self.defenseR+attack), "|Postava tvrdi, ze utrpela jine zraneni, nez mela")
|
||||
self.assertCharacter(char, name, self.vitality-attack,0,self.agility+self.defenseL+self.defenseR,"|Postava o sobe nepodava spravne informace")
|
||||
|
||||
def test_attack(self):
|
||||
name = "zautoc"
|
||||
left = Weapon("LEVA", self.attackL, 0)
|
||||
right = Weapon("PRAVA", self.attackR, 0)
|
||||
|
||||
char = Character(name, self.strength, 0, self.vitality)
|
||||
char.take_weapon(left,Character.HAND_LEFT)
|
||||
char.take_weapon(right, Character.HAND_RIGHT)
|
||||
|
||||
self.assertTrue(self.strength + self.attackL + self.attackR == char.attack(), "|Postava tvrdi, ze utoci jinou silou, nez jaky je jeji utok.")
|
||||
self.assertCharacter(char, name, self.vitality, self.strength + self.attackL + self.attackR, 0, "|Postava o sobe nepodava spravne informace")
|
||||
|
||||
def test_is_alive(self):
|
||||
name = "jeZiva"
|
||||
|
||||
char = Character(name, 0,0,self.vitality)
|
||||
self.assertTrue(char.is_alive(), "|Postava zemrela pri narozeni")
|
||||
|
||||
char.defend(self.vitality)
|
||||
self.assertFalse(char.is_alive(), "|Postava nezemrela pri brutalnim utoku")
|
||||
118
tests/rpg_test.py
Normal file
118
tests/rpg_test.py
Normal file
@ -0,0 +1,118 @@
|
||||
import random
|
||||
import unittest
|
||||
import builtins
|
||||
import typing
|
||||
from typing import Any
|
||||
from character import Character
|
||||
from weapon import Weapon
|
||||
from rpg import RPG
|
||||
|
||||
class RPGTest(unittest.TestCase):
|
||||
|
||||
class InputShim:
|
||||
"""
|
||||
Třída pro nahrazení standardní funkce input pro vstup dat
|
||||
"""
|
||||
__idx:int = 0
|
||||
__lines:list[str] = []
|
||||
|
||||
@staticmethod
|
||||
def set_input_data(lines:list[str]):
|
||||
RPGTest.InputShim.__idx = 0
|
||||
RPGTest.InputShim.__lines = lines
|
||||
builtins.input = typing.cast(Any, RPGTest.InputShim.__next)
|
||||
|
||||
@staticmethod
|
||||
def get_latest_input() -> str|None:
|
||||
if RPGTest.InputShim.__idx==0:
|
||||
return None
|
||||
else:
|
||||
return RPGTest.InputShim.__lines[RPGTest.InputShim.__idx-1]
|
||||
|
||||
@staticmethod
|
||||
def __next(prompt:str=""):
|
||||
assert RPGTest.InputShim.__idx<len(RPGTest.InputShim.__lines), "| nejsou zadany dalsi hodnoty na vstupu"
|
||||
result = RPGTest.InputShim.__lines[RPGTest.InputShim.__idx] # + "\n"
|
||||
RPGTest.InputShim.__idx += 1
|
||||
return result
|
||||
"""
|
||||
class PrintShim:
|
||||
|
||||
@staticmethod
|
||||
def set_output_data():
|
||||
builtins.print =
|
||||
|
||||
"""
|
||||
|
||||
def assertCharacter(self, char:Character, name:str, vitality:int, attack:int, defense:int, msg:str):
|
||||
text = f"{name} [{vitality}] ({attack}/{defense})"
|
||||
self.assertEqual(text, char.__str__(), msg)
|
||||
|
||||
def assertWeapon(self, weapon:Weapon, name:str, attack:int, defense: int, msg:str):
|
||||
text = f"{name} [{attack}/{defense}]"
|
||||
self.assertEqual(text, weapon.__str__(), msg)
|
||||
|
||||
|
||||
def test_input_character(self):
|
||||
strength = random.randrange(1,50)
|
||||
agility = random.randrange(1,50)
|
||||
vitality = random.randrange(1,50)
|
||||
name = "nactiPostavu"
|
||||
RPGTest.InputShim.set_input_data([name,strength,agility,vitality])
|
||||
rpg = RPG()
|
||||
char = rpg.input_character()
|
||||
self.assertCharacter(char, name, vitality, strength, agility, "|Nactena postava tvrdi, ze ma jine vlastnosti, nez by mela mit.")
|
||||
|
||||
def test_input_weapon(self):
|
||||
defense = random.randrange(1,50)
|
||||
attack = random.randrange(1,50)
|
||||
name = "nactiZbran"
|
||||
RPGTest.InputShim.set_input_data([name,attack,defense])
|
||||
rpg = RPG()
|
||||
weapon = rpg.input_weapon()
|
||||
self.assertWeapon(weapon,name,attack,defense,"|Nactena zbran tvrdi, ze ma jine vlastnosti, nez by mela mit.")
|
||||
|
||||
RPGTest.InputShim.set_input_data([""])
|
||||
rpg = RPG()
|
||||
weapon = rpg.input_weapon()
|
||||
self.assertIsNone(weapon, "|Nemela se nacist zadna zbran")
|
||||
|
||||
def test_equip_character(self):
|
||||
strength = random.randrange(1,50)
|
||||
attackL = random.randrange(1,50)
|
||||
attackR = random.randrange(1,50)
|
||||
agility = random.randrange(1,50)
|
||||
defenseL = random.randrange(1,50)
|
||||
defenseR = random.randrange(1,50)
|
||||
vitality = random.randrange(1,50)
|
||||
name = "vyzbrojPostavu"
|
||||
char = Character(name,strength,agility,vitality)
|
||||
left = Weapon("leva",attackL,defenseL)
|
||||
right = Weapon("prava",attackR,defenseR)
|
||||
|
||||
rpg = RPG()
|
||||
rpg.equip_character(char,None,right)
|
||||
self.assertCharacter(char,name,vitality,strength+attackR, agility + defenseR,"|Vyzbrojeni postavy se nepovedlo, cekal jsem jiny utok.")
|
||||
|
||||
rpg.equip_character(char,left,None)
|
||||
self.assertCharacter(char,name,vitality,strength+attackR+attackL, agility + defenseR+defenseL,"|Vyzbrojeni postavy se nepovedlo, cekal jsem jiny utok.")
|
||||
|
||||
def test_fight(self):
|
||||
char1=Character("Golias",3,0,10)
|
||||
char2=Character("David",1,1,20)
|
||||
c1s = char1.__str__()
|
||||
c2s = char2.__str__()
|
||||
|
||||
rpg = RPG()
|
||||
winner = rpg.fight(char1, char2)
|
||||
self.assertEqual(winner, char1, f"|{c1s} zautocil na {c2s} a mel vyhrat")
|
||||
|
||||
char1=Character("Golias",3,0,10)
|
||||
char2=Character("David",1,1,20)
|
||||
c1s = char1.__str__()
|
||||
c2s = char2.__str__()
|
||||
|
||||
rpg = RPG()
|
||||
winner = rpg.fight(char2, char1)
|
||||
self.assertEqual(winner, char2, f"|{c2s} zautocil na {c1s} a mel vyhrat")
|
||||
|
||||
17
tests/weapon_test.py
Normal file
17
tests/weapon_test.py
Normal file
@ -0,0 +1,17 @@
|
||||
import random
|
||||
import unittest
|
||||
from weapon import Weapon
|
||||
|
||||
class WeaponTest(unittest.TestCase):
|
||||
def assertWeapon(self, weapon:Weapon, name:str, attack:int, defense: int, msg:str):
|
||||
text = f"{name} [{attack}/{defense}]"
|
||||
self.assertEqual(text, weapon.__str__(), msg)
|
||||
|
||||
def test_weapon(self):
|
||||
attack = random.randrange(100)
|
||||
defense = random.randrange(100)
|
||||
weapon = Weapon("Zbran", attack, defense)
|
||||
self.assertEqual(defense, weapon.defense, "|Vytvorena zbran ma jinou obranu, nez s jakou byla vytvorena.")
|
||||
self.assertEqual(attack, weapon.attack, "|Vytvorena zbran ma jiny utok, nez s jakym byla vytvorena.")
|
||||
self.assertWeapon(weapon,"Zbran",attack,defense, "|Vytvorena zbran se lisi od zadani")
|
||||
|
||||
36
weapon.py
Normal file
36
weapon.py
Normal file
@ -0,0 +1,36 @@
|
||||
class Weapon:
|
||||
"""
|
||||
Weapon reprezentuje zbran, kterou muze Character drzet ve svych rukou
|
||||
|
||||
@Author: zbyv
|
||||
@Date: 15.11.2023
|
||||
"""
|
||||
|
||||
def __init__(self, name: str, attack: int, defense: int) -> None:
|
||||
"""
|
||||
Args:
|
||||
name: Nazev zbrane
|
||||
attack: Utocna sila zbrane
|
||||
defense: Obranna sila zbrane
|
||||
"""
|
||||
self.__name = name
|
||||
self.__attack = attack
|
||||
self.__defense = defense
|
||||
|
||||
@property
|
||||
def attack(self) -> int:
|
||||
"""
|
||||
Utocna sila zbrane
|
||||
"""
|
||||
return self.__attack
|
||||
|
||||
@property
|
||||
def defense(self) -> int:
|
||||
"""
|
||||
Obranna sila zbrane
|
||||
"""
|
||||
return self.__defense
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.__name} [{self.__attack}/{self.__defense}]"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user