Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add knights fighting solution #788

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[flake8]
inline-quotes = "
ignore = E203, E266, W503, ANN002, ANN003, ANN101, ANN102, ANN401, N807, N818
ignore = E203, E266, W503, ANN002, ANN003, ANN101, ANN102, ANN401, N807, N818, F401
max-line-length = 79
max-complexity = 18
select = B,C,E,F,W,T4,B9,ANN,Q0,N8,VNE
exclude = venv, tests

1 change: 1 addition & 0 deletions app/battle/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .battle import Battle
22 changes: 22 additions & 0 deletions app/battle/battle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from typing import Dict
from app.knight import Knight


class Battle:
def __init__(self) -> None:
pass

def fight(self, knight1: Knight, knight2: Knight) -> Dict[str, int]:
damage_to_knight1 = max(0, knight2.power - knight1.protection)
damage_to_knight2 = max(0, knight1.power - knight2.protection)

knight1.take_damage(damage_to_knight1)
knight2.take_damage(damage_to_knight2)

knight1.hp = max(knight1.hp, 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are directly modifying the hp attribute of the Knight class from outside of it. This is not a good practice as it breaks the encapsulation principle of OOP. The hp attribute should be private (i.e., _hp) and any modifications to it should be done through methods inside the Knight class. Consider creating a method in the Knight class that ensures the hp cannot fall below 0, and call this method instead of directly modifying the hp attribute here.

knight2.hp = max(knight2.hp, 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the previous comment, you should not directly modify the hp attribute of the Knight class from outside of it. Consider creating a method in the Knight class that ensures the hp cannot fall below 0, and call this method instead of directly modifying the hp attribute here.


return {
knight1.name: knight1.hp,
knight2.name: knight2.hp,
}
1 change: 1 addition & 0 deletions app/config/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .constants import KNIGHTS
37 changes: 37 additions & 0 deletions app/config/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
KNIGHTS = {
"lancelot": {
"name": "Lancelot",
"power": 40,
"hp": 90,
"armour": [
{"part": "helmet", "protection": 10},
{"part": "shield", "protection": 15},
],
"weapon": {"name": "Sword", "power": 30},
"potion": {"name": "Blessing", "effect": {"hp": 5, "power": 10}},
},
"mordred": {
"name": "Mordred",
"power": 45,
"hp": 100,
"armour": [{"part": "breastplate", "protection": 20}],
"weapon": {"name": "Axe", "power": 35},
"potion": None,
},
"arthur": {
"name": "Arthur",
"power": 50,
"hp": 80,
"armour": [],
"weapon": {"name": "Lance", "power": 40},
"potion": None,
},
"red_knight": {
"name": "Red Knight",
"power": 35,
"hp": 70,
"armour": [{"part": "breastplate", "protection": 25}],
"weapon": {"name": "Sword", "power": 45},
"potion": {"name": "Blessing", "effect": {"hp": 10, "power": 5}},
},
}
3 changes: 3 additions & 0 deletions app/entities/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .armour import Armour
from .weapon import Weapon
from .potion import Potion
4 changes: 4 additions & 0 deletions app/entities/armour.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Armour:
def __init__(self, part: str, protection: int) -> None:
self.part = part
self.protection = protection
4 changes: 4 additions & 0 deletions app/entities/potion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Potion:
def __init__(self, name: str, effect: dict) -> None:
self.name = name
self.effect = effect
4 changes: 4 additions & 0 deletions app/entities/weapon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Weapon:
def __init__(self, name: str, power: int) -> None:
self.name = name
self.power = power
2 changes: 2 additions & 0 deletions app/knight/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .knight import Knight
from .factory import create_knight
36 changes: 36 additions & 0 deletions app/knight/factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from app.entities import Armour, Weapon, Potion
from .knight import Knight


def create_armour(armour_data: list) -> list:
return [Armour(arm["part"], arm["protection"]) for arm in armour_data]


def create_weapon(weapon_data: dict) -> Weapon:
return Weapon(weapon_data["name"], weapon_data["power"])


def create_potion(potion_data: dict) -> Potion:
if potion_data is None:
return None
return Potion(potion_data["name"], potion_data["effect"])


def create_knight(knight_data: dict) -> Knight:
armour = create_armour(knight_data["armour"])
weapon = create_weapon(knight_data["weapon"])
potion = create_potion(knight_data.get("potion"))
return Knight(
name=knight_data["name"],
base_power=knight_data["power"],
hp=knight_data["hp"],
armour=armour,
weapon=weapon,
potion=potion,
)


def get_knights(knights_config: dict) -> list:
return [
create_knight(knight_data) for knight_data in knights_config.values()
]
47 changes: 47 additions & 0 deletions app/knight/knight.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from app.entities import Weapon, Potion


class Knight:
def __init__(
self,
name: str,
base_power: int,
hp: int,
armour: list,
weapon: Weapon,
potion: Potion = None,
) -> None:
self.name = name
self.base_power = base_power
self.hp = hp
self.armour = armour
self.weapon = weapon
self.potion = potion

self.power = self.calculate_power()
self.protection = self.calculate_protection()
self.hp = self.calculate_total_hp()

def calculate_power(self) -> int:
total_power = self.base_power + self.weapon.power
if self.potion and "power" in self.potion.effect:
total_power += self.potion.effect["power"]
return total_power

def calculate_protection(self) -> int:
total_protection = sum(arm.protection for arm in self.armour)
if self.potion and "protection" in self.potion.effect:
total_protection += self.potion.effect.get("protection", 0)
return total_protection

def calculate_total_hp(self) -> int:
total_hp = self.hp
if self.potion and "hp" in self.potion.effect:
total_hp += self.potion.effect["hp"]
return total_hp

def take_damage(self, damage: int) -> None:
self.hp = max(0, self.hp - damage)

def is_defeated(self) -> bool:
return self.hp == 0
Loading
Loading