Advertisement
GeorgiLukanov87

Python OOP Exam - 10 April 2022 - Medieval Games

Nov 16th, 2022 (edited)
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.68 KB | None | 0 0
  1. # Python OOP Exam - 10 April 2022 - Medieval Games
  2.  
  3. # https://judge.softuni.org/Contests/Practice/Index/3426#0
  4. =============================================================================================
  5.  
  6. # file name: supply.py
  7.  
  8. from abc import ABC, abstractmethod
  9.  
  10.  
  11. class Supply(ABC):
  12.     @abstractmethod
  13.     def __init__(self, name: str, energy: int):
  14.         self.name = name
  15.         self.energy = energy
  16.  
  17.     @property
  18.     def name(self):
  19.         return self.__name
  20.  
  21.     @name.setter
  22.     def name(self, value):
  23.         if value == '':
  24.             raise ValueError("Name cannot be an empty string.")
  25.         self.__name = value
  26.  
  27.     @property
  28.     def energy(self):
  29.         return self.__energy
  30.  
  31.     @energy.setter
  32.     def energy(self, value):
  33.         if value < 0:
  34.             raise ValueError("Energy cannot be less than zero.")
  35.         self.__energy = value
  36.  
  37.     def details(self):
  38.         return f"{self.__class__.__name__}: {self.name}, {self.energy}"
  39.    
  40. =============================================================================================
  41. # file name: drink.py
  42.  
  43. from project.supply.supply import Supply
  44.  
  45.  
  46. class Drink(Supply):
  47.     def __init__(self, name: str, energy=15):
  48.         super().__init__(name, energy)
  49.  
  50. =============================================================================================
  51. # file name: food.py
  52.  
  53. from project.supply.supply import Supply
  54.  
  55.  
  56. class Food(Supply):
  57.     def __init__(self, name: str, energy=25):
  58.         super().__init__(name, energy)
  59.  
  60. =============================================================================================
  61. # file name: player.py
  62.  
  63. class Player:
  64.     MAX_STAMINA = 100
  65.     MIN_STAMINA = 0
  66.     added_player_names = []
  67.  
  68.     def __init__(self, name: str, age: int, stamina=100):
  69.         self.name = name
  70.         self.age = age
  71.         self.stamina = stamina
  72.  
  73.     @property
  74.     def name(self):
  75.         return self.__name
  76.  
  77.     @name.setter
  78.     def name(self, value):
  79.         if value == '':
  80.             raise ValueError("Name not valid!")
  81.         elif value in Player.added_player_names:
  82.             raise Exception(f"Name {value} is already used!")
  83.         Player.added_player_names.append(value)
  84.         self.__name = value
  85.  
  86.     @property
  87.     def age(self):
  88.         return self.__age
  89.  
  90.     @age.setter
  91.     def age(self, value):
  92.         if value < 12:
  93.             raise ValueError("The player cannot be under 12 years old!")
  94.         self.__age = value
  95.  
  96.     @property
  97.     def stamina(self):
  98.         return self.__stamina
  99.  
  100.     @stamina.setter
  101.     def stamina(self, value):
  102.         if not 0 <= value <= 100:
  103.             raise ValueError("Stamina not valid!")
  104.         self.__stamina = value
  105.  
  106.     @property
  107.     def need_sustenance(self):
  108.         return self.stamina < 100
  109.  
  110.     def __str__(self):
  111.         return f"Player: {self.name}, {self.age}, {self.stamina}, {self.need_sustenance}"
  112.  
  113. =============================================================================================
  114. # file name: controller.py
  115.  
  116. from project.player import Player
  117. from project.supply.supply import Supply
  118.  
  119.  
  120. class Controller:
  121.     def __init__(self):
  122.         self.players = []
  123.         self.supplies = []
  124.  
  125.     def add_player(self, *players: Player):
  126.         added_players_names = []
  127.         for player_obj in players:
  128.             if player_obj not in self.players:
  129.                 self.players.append(player_obj)
  130.                 added_players_names.append(player_obj.name)
  131.         return f"Successfully added: {', '.join(added_players_names)}"
  132.  
  133.     def add_supply(self, *supplies: Supply):
  134.         for supply_obj in supplies:
  135.             self.supplies.append(supply_obj)
  136.  
  137.     def sustain(self, player_name: str, sustenance_type: str):
  138.         player = self.__find_player_by_name(player_name)
  139.         if player is None:
  140.             return
  141.         if not player.need_sustenance:
  142.             return f"{player_name} have enough stamina."
  143.         if sustenance_type not in ['Food', 'Drink']:
  144.             return
  145.  
  146.         last_supply = self.__find_last_supply_by_type(sustenance_type)
  147.         player.stamina = min(player.stamina + last_supply.energy, 100)
  148.         return f"{player_name} sustained successfully with {last_supply.name}."
  149.  
  150.     def __find_last_supply_by_type(self, supply_type_):
  151.         for index in range(len(self.supplies) - 1, -1, -1):
  152.             if type(self.supplies[index]).__name__ == supply_type_:
  153.                 return self.supplies.pop(index)
  154.         raise Exception(f"There are no {supply_type_.lower()} supplies left!")
  155.  
  156.     def __find_player_by_name(self, player_name_):
  157.         for player_obj in self.players:
  158.             if player_obj.name == player_name_:
  159.                 return player_obj
  160.  
  161.     def duel(self, first_player_name: str, second_player_name: str):
  162.         player1 = self.__find_player_by_name(first_player_name)
  163.         player2 = self.__find_player_by_name(second_player_name)
  164.  
  165.         result_if_both_stamina_is_0 = []
  166.         if player1.stamina <= 0 or player2.stamina <= 0:
  167.             if player1.stamina <= 0:
  168.                 result_if_both_stamina_is_0.append(f'Player {first_player_name} does not have enough stamina.')
  169.             if player2.stamina <= 0:
  170.                 result_if_both_stamina_is_0.append(f'Player {second_player_name} does not have enough stamina.')
  171.             return '\n'.join(result_if_both_stamina_is_0)
  172.  
  173.         lower_stamina_order = sorted([player1, player2], key=lambda x: x.stamina)
  174.         player1, player2 = lower_stamina_order[0], lower_stamina_order[1]
  175.  
  176.         player2.stamina = max(player2.stamina - player1.stamina / 2, 0)
  177.         if player2.stamina == 0:
  178.             return f'Winner: {player1.name}'
  179.  
  180.         player1.stamina = max(player1.stamina - player2.stamina / 2, 0)
  181.         if player1.stamina == 0:
  182.             return f'Winner: {player2.name}'
  183.  
  184.         higher_stamina_order = sorted([player1, player2], key=lambda x: -x.stamina)
  185.         return f"Winner: {higher_stamina_order[0].name}"
  186.  
  187.     def next_day(self):
  188.         for player_obj in self.players:
  189.             player_obj.stamina = max(player_obj.stamina - player_obj.age * 2, 0)
  190.  
  191.         for player_obj in self.players:
  192.  
  193.             give_food = self.__find_last_supply_by_type('Food')
  194.             player_obj.stamina = min(player_obj.stamina + give_food.energy, 100)
  195.  
  196.             give_drink = self.__find_last_supply_by_type('Drink')
  197.             player_obj.stamina = min(player_obj.stamina + give_drink.energy, 100)
  198.  
  199.     def __str__(self):
  200.         result = []
  201.         for player in self.players:
  202.             result.append(str(player))
  203.         for supply in self.supplies:
  204.             result.append(supply.details())
  205.  
  206.         return '\n'.join(result)
  207.  
  208.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement