def put_on_stack(self): if self.choose_targets(): return play.Play(lambda: self.resolve(), apply_condition=lambda: self.intervening_if(self), name=self.card.name + ' triggered ability ' + str(self), source=self) return None
def play_card(self, card): if isinstance(card, str): # convert card name to Card object card = cards.card_from_name(card) _play = play.Play(card.play_func) if _play.is_mana_ability or _play.is_special_action: # applies instantly _play.apply() else: self.game.stack.add(play) # add to stack
def activate_ability(self, num=0): print("activating ability... {}".format(self.activated_abilities[num])) # pdb.set_trace() # self._activated_abilities_effects[num](self) name = self.name + ' activated ability #' + str(num) return play.Play( lambda: self.activated_abilities[num].resolve(), source=self.activated_abilities[num], name=name, is_mana_ability=self.activated_abilities[num].is_mana_ability)
def get_action(self): """ asks the player to do something this gets called whenever a player has priority """ answer = 'placeholder' _play = None while answer and _play is None: answer = self.make_choice( "What would you like to do? {}{}, {}\n".format( self.name, '*' if self.is_active else '', self.game.step)) if self.game.test: print("\t" + self.name + ", " + str(self.game.step) + ": " + answer + "\n") if answer == '': break try: if answer == 'print': self.game.print_game_state() elif answer == 'hand': print(self.hand) elif answer == 'battlefield': print(self.battlefield) elif answer == 'graveyard': print(self.graveyard) elif answer == 'exile': print(self.exile) elif answer == 'stack': print(self.game.stack) elif answer == 'mana': print(self.mana) ## debug elif answer == 'addmana': self.mana.add_str('WWWWWUUUUUBBBBBRRRRRGGGGG11111') elif answer == 'debug': # pdb.set_trace() pass elif answer[:2] == '__': # for dev purposes exec(answer[2:]) return '__continue' elif answer[0] == 'p': # playing card from hand try: # 'p 3' == plays third card in hand num = int(answer[2:]) assert num < len(self.hand) card = self.hand[num] except: name = answer[2:] # 'p Island' == plays 'Island' card = self.hand.get_card_by_name(name) assert card # timing & restrictions can_play = True if card.is_land and self.landPlayed >= self.landPerTurn: can_play = False if not (card.is_instant or card.has_ability('Flash')) and ( self.game.stack or self.game.step.phase not in [ gamesteps.Phase.PRECOMBAT_MAIN, gamesteps.Phase.POSTCOMBAT_MAIN ] or not self.is_active): can_play = False # choose targets if can_play: can_target = card.targets() # pay mana costs if can_play and can_target: can_pay = False cost = card.manacost creatures_to_tap = [] if card.has_ability("Convoke"): untapped_creatures = [ c for c in self.creatures if not c.status.tapped ] print("Your creatures: {}".format( untapped_creatures)) ans = self.make_choice( "What creatures would you like to tap" " to pay for %s? (Convoke) " % card) ans = ans.split(" ") for ind in ans: try: ind = int(ind) _creature = untapped_creatures[ind] if not _creature.status.tapped and _creature not in creatures_to_tap: color = _creature.characteristics.color if not color: color = 'C' elif len(color) > 1: color = self.make_choice( "What color would you like to add? {}" .format(color)) assert color in mana.manachr else: color = color[0] color = mana.chr_to_mana(color) creatures_to_tap.append(_creature) if cost[color]: cost[color] -= 1 else: if cost[mana.Mana.GENERIC]: cost[mana.Mana.GENERIC] -= 1 else: raise ValueError except (IndexError, ValueError): print( "error processing creature for convoke" ) pass can_pay = self.mana.canPay(cost) if can_play and can_target and can_pay: self.hand.remove(card) self.mana.pay(can_pay) for _creature in creatures_to_tap: _creature.tap() print("{} playing {} targeting {}\n".format( self, card, card.targets_chosen)) _play = play.Play(card.play_func, card=card) # special actions if card.is_land: _play.is_special_action = True self.landPlayed += 1 else: # illegal casting, revert if not can_play: print("Cannot play this right now\n") elif not can_target: print("Cannot target\n") elif not can_pay: print("Cannot pay mana costs\n") # activate ability from battlefield -- 'a 3_1' plays 2nd (index starts at 0) ability from 3rd permanent # 'a 3' playrs 1st (default) ability of the 3rd permanent elif answer[:2] == 'a ': nums = answer[2:].split('_') if len(nums) == 1: nums.append(0) nums[0] = int(nums[0]) nums[1] = int(nums[1]) assert nums[0] < len(self.battlefield) card = self.battlefield[nums[0]] assert nums[1] <= len(card.activated_abilities) # ability activation # if card._activated_abilities_costs_validation[nums[1]](card): # TODO: target validation PLAYER_PREVIOUS_STATE = deepcopy(self) # if card._activated_abilities_costs[nums[1]](card): if card.activated_abilities[nums[1]].can_activate(): # TODO: make each ability have its own description/name for printing _play = card.activate_ability(nums[1]) else: raise ResetGameException # skip priority until something happens / certain step elif answer[:2] == 's ': if answer[2:] == 'main': answer = 's precombat_main' if answer[2:] == 'main2': answer = 's postcombat_main' if answer[2:] == 'combat': answer = 's beginning_of_combat' assert answer[2:].upper() in gamesteps.Step._member_names_ self.passPriorityUntil = gamesteps.Step[answer[2:].upper()] break else: raise BadFormatException() except ResetGameException: print("Illegial action. Resetting...") self = PLAYER_PREVIOUS_STATE except: traceback.print_exc() print("Bad format.\n") continue return _play