<commit_before># -*- coding: utf-8 -*-
"""
.. module:: deck
    :synopsis: Encapsulates the behavior of card collections
.. moduleauthor:: <NAME> <<EMAIL>>
"""

from random import shuffle
from typing import List
from .cards import Card
from .cardrepo import CardRepo
from .exceptions import (
    RealmsException,
    MainDeckEmpty,
    PlayerDeckEmpty,
    PlayerDeckInitSize,
    PlayerDeckInitContents
)

CardList = List[Card]


class Hand(object):
    """
    The player's hand of cards

    Contains a collection of cards, each of which provides one or more effects.
    Some cards may be bases, and thus will not be discarded after being played.

    :param cards: Cards drawn by the player
    :type cards: [Card]
    :param existing_bases: Bases that were played previously and have not been destroyed
    :type existing_bases: [Card]

    .. note:: INCOMPLETE
    """
    def __init__(self, cards, existing_bases):
        self._cards = cards
        self._existing_bases = existing_bases
        self._effects = self._aggregate_effects(self._cards + self._existing_bases)
        return

    def _aggregate_effects(self, cards):
        """
        Returns a list of effects provided by a list of cards

        Examines each card and extracts the relevant effects that it provides.
        Ally abilities are extracted if allies exist in the hand of cards.

        :param cards: The cards whose effects will be aggregated
        :type cards: [Card]
        :return A list of effects provided by the cards
        :rtype [CardEffect]
        """
        pass

    def _factions_with_allies(self, cards):
        """
        Returns a list of factions that appear more than once in the hand

        :param cards: The cards to check for allies
        :type cards: [Card]
        :return A list of factions with allies present in the hand
        :rtype [Faction]
        """
        pass

    def _scrap(self, card):
        """
        Permanently removes a card from the player's deck

        :param card: The card to permanently remove
        :type card: Card
        """
        pass


class PlayerDeck(object):
    """
    Records the state of the player's deck

    At any given point in time the player may have three piles of cards: undrawn cards, a
    hand of cards, and a pile of used (discarded) cards. PlayerDeck records which cards are
    in which pile, provides an interface from which a hand of cards can be assembled, and
    shuffles the deck when necessary.

    Parameters
    ----------
    player_cards : List[Card]
        The list of cards from which the player's starting deck will be constructed

    Raises
    ------
    PlayerDeckInitSize
        Raised when constructing the deck with the wrong number of cards
    PlayerDeckInitContents
        Raised when constructing the deck with cards other than Vipers and Scouts
    """

    starting_size = 10

    def __init__(self, player_cards: CardList):
        try:
            self._validate_deck_size(player_cards)
            self._validate_deck_contents(player_cards)
        except RealmsException:
            raise
        self._undrawn: CardList = player_cards
        shuffle(self._undrawn)
        self._discards: CardList = []

    @staticmethod
    def _validate_deck_size(cards: CardList) -> None:
        """Ensures that the starting deck contains the correct
        number of cards

        Parameters
        ----------
        cards : CardList
            The tentative starting deck

        Raises
        ------
        PlayerDeckInitSize
            Raised if the tentative starting deck is not the correct size
        """
        if len(cards) != PlayerDeck.starting_size:
            raise PlayerDeckInitSize(len(cards))
        return<commit_msg>(doc) PlayerDeck - clarified that cards are shuffled in place<commit_after># -*- coding: utf-8 -*-
"""
.. module:: deck
    :synopsis: Encapsulates the behavior of card collections
.. moduleauthor:: <NAME> <<EMAIL>>
"""

from random import shuffle
from typing import List
from .cards import Card
from .cardrepo import CardRepo
from .exceptions import (
    RealmsException,
    MainDeckEmpty,
    PlayerDeckEmpty,
    PlayerDeckInitSize,
    PlayerDeckInitContents
)

CardList = List[Card]


class Hand(object):
    """
    The player's hand of cards

    Contains a collection of cards, each of which provides one or more effects.
    Some cards may be bases, and thus will not be discarded after being played.

    :param cards: Cards drawn by the player
    :type cards: [Card]
    :param existing_bases: Bases that were played previously and have not been destroyed
    :type existing_bases: [Card]

    .. note:: INCOMPLETE
    """
    def __init__(self, cards, existing_bases):
        self._cards = cards
        self._existing_bases = existing_bases
        self._effects = self._aggregate_effects(self._cards + self._existing_bases)
        return

    def _aggregate_effects(self, cards):
        """
        Returns a list of effects provided by a list of cards

        Examines each card and extracts the relevant effects that it provides.
        Ally abilities are extracted if allies exist in the hand of cards.

        :param cards: The cards whose effects will be aggregated
        :type cards: [Card]
        :return A list of effects provided by the cards
        :rtype [CardEffect]
        """
        pass

    def _factions_with_allies(self, cards):
        """
        Returns a list of factions that appear more than once in the hand

        :param cards: The cards to check for allies
        :type cards: [Card]
        :return A list of factions with allies present in the hand
        :rtype [Faction]
        """
        pass

    def _scrap(self, card):
        """
        Permanently removes a card from the player's deck

        :param card: The card to permanently remove
        :type card: Card
        """
        pass


class PlayerDeck(object):
    """
    Records the state of the player's deck

    At any given point in time the player may have three piles of cards: undrawn cards, a
    hand of cards, and a pile of used (discarded) cards. PlayerDeck records which cards are
    in which pile, provides an interface from which a hand of cards can be assembled, and
    shuffles the deck when necessary.

    Parameters
    ----------
    player_cards : List[Card]
        The list of cards from which the player's starting deck will be constructed

    Raises
    ------
    PlayerDeckInitSize
        Raised when constructing the deck with the wrong number of cards
    PlayerDeckInitContents
        Raised when constructing the deck with cards other than Vipers and Scouts
    """

    starting_size = 10

    def __init__(self, player_cards: CardList):
        try:
            self._validate_deck_size(player_cards)
            self._validate_deck_contents(player_cards)
        except RealmsException:
            raise
        self._undrawn: CardList = player_cards
        shuffle(self._undrawn)  # shuffled in place
        self._discards: CardList = []

    @staticmethod
    def _validate_deck_size(cards: CardList) -> None:
        """Ensures that the starting deck contains the correct
        number of cards

        Parameters
        ----------
        cards : CardList
            The tentative starting deck

        Raises
        ------
        PlayerDeckInitSize
            Raised if the tentative starting deck is not the correct size
        """
        if len(cards) != PlayerDeck.starting_size:
            raise PlayerDeckInitSize(len(cards))
        return
{'fraction_non_alphanumeric': 0.06737728648506383, 'fraction_numerical': 0.0007895775759968417, 'mean_word_length': 2.3480176211453743, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6368104', 'n_tokens_mistral': 2037, 'n_tokens_neox': 1941, 'n_words': 814}