-
Thomas Röck authoredThomas Röck authored
plant.py 2.85 KiB
import random
from abc import ABC, abstractmethod
from copy import copy
from exceptions import DeadPlantError, NoMoreFruitsError
from fruit import Fruit
from root import Root
class Plant(ABC):
def __init__(self, species: str, growth_factor: float):
self.species = species
self.growth_factor = growth_factor
self._size = 1
self.dead = False
def __repr__(self):
return f"{self.species}"
def __str__(self):
return f"{self.species} of size {self.size:.1f}"
@property
def growth_factor(self):
return self._growth_factor
@growth_factor.setter
def growth_factor(self, growth_factor: float):
if growth_factor <= 1:
raise ValueError(f"Invalid growth_factor: {growth_factor} (>1 required)")
self._growth_factor = growth_factor
@property
def size(self):
return self._size
def grow(self) -> None:
if self.dead:
raise DeadPlantError("{self} is dead, it can't grow")
self._size *= self.growth_factor
@abstractmethod
def harvest(self) -> list:
raise NotImplementedError
class FruitBearingPlant(Plant):
def __init__(self, species: str, growth_factor: float, fruit_template: Fruit):
super().__init__(species, growth_factor)
self.fruit_template = fruit_template
self._fruits = []
def __str__(self):
return f"{self.species} of size {self.size:.1f} with {len(self.fruits)} fruits"
@property
def fruits(self):
return self._fruits
@fruits.deleter
def fruits(self):
self._fruits.clear()
def grow(self) -> None:
super().grow()
if random.randrange(100) < self.size:
self.fruits.append(copy(self.fruit_template))
def pick(self) -> Fruit:
if not self.fruits:
raise NoMoreFruitsError(f"{self} is empty, you can't pick any more fruits :(")
return self.fruits.pop()
def harvest(self) -> list:
harvested = []
while True:
try:
harvested.append(self.pick())
except NoMoreFruitsError:
return harvested
class RootVegetable(Plant):
def __init__(self,
species: str,
growth_factor: float,
calories_per_root_length: int,
plant_size_to_root_length_factor: float):
super().__init__(species, growth_factor)
self._root = Root(self.species, calories_per_root_length)
self._plant_size_to_root_length_factor = plant_size_to_root_length_factor
def grow(self):
super().grow()
self._root.length = self._size * self._plant_size_to_root_length_factor
def harvest(self) -> list:
self.dead = True
if self._root is None:
return []
harvested = [self._root]
self._root = None
return harvested