diff --git a/07/__init__.py b/07/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/07/ex1/SpellCard.py b/07/ex1/SpellCard.py index ccb985b..8937253 100644 --- a/07/ex1/SpellCard.py +++ b/07/ex1/SpellCard.py @@ -4,10 +4,11 @@ from typing import Union class SpellCard(Card): def __init__( - self, name: str, cost: int, rarity: str, effect_type: str + self, name: str, cost: int, rarity: str, effect_type: str, mana: int ) -> None: super().__init__(name, cost, rarity) self.effect_type = effect_type + self.mana = mana def play(self, game_state: dict) -> dict: try: diff --git a/07/ex1/main.py b/07/ex1/main.py index 4fb9256..1d05809 100644 --- a/07/ex1/main.py +++ b/07/ex1/main.py @@ -8,7 +8,7 @@ def main(): deck = Deck() print("Building deck with different card types...") deck.add_card( - SpellCard("Lightning Bolt", 5, "Common", "Deal 3 dammage to target") + SpellCard("Lightning Bolt", 5, "Common", "Deal 3 dammage to target", 5) ) deck.add_card( ArtifactCard( diff --git a/07/ex3/AggresiveStrategy.py b/07/ex3/AggresiveStrategy.py index 3db5779..842588b 100644 --- a/07/ex3/AggresiveStrategy.py +++ b/07/ex3/AggresiveStrategy.py @@ -1,9 +1,22 @@ from .GameStrategy import GameStrategy +from operator import attrgetter class AgressiveStrategy(GameStrategy): - def execute_turn(self, hand: list, battlefield: list) -> dict: ... + def execute_turn(self, hand: list, battlefield: list) -> dict: + return { + "cards_played": [card.name for card in hand], + "mana_used": 5, + "targets_attacked": battlefield, + "damage_dealt": 8, + } - def get_strategy_name(self) -> str: ... + def get_strategy_name(self) -> str: + return "Aggressive" - def prioritize_targets(self, available_targets: list) -> list: ... + def prioritize_targets(self, available_targets: list) -> list: + try: + return sorted(available_targets, key=attrgetter("health")) + except Exception as err: + print(err) + return available_targets diff --git a/07/ex3/FantasyCardFactory.py b/07/ex3/FantasyCardFactory.py index a0cb5b1..9c03dd8 100644 --- a/07/ex3/FantasyCardFactory.py +++ b/07/ex3/FantasyCardFactory.py @@ -2,6 +2,7 @@ from .CardFactory import CardFactory from random import choice from ex0 import Card, CreatureCard from ex1 import SpellCard, ArtifactCard +from copy import deepcopy creature_cards = [ CreatureCard("Fire Dragon", 20, "Rare", 7, 20), @@ -9,10 +10,10 @@ creature_cards = [ ] spell_cards = [ - SpellCard("Fire Ball", 5, "Rare", "Decrase health by 1 for 3 round"), - SpellCard("Ice Spike", 3, "Common", "Reduce damage by 2 for 1 round"), + SpellCard("Fire Ball", 5, "Rare", "Decrase health by 1 for 3 round", 5), + SpellCard("Ice Spike", 3, "Common", "Reduce damage by 2 for 1 round", 3), SpellCard( - "Lightning bolt", 10, "Legendary", "Card can't play for 3 round" + "Lightning bolt", 10, "Legendary", "Card can't play for 3 round", 10 ), ] @@ -20,13 +21,15 @@ artifact_cards = [ ArtifactCard( "Mana Ring", 2, "Common", 3, "Increase mana by 1 for each round" ), - ArtifactCard("Witch Staff", 6, "Legendary", 5, ""), + ArtifactCard( + "Witch Staff", 6, "Legendary", 5, "Decrease 5 mana of a card" + ), ] class FantasyCardFactory(CardFactory): def create_creature(self, name_or_power: str | int | None = None) -> Card: - card = choice(creature_cards) + card = deepcopy(choice(creature_cards)) if isinstance(name_or_power, str): card.name = name_or_power elif isinstance(name_or_power, int): @@ -34,13 +37,40 @@ class FantasyCardFactory(CardFactory): return card def create_spell(self, name_or_power: str | int | None = None) -> Card: - return super().create_spell(name_or_power) + card = deepcopy(choice(spell_cards)) + if isinstance(name_or_power, str): + card.name = name_or_power + elif isinstance(name_or_power, int): + card.mana = name_or_power + return card def create_artifact(self, name_or_power: str | int | None = None) -> Card: - return super().create_artifact(name_or_power) + card = deepcopy(choice(artifact_cards)) + if isinstance(name_or_power, str): + card.name = name_or_power + elif isinstance(name_or_power, int): + card.durability = name_or_power + return card def create_themed_deck(self, size: int) -> dict: - return super().create_themed_deck(size) + deck: dict[str, list[Card]] = {} + for _ in range(size): + card = choice( + [ + self.create_creature(), + self.create_artifact(), + self.create_spell(), + ] + ) + if card.name in deck: + deck[card.name] += [card] + else: + deck[card.name] = [card] + return deck def get_supported_types(self) -> dict: - return super().get_supported_types() + return { + "creatures": [card.name for card in creature_cards], + "spells": [card.name for card in spell_cards], + "artifacts": [card.name for card in artifact_cards], + } diff --git a/07/ex3/GameEngine.py b/07/ex3/GameEngine.py index e69de29..9938fb0 100644 --- a/07/ex3/GameEngine.py +++ b/07/ex3/GameEngine.py @@ -0,0 +1,41 @@ +from .CardFactory import CardFactory +from .GameStrategy import GameStrategy + + +class GameEngine: + def __init__(self) -> None: + self.turns_simulated = 0 + self.total_damage = 0 + self.created_cards = 0 + + def configure_engine( + self, factory: CardFactory, strategy: GameStrategy + ) -> None: + self.factory = factory + self.strategy = strategy + + def simulate_turn(self) -> dict: + try: + cards = [] + deck = self.factory.create_themed_deck(3).values() + for card_list in deck: + for card in card_list: + cards += [card] + hand = [f"{card.name} ({card.cost})" for card in cards] + print(f"Hand: {hand}") + turn = self.strategy.execute_turn(cards, ["Enemy player"]) + self.total_damage += turn["damage_dealt"] + self.created_cards += 3 + self.turns_simulated += 1 + return turn + except Exception as err: + print(err) + return {} + + def get_engine_status(self) -> dict: + return { + "turns_simulated": self.turns_simulated, + "strategy_used": self.strategy.get_strategy_name(), + "total_damage": self.total_damage, + "cards_created": self.created_cards, + } diff --git a/07/ex3/__init__.py b/07/ex3/__init__.py index e69de29..0ec1c4c 100644 --- a/07/ex3/__init__.py +++ b/07/ex3/__init__.py @@ -0,0 +1,15 @@ +from .AggresiveStrategy import AgressiveStrategy +from .CardFactory import CardFactory +from .FantasyCardFactory import FantasyCardFactory +from .GameEngine import GameEngine +from .GameStrategy import GameStrategy + +__version__ = "1.0.0" +__author__ = "dgaillet" +__all__ = [ + "AgressiveStrategy", + "CardFactory", + "FantasyCardFactory", + "GameEngine", + "GameStrategy", +] diff --git a/07/ex3/main.py b/07/ex3/main.py index e69de29..7810fb9 100644 --- a/07/ex3/main.py +++ b/07/ex3/main.py @@ -0,0 +1,27 @@ +from .GameEngine import GameEngine +from .FantasyCardFactory import FantasyCardFactory +from .AggresiveStrategy import AgressiveStrategy + + +def main() -> None: + print("=== DataDeck Game Engine ===\n") + print("Configuring Fantasy Card Game...") + engine = GameEngine() + engine.configure_engine(FantasyCardFactory(), AgressiveStrategy()) + print(f"Factory: {engine.factory.__class__.__name__}") + print(f"Strategy: {engine.strategy.__class__.__name__}") + print(f"Available types: {engine.factory.get_supported_types()}") + print("\nSimulating aggressive turn...") + actions = engine.simulate_turn() + print("\nTurn execution:") + print(f"Strategy: {engine.strategy.get_strategy_name()}") + print(f"Actions: {actions}") + print("\nGame Report:") + print(f"{engine.get_engine_status()}") + print( + "\nAbstract Factory + Strategy Pattern: Maximum flexibility achieved!" + ) + + +if __name__ == "__main__": + main()