# Path: MTG/mana.py
# class Mana(Enum):
# class ManaPool():
#     WHITE = 0
#     BLUE = 1
#     BLACK = 2
#     RED = 3
#     GREEN = 4
#     COLORLESS = 5
#     GENERIC = 6
# def str_to_mana_dict(manacost):
# def chr_to_mana(c):
#     def __init__(self, controller=None):
#     def add(self, mana, amount=1):
#     def add_str(self, mana_str):
#     def pay(self, manacost):
#     def is_empty(self):
#     def determine_costs(self, manacost):
#     def canPay(self, manacost, convoke=False):
#     def clear(self):
#     def __repr__(self):
# 
# Path: MTG/zone.py
# class ZoneType(Enum):
# class Zone():
# class Battlefield(Zone):
# class Stack(Zone):
# class Hand(Zone):
# class Graveyard(Zone):
# class Exile(Zone):
# class Library(Zone):
#     LIBRARY = 0
#     HAND = 1
#     BATTLEFIELD = 2
#     GRAVEYARD = 3
#     STACK = 4
#     EXILE = 5
# def str_to_zone_type(z):
#     def __init__(self, controller=None, elements: list=None):
#     def __repr__(self):
#     def __str__(self):
#     def __len__(self):
#     def __bool__(self):
#     def __getitem__(self, pos):
#     def isEmpty(self):
#     def add(self, obj):
#     def remove(self, obj):
#     def filter(self, characteristics=None, filter_func=None):
#     def count(self, characteristics=None, filter_func=None):
#     def get_card_by_name(self, name):
#     def pop(self, pos=-1):
#     def clear(self):
#     def add(self, obj, status_mod=None, modi_func=None):
#     def shuffle(self):
#     def __init__(self, controller=None, elements: list=None):
#     def add(self, obj, from_top=0, shuffle=True):
#     def remove(self, obj, shuffle=False):
# 
# Path: MTG/play.py
# class Play(gameobject.GameObject):
#     def __init__(self, apply_func, apply_condition=lambda: True, 
#                  card=None, source=None, name=None,
#                  targets_chosen=None, target_criterias=None, is_mana_ability=False):
#     def __repr__(self):
#     def can_be_countered(self, source=None):
#     def counter(self, source):
#     def apply(self):
# 
# Path: MTG/gamesteps.py
# class Phase(Enum):
# class Step(Enum):
#     BEGINNING = 0
#     PRECOMBAT_MAIN = 1
#     COMBAT = 2
#     POSTCOMBAT_MAIN = 3
#     ENDING = 4
#     UNTAP = 0
#     UPKEEP = 1
#     DRAW = 2
#     PRECOMBAT_MAIN = 3
#     BEGINNING_OF_COMBAT = 4
#     DECLARE_ATTACKERS = 5
#     DECLARE_BLOCKERS = 6
#     FIRST_STRIKE_COMBAT_DAMAGE = 7
#     COMBAT_DAMAGE = 8
#     END_OF_COMBAT = 9
#     POSTCOMBAT_MAIN = 10
#     END = 11
#     CLEANUP = 12
#     def steps(self):
#     def phase(self):
# 
# Path: MTG/cards.py
# SETPREFIX = ['M15', 'sm_set', 'cube']
#     ID = name_to_id(name)
# def id_to_name(ID):
# def name_to_id(name):
# def str_to_class(str):
# def card_from_name(name, get_instance=True):
# def read_deck(filename):
# def add_activated_ability(cardname, cost, effect, target_criterias=None, prompts=None):
# def add_targets(cardname, criterias=[lambda self, p: True], prompts=None):
# def add_play_func_with_targets(cardname, outcome=lambda self, t, l: True):
#     def play_func(self):
# def add_play_func_no_target(cardname, outcome=lambda self: True):
# def add_aura_effect(cardname, effects, target_criterias=['creature']):
# def add_trigger(cardname, condition, effect, requirements=None,
#                 target_criterias=None, target_prompts=None, intervening_if=None):
# def add_static_effect(cardname, apply_to, name, value, toggle_func=lambda eff: False):
# def indentation_lv(s):
# def parse_card_from_lines(lines, log=None):
# def setup_cards(FILES=['data/m15_cards.txt', 'data/cube_cards.txt']):
# 
# Path: MTG/triggers.py
# class triggerConditions(Enum):
# 
# Path: MTG/token.py
# class Token(permanent.Permanent):
#     def __init__(self, characteristics, controller, activated_abilities=[]):
# def create_token(attributes, controller, num=1, keyword_abilities=[], activated_abilities=[]):


import pdb
import traceback
import random
from copy import deepcopy
from collections import defaultdict
from MTG import mana
from MTG import zone
from MTG import play
from MTG import gamesteps
from MTG import cards
from MTG import triggers
from MTG import token
from MTG.exceptions import *
        - filter out by a condition function if necessary
        - defaults to all cards

        return True if at least one object satisfied the condition
        """

        did_something = False
        # use [:] to iterate over a copy of the list in case items get changed
        cards = self.get_zone(zone)[:]

        for card in cards:
            if condition(card):
                apply_func(card)
                did_something = True

        return did_something


    def apply_to_battlefield(self, apply_func, condition=lambda p: True):
        return self.apply_to_zone(apply_func, zone.ZoneType.BATTLEFIELD, condition)


    def lose(self):
        print("{} has lost the game\n".format(self))
        self.lost = True


    def print_player_state(self):
        print("\nPLAYER {}\nlife: {}\n".format(self.name, self.life))


# Path: MTG/mana.py
# class Mana(Enum):
# class ManaPool():
#     WHITE = 0
#     BLUE = 1
#     BLACK = 2
#     RED = 3
#     GREEN = 4
#     COLORLESS = 5
#     GENERIC = 6
# def str_to_mana_dict(manacost):
# def chr_to_mana(c):
#     def __init__(self, controller=None):
#     def add(self, mana, amount=1):
#     def add_str(self, mana_str):
#     def pay(self, manacost):
#     def is_empty(self):
#     def determine_costs(self, manacost):
#     def canPay(self, manacost, convoke=False):
#     def clear(self):
#     def __repr__(self):
# 
# Path: MTG/zone.py
# class ZoneType(Enum):
# class Zone():
# class Battlefield(Zone):
# class Stack(Zone):
# class Hand(Zone):
# class Graveyard(Zone):
# class Exile(Zone):
# class Library(Zone):
#     LIBRARY = 0
#     HAND = 1
#     BATTLEFIELD = 2
#     GRAVEYARD = 3
#     STACK = 4
#     EXILE = 5
# def str_to_zone_type(z):
#     def __init__(self, controller=None, elements: list=None):
#     def __repr__(self):
#     def __str__(self):
#     def __len__(self):
#     def __bool__(self):
#     def __getitem__(self, pos):
#     def isEmpty(self):
#     def add(self, obj):
#     def remove(self, obj):
#     def filter(self, characteristics=None, filter_func=None):
#     def count(self, characteristics=None, filter_func=None):
#     def get_card_by_name(self, name):
#     def pop(self, pos=-1):
#     def clear(self):
#     def add(self, obj, status_mod=None, modi_func=None):
#     def shuffle(self):
#     def __init__(self, controller=None, elements: list=None):
#     def add(self, obj, from_top=0, shuffle=True):
#     def remove(self, obj, shuffle=False):
# 
# Path: MTG/play.py
# class Play(gameobject.GameObject):
#     def __init__(self, apply_func, apply_condition=lambda: True, 
#                  card=None, source=None, name=None,
#                  targets_chosen=None, target_criterias=None, is_mana_ability=False):
#     def __repr__(self):
#     def can_be_countered(self, source=None):
#     def counter(self, source):
#     def apply(self):
# 
# Path: MTG/gamesteps.py
# class Phase(Enum):
# class Step(Enum):
#     BEGINNING = 0
#     PRECOMBAT_MAIN = 1
#     COMBAT = 2
#     POSTCOMBAT_MAIN = 3
#     ENDING = 4
#     UNTAP = 0
#     UPKEEP = 1
#     DRAW = 2
#     PRECOMBAT_MAIN = 3
#     BEGINNING_OF_COMBAT = 4
#     DECLARE_ATTACKERS = 5
#     DECLARE_BLOCKERS = 6
#     FIRST_STRIKE_COMBAT_DAMAGE = 7
#     COMBAT_DAMAGE = 8
#     END_OF_COMBAT = 9
#     POSTCOMBAT_MAIN = 10
#     END = 11
#     CLEANUP = 12
#     def steps(self):
#     def phase(self):
# 
# Path: MTG/cards.py
# SETPREFIX = ['M15', 'sm_set', 'cube']
#     ID = name_to_id(name)
# def id_to_name(ID):
# def name_to_id(name):
# def str_to_class(str):
# def card_from_name(name, get_instance=True):
# def read_deck(filename):
# def add_activated_ability(cardname, cost, effect, target_criterias=None, prompts=None):
# def add_targets(cardname, criterias=[lambda self, p: True], prompts=None):
# def add_play_func_with_targets(cardname, outcome=lambda self, t, l: True):
#     def play_func(self):
# def add_play_func_no_target(cardname, outcome=lambda self: True):
# def add_aura_effect(cardname, effects, target_criterias=['creature']):
# def add_trigger(cardname, condition, effect, requirements=None,
#                 target_criterias=None, target_prompts=None, intervening_if=None):
# def add_static_effect(cardname, apply_to, name, value, toggle_func=lambda eff: False):
# def indentation_lv(s):
# def parse_card_from_lines(lines, log=None):
# def setup_cards(FILES=['data/m15_cards.txt', 'data/cube_cards.txt']):
# 
# Path: MTG/triggers.py
# class triggerConditions(Enum):
# 
# Path: MTG/token.py
# class Token(permanent.Permanent):
#     def __init__(self, characteristics, controller, activated_abilities=[]):
# def create_token(attributes, controller, num=1, keyword_abilities=[], activated_abilities=[]):


# Path: MTG/player.py
import pdb
import traceback
import random
from copy import deepcopy
from collections import defaultdict
from MTG import mana
from MTG import zone
from MTG import play
from MTG import gamesteps
from MTG import cards
from MTG import triggers
from MTG import token
from MTG.exceptions import *

        - filter out by a condition function if necessary
        - defaults to all cards

        return True if at least one object satisfied the condition
        """

        did_something = False
        # use [:] to iterate over a copy of the list in case items get changed
        cards = self.get_zone(zone)[:]

        for card in cards:
            if condition(card):
                apply_func(card)
                did_something = True

        return did_something


    def apply_to_battlefield(self, apply_func, condition=lambda p: True):
        return self.apply_to_zone(apply_func, zone.ZoneType.BATTLEFIELD, condition)


    def lose(self):
        print("{} has lost the game\n".format(self))
        self.lost = True


    def print_player_state(self):
        print("\nPLAYER {}\nlife: {}\n".format(self.name, self.life))


        print("mana: {}\n".format(self.mana))