Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Python OOP Exam - 10 April 2022 - Medieval Games
- # https://judge.softuni.org/Contests/Practice/Index/3426#0
- =============================================================================================
- # file name: supply.py
- from abc import ABC, abstractmethod
- class Supply(ABC):
- @abstractmethod
- def __init__(self, name: str, energy: int):
- self.name = name
- self.energy = energy
- @property
- def name(self):
- return self.__name
- @name.setter
- def name(self, value):
- if value == '':
- raise ValueError("Name cannot be an empty string.")
- self.__name = value
- @property
- def energy(self):
- return self.__energy
- @energy.setter
- def energy(self, value):
- if value < 0:
- raise ValueError("Energy cannot be less than zero.")
- self.__energy = value
- def details(self):
- return f"{self.__class__.__name__}: {self.name}, {self.energy}"
- =============================================================================================
- # file name: drink.py
- from project.supply.supply import Supply
- class Drink(Supply):
- def __init__(self, name: str, energy=15):
- super().__init__(name, energy)
- =============================================================================================
- # file name: food.py
- from project.supply.supply import Supply
- class Food(Supply):
- def __init__(self, name: str, energy=25):
- super().__init__(name, energy)
- =============================================================================================
- # file name: player.py
- class Player:
- MAX_STAMINA = 100
- MIN_STAMINA = 0
- added_player_names = []
- def __init__(self, name: str, age: int, stamina=100):
- self.name = name
- self.age = age
- self.stamina = stamina
- @property
- def name(self):
- return self.__name
- @name.setter
- def name(self, value):
- if value == '':
- raise ValueError("Name not valid!")
- elif value in Player.added_player_names:
- raise Exception(f"Name {value} is already used!")
- Player.added_player_names.append(value)
- self.__name = value
- @property
- def age(self):
- return self.__age
- @age.setter
- def age(self, value):
- if value < 12:
- raise ValueError("The player cannot be under 12 years old!")
- self.__age = value
- @property
- def stamina(self):
- return self.__stamina
- @stamina.setter
- def stamina(self, value):
- if not 0 <= value <= 100:
- raise ValueError("Stamina not valid!")
- self.__stamina = value
- @property
- def need_sustenance(self):
- return self.stamina < 100
- def __str__(self):
- return f"Player: {self.name}, {self.age}, {self.stamina}, {self.need_sustenance}"
- =============================================================================================
- # file name: controller.py
- from project.player import Player
- from project.supply.supply import Supply
- class Controller:
- def __init__(self):
- self.players = []
- self.supplies = []
- def add_player(self, *players: Player):
- added_players_names = []
- for player_obj in players:
- if player_obj not in self.players:
- self.players.append(player_obj)
- added_players_names.append(player_obj.name)
- return f"Successfully added: {', '.join(added_players_names)}"
- def add_supply(self, *supplies: Supply):
- for supply_obj in supplies:
- self.supplies.append(supply_obj)
- def sustain(self, player_name: str, sustenance_type: str):
- player = self.__find_player_by_name(player_name)
- if player is None:
- return
- if not player.need_sustenance:
- return f"{player_name} have enough stamina."
- if sustenance_type not in ['Food', 'Drink']:
- return
- last_supply = self.__find_last_supply_by_type(sustenance_type)
- player.stamina = min(player.stamina + last_supply.energy, 100)
- return f"{player_name} sustained successfully with {last_supply.name}."
- def __find_last_supply_by_type(self, supply_type_):
- for index in range(len(self.supplies) - 1, -1, -1):
- if type(self.supplies[index]).__name__ == supply_type_:
- return self.supplies.pop(index)
- raise Exception(f"There are no {supply_type_.lower()} supplies left!")
- def __find_player_by_name(self, player_name_):
- for player_obj in self.players:
- if player_obj.name == player_name_:
- return player_obj
- def duel(self, first_player_name: str, second_player_name: str):
- player1 = self.__find_player_by_name(first_player_name)
- player2 = self.__find_player_by_name(second_player_name)
- result_if_both_stamina_is_0 = []
- if player1.stamina <= 0 or player2.stamina <= 0:
- if player1.stamina <= 0:
- result_if_both_stamina_is_0.append(f'Player {first_player_name} does not have enough stamina.')
- if player2.stamina <= 0:
- result_if_both_stamina_is_0.append(f'Player {second_player_name} does not have enough stamina.')
- return '\n'.join(result_if_both_stamina_is_0)
- lower_stamina_order = sorted([player1, player2], key=lambda x: x.stamina)
- player1, player2 = lower_stamina_order[0], lower_stamina_order[1]
- player2.stamina = max(player2.stamina - player1.stamina / 2, 0)
- if player2.stamina == 0:
- return f'Winner: {player1.name}'
- player1.stamina = max(player1.stamina - player2.stamina / 2, 0)
- if player1.stamina == 0:
- return f'Winner: {player2.name}'
- higher_stamina_order = sorted([player1, player2], key=lambda x: -x.stamina)
- return f"Winner: {higher_stamina_order[0].name}"
- def next_day(self):
- for player_obj in self.players:
- player_obj.stamina = max(player_obj.stamina - player_obj.age * 2, 0)
- for player_obj in self.players:
- give_food = self.__find_last_supply_by_type('Food')
- player_obj.stamina = min(player_obj.stamina + give_food.energy, 100)
- give_drink = self.__find_last_supply_by_type('Drink')
- player_obj.stamina = min(player_obj.stamina + give_drink.energy, 100)
- def __str__(self):
- result = []
- for player in self.players:
- result.append(str(player))
- for supply in self.supplies:
- result.append(supply.details())
- return '\n'.join(result)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement