def draw_first_cards(self, uid): # who_starts = self.players[randint(0, 1)] # who_starts = self.get_player_by_uid("ai") # TODO who_starts = self.get_nonai_player() drawed_cards = [[], []] j = 0 for player in self.players: for i in range(3): drawed_cards[j] += player.draw_card(return_tailored=True) j += 1 result = { 'type': "draw-first-cards", 'who_starts': who_starts.uid, 'cmds': [] } command = Command(meta={'uid': uid}) command.add('list', [drawed_cards[0][0], drawed_cards[1][0]]) command.add('list', [drawed_cards[0][1], drawed_cards[1][1]]) command.add('list', [drawed_cards[0][2], drawed_cards[1][2]]) # command = who_starts.start_turn(base_command=command) result['cmds'] = command return result
def end_turn(self, base_command=None): # logger.info("############################ ENDING TURN FOR {0}".format(self.uid)) if not base_command: command = Command(meta={'uid': self.uid}) else: command = base_command opponent = self.game.get_opposite_player(self.uid) tailored1 = self.trigger_turn_event("onturn:end", opponent) if len(tailored1): command.add('list', tailored1) tailored2 = self.trigger_turn_event("onplayer:turn:end", opponent) if len(tailored2): command.add('list', tailored2) logger.info( "################################################## TURN ENDED FOR {0}" .format(self.uid)) return opponent.start_turn(base_command=command)
def card_attack_to_player(self, attacker_uuid, target_uid, base_command=None): if base_command: command = base_command else: command = Command(meta={'uid': self.uid}) target_player = self.game.get_player_by_uid(target_uid) attacker_player = self.game.get_opposite_player(target_uid) attacker = attacker_player.ground.get_card_by_uuid(attacker_uuid) attacker.attacked_this_turn = True # DEFENDER defenders = target_player.ground.get_cards({ 'defender': True, 'count': 1, 'random': True, 'ignore-immune': True }) if len(defenders): defender = defenders[0] command.add( 'dummy', { 'uid': target_player.uid, 'uuid': defender.uuid, 'textanim': { 'text': "Defender", 'harmful': False } }) return self.card_attack_from_ground(attacker_uuid, defender.uuid, base_command=command) # attacker.hp -= target.dp TODO Player.dp not implemented yet target_player.hp -= attacker.dp target_total_damage = attacker.dp # TODO TOGETHER - shoul we implement attack together to player? simple_logger.debug("{0} attacked to player {1}({2})".format( attacker.label, target_player.name, target_player.hp)) command.add( 'attacked', { 'attacker': { 'uid': self.uid, 'uuid': attacker.uuid, 'attacked_this_turn': True }, 'target': { 'uid': target_player.uid } # we don't send uuid so client must understand it's an attack to a player }) tailor1 = list() tailor1.append({ 'dummy': { 'uid': target_player.uid, 'textanim': { 'text': "-{0}".format(target_total_damage), 'harmful': True } } }) # TODO player's cannot attack now # tailor1.append({'dummy': {'uid': self.uid, 'uuid': attacker.uuid, 'textanim': {'text': "-{0}".format(target.dp), 'harmful': True}}}) tailor1.append({ "hp_decreased": { 'uid': target_player.uid, 'hp': target_player.hp } }) command.add('list', tailor1) # attacker's attack triggering event_result2 = self.game.events.fire('onauraAttack', { 'triggerer': attacker, 'attacker': attacker, 'victim': target_player }) if event_result2: command.add('list', event_result2) if target_player.hp <= 0: self.game.over = True command.add('player_died', {'uid': target_player.uid}) # TODO if attacker died (player must have dp for this) return command
def start_turn(self, base_command=None): logger.info( "################################################## STARTING TURN {0} FOR {1}" .format(self.turn.no, self.uid)) simple_logger.debug("\nTurn {0} started for {1}".format( self.turn.no, self.name)) if self.inspector and self.game.over: print("Game Over") simple_logger.debug("\nRESULT:") simple_logger.debug(base_command.items) return base_command # raise Exception("Game Over") self.turn.start() if base_command: command = base_command else: command = Command(meta={'uid': self.uid}) command.add('turn-begin', self.turn.to_json()) # add draw card command # command = self.draw_card(base_command=command) result = self.draw_card(return_tailored=True) if result: if "drawed" in result: card = self.hand.get_card_by_uuid(result['drawed']['uuid']) tailored = card.cast_spell('ondraw', {'provided': card}) # returns list if tailored: result = [result] result += tailored command.add('list', result) else: command.add('drawed', result['drawed']) # print(command.items) # import sys # sys.exit(2) else: command.add('discarded', result['discarded']) if self.uid == "ai" or self.inspector: command = self.ai.play_your_turn(base_command=command) opponent = self.game.get_opposite_player(self.uid) tailored2 = self.trigger_turn_event("onplayer:turn:begin", opponent) if len(tailored2): command.add('list', tailored2) """ tailored1 = [] opponent = self.game.get_opposite_player(self.uid) for card in opponent.ground.cards: tailored1 += card.cast_spell("onplayer:turn:end") logger.info("Events> player({0}):turn:end {1}".format(opponent.uid, tailored1)) if len(tailored1): command.add('list', tailored1) """ return command
def card_attack_from_ground( self, attacker_uuid, target_uuid, base_command=None ): # TODO stop attacking multiple times in one turn target_player = self.game.get_opposite_player(self.uid) attacker = self.ground.get_card_by_uuid(attacker_uuid) try: target = target_player.ground.get_card_by_uuid(target_uuid) except Exception as err: import sys print("{0}.ground.get_card_by_uuid({1}) DoesNotExist {1}".format( self.name, target_uuid, target_player.ground.cards)) sys.exit(1) attacker.attacked_this_turn = True defender = None defenders = target_player.ground.get_cards({ 'defender': True, 'count': 1, 'random': True, 'exclude': target, 'ignore-immune': True }) if len(defenders): defender = defenders[0] target = defender if not target: import sys print( "card_attack_from_ground: NoTargetAtSecond me:{0} target:{1} {2}" .format(self.name, target_uuid, target_player.ground.cards)) sys.exit(1) try: attacker.hp -= target.dp except AttributeError as err: print("card_attack_from_ground: AttributeError.1", err, attacker.label, target, target_uuid) try: target.hp -= attacker.dp except AttributeError as err: print("card_attack_from_ground: AttributeError.2", err, target.label, attacker.label, target_uuid) # self.turn.remaining_mana -= attacker.mana if base_command: command = base_command else: command = Command(meta={'uid': self.uid}) if defender: command.add( 'dummy', { 'uid': target_player.uid, 'uuid': defender.uuid, 'textanim': { 'text': "Defender", 'harmful': False } }) # TOGETHER target_total_damage = attacker.dp attack_together = False if attacker.together: partners = self.ground.get_cards({ 'canattack': True, 'random': True, 'count': 1, 'exclude': attacker, 'ignore-immune': True }) if len(partners): partner = partners[0] if target.hp > 0: # target must be still alive after attacker's attack partner.hp -= target.dp target.hp -= partner.dp command.add( 'dummy', { 'uid': self.uid, 'uuid': partner.uuid, 'textanim': { 'text': "Together", 'harmful': False } }) tailored = list() tailored.append({ 'attacked': { 'attacker': { 'uid': self.uid, 'uuid': attacker.uuid, 'attacked_this_turn': True }, 'target': { 'uid': target_player.uid, 'uuid': target.uuid } } }) tailored.append({ 'attacked': { 'attacker': { 'uid': self.uid, 'uuid': partner.uuid }, 'target': { 'uid': target_player.uid, 'uuid': target.uuid } } }) command.add('list', tailored) attack_together = True target_total_damage += partner.dp if not attack_together: command.add( 'attacked', { 'attacker': { 'uid': self.uid, 'uuid': attacker.uuid, 'attacked_this_turn': True }, 'target': { 'uid': target_player.uid, 'uuid': target.uuid } }) simple_logger.debug("{0} attacked to {1}".format( attacker.label, target.label)) tailor1 = list() if target.dp > 0: tailor1.append({ 'dummy': { 'uid': self.uid, 'uuid': attacker.uuid, 'textanim': { 'text': "-{0}".format(target.dp), 'harmful': True } } }) if target_total_damage > 0: tailor1.append({ 'dummy': { 'uid': target_player.uid, 'uuid': target.uuid, 'textanim': { 'text': "-{0}".format(target_total_damage), 'harmful': True } } }) command.add('list', tailor1) tailor2 = list() # if attacker.is_hp_decreased(): if target.dp > 0: # if its bleeding tailor2.append({ "hp_decreased": { 'uid': self.uid, 'uuid': attacker.uuid, 'hp': attacker.hp } }) # if target.is_hp_decreased(): if target_total_damage > 0: # if its bleeding tailor2.append({ "hp_decreased": { 'uid': target_player.uid, 'uuid': target.uuid, 'hp': target.hp } }) # victim's defense triggering event_result1 = self.game.events.fire('onauraDefense', { 'triggerer': target, 'attacker': attacker, 'victim': target }) if event_result1: tailor2 += event_result1 # attacker's attack triggering event_result2 = self.game.events.fire('onauraAttack', { 'triggerer': attacker, 'attacker': attacker, 'victim': target }) if event_result2: tailor2 += event_result2 # target's ondefense triggering event_result3 = target.cast_spell('ondefense', {'provided': attacker}) if event_result3: tailor2 += event_result3 if len(tailor2): command.add('list', tailor2) tailor3 = [] tailor4 = [] if target.alive and target.hp <= 0: card_died_dict = { "card_died": { 'uid': target_player.uid, 'uuid': target.uuid } } if target.avengeme and attacker.hp > 0 and len( target_player.ground.cards ) - 1: # avengeme card still on the ground card_died_dict['card_died']['textanim'] = { 'text': "Avenge Me!", 'harmfull': True } tailor3.append(card_died_dict) event_result = target.kill( destroyer=attacker) # trigger game event/auras if event_result: tailor4 += event_result if attacker.alive and attacker.hp <= 0: tailor3.append( {"card_died": { 'uid': self.uid, 'uuid': attacker.uuid }}) event_result = attacker.kill( destroyer=target) # trigger game event/auras if event_result: tailor4 += event_result if len(tailor3): # card_died tailors command.add('list', tailor3) if len(tailor4): # ondestroy game event command.add('list', tailor4) # target has avenge me if target.avengeme and target.hp <= 0 and attacker.hp and len( target_player.ground.cards): # TODO find most powerfull ally cards = target_player.ground.get_cards({ 'canattack': True, 'random': True, 'count': 1, 'ignore-immune': True }) if len(cards): avenger = cards[0] command.add( 'dummy', { 'uid': target_player.uid, 'uuid': avenger.uuid, 'textanim': { 'text': "Avenger", 'harmful': False } }) command = target_player.card_attack_from_ground( avenger.uuid, attacker.uuid, base_command=command) # target has revenge if target.revenge and target.hp > 0 and target.dp > 0 and attacker.hp > 0: target.dp += target.revenge command.add( 'dp_increased', { 'uid': target_player.uid, 'uuid': target.uuid, 'dp': target.dp, 'textanim': { 'text': "Revenge", 'harmful': False } }) command = target_player.card_attack_from_ground( target.uuid, attacker.uuid, base_command=command) target.dp -= target.revenge if target.hp > 0: # if still alive after revenge > restore dp command.add('dp_restored', { 'uid': target_player.uid, 'uuid': target.uuid, 'dp': target.dp }) return command
def play_spell_card(self, attacker_uuid, target_uuid=None, base_command=None): cast_data = None target = None from_card = self.hand.get_card_by_uuid(attacker_uuid) if not from_card: logger.info("ERROR> play_spell_card probably double playing.") logger.info("Hand.DoesNotExist owner:{0} uuid:{1} hand{2}".format( self.uid, attacker_uuid, [{ 'title': c.title, 'uuid': c.uuid } for c in self.hand.cards])) return None if target_uuid: if target_uuid.startswith("{0}-".format( self.uid)): # am i targeting one of my cards? target_player = self else: target_player = self.game.get_opposite_player(self.uid) target = target_player.ground.get_card_by_uuid(target_uuid) cast_data = {'provided': target} self.hand.remove(from_card) self.graveyard.add(from_card) simple_logger.debug("{0} played spell card {1}".format( self.name, from_card.title)) self.turn.remaining_mana -= from_card.mana if base_command: command = base_command else: command = Command(meta={'uid': self.uid}) result_dict = { 'uid': self.uid, 'uuid': from_card.uuid, 'remaining_mana': self.turn.remaining_mana, 'from': from_card.title } if target_uuid: result_dict['target'] = target_uuid result_dict['to'] = target.title # we assume spell cards has only one spell in it and it's trigger is onplay right? spell = from_card.spells[0] if spell.animation: result_dict['animation'] = spell.animation command.add('spell_card_played', result_dict) tailored = from_card.cast_spell( "onplay", cast_data ) # TODO put animation type (ex: fireball, freeze etc to use in client-side) died = None if tailored: died_index = -1 for index, item in enumerate(tailored): if list(item.keys())[0] == "card_died": died_index = index break if died_index >= 0: died = list(tailored[died_index].values())[0] del tailored[died_index] command.add('list', tailored) event_result = self.game.events.fire('onauraPlay', { 'card': from_card, 'target': target }) if event_result and len(event_result): command.add('list', event_result) if died: simple_logger.debug( "{0} play_spell_card some card died {0}".format( self.name, died)) command.add('card_died', died) return command
def play_creature_card(self, card_uuid, target=None, slot=4, base_command=None): card = self.hand.get_card_by_uuid(card_uuid) if not card: logger.info("ERROR> play_creature_card probably double playing.") logger.info( "Player.play_creature_card uid:{0} card:{1} hand:{2}".format( self.uid, card_uuid, [{ 'uuid': c.uuid, 'title': c.title } for c in self.hand.cards])) return None if base_command: command = base_command else: command = Command(meta={'uid': self.uid}) # TODO check is playable? self.hand.remove(card) # TODO check is groundable? self.ground.add(card, slot=slot) # ground_slot is defining here simple_logger.debug("{0} played creature {1}".format( self.name, card.title)) self.turn.remaining_mana -= card.mana command.add( 'creature_card_played', { 'uid': self.uid, 'uuid': card.uuid, 'slot': card.slot_index, 'remaining_mana': self.turn.remaining_mana }) tailored = card.cast_spell('ondeploy', {'provided': target}) died = None if tailored and len(tailored): died_index = -1 for index, item in enumerate(tailored): try: if list(item.keys())[0] == "card_died": died_index = index break except AttributeError as err: print("play_creature_card AttributeError", err, item, tailored) if died_index >= 0: died = list(tailored[died_index].values())[0] del tailored[died_index] if len(tailored): command.add('list', tailored) event_result = self.game.events.fire('onauraPlay', { 'card': card, 'target': target }) if event_result and len(event_result): command.add('list', event_result) if died: simple_logger.debug( "{0} play_creature_card some card died {1}".format( self.name, died)) command.add('card_died', died) return command
def draw_card(self, amount=1, base_command=None, return_tailored=False): command = None if not return_tailored: if base_command: command = base_command else: command = Command(meta={'uid': self.uid}) if len(self.deck.cards): card = self.deck.cards.pop() """ :type card: server.Card """ deck_count = len(self.deck.cards) if card: if len(self.hand.cards) + 1 > self.hand.limit: logger.info("Player> Discard card -> hand is full") if return_tailored: command = { 'discarded': { 'uuid': card.uuid, 'uid': self.uid, 'ckey': card.key, 'deck_count': deck_count } } else: command.add( 'discarded', { 'uuid': card.uuid, 'uid': self.uid, 'ckey': card.key, 'deck_count': deck_count }) else: self.hand.add(card) draw_data = { 'uid': self.uid, 'uuid': card.uuid, 'ckey': card.key, 'deck_count': deck_count } if card.is_hp_increased(): # karamurat etc draw_data['hp_increased'] = True draw_data['hp'] = card.hp if card.is_dp_increased(): # karamurat etc draw_data['dp_increased'] = True draw_data['dp'] = card.dp if return_tailored: command = {'drawed': draw_data} else: command.add('drawed', draw_data) simple_logger.debug("{0} drawed {1}".format( self.name, card.label)) logger.info("Player.{0}.draw_card {1}".format( self.uid, card.label)) else: logger.info("Player> Draw failed, no cards in deck!") return command
def load_game(self): from server.models import Card result = { 'id': self.id, 'type': 'load-game', 'players': None, 'carddb': [c.to_json() for c in Card.objects.all()], 'first_cards': None } if self.dungeon: result['dungeon'] = { 'name': self.dungeon.name, 'stage': self.dungeon.stage, 'next_stage': self.dungeon.next_stage, 'cardback': self.dungeon.cardback, 'boss': { 'name': self.dungeon.boss['name'], 'portrait': self.dungeon.boss['portrait'], 'hp': self.dungeon.boss['hp'] } } players = [] for player in self.players: # cards = [vc.to_simple_json() for vc in player.deck.cards] players.append({ 'uid': player.uid, 'name': player.name, 'deck_count': len(player.deck.cards) }) result['players'] = players cards1 = [ self.players[0].draw_card(return_tailored=True), self.players[1].draw_card(return_tailored=True) ] # drawed_cards[1][0] = self.players[1].draw_card_by_key(card_key="creature_corrupted-warmaster") cards2 = [ self.players[0].draw_card(return_tailored=True), self.players[1].draw_card(return_tailored=True) ] cards3 = [ self.players[0].draw_card(return_tailored=True), self.players[1].draw_card(return_tailored=True) ] command = Command(meta={'uid': self.players[0].uid}) # player is temp command.add('list', cards1) command.add('list', cards2) command.add('list', cards3) """ drawed_cards = [[], []] j = 0 for player in self.players: for i in range(3): if i == 0 and player.uid == "ai": drawed_cards[j] += player.draw_card_by_key(card_key="creature_corrupted-warmaster") else: drawed_cards[j] += player.draw_card(return_tailored=True) j += 1 command = Command(meta={'uid': self.players[0].uid}) # player is temp command.add('list', [drawed_cards[0][0], drawed_cards[1][0]]) command.add('list', [drawed_cards[0][1], drawed_cards[1][1]]) command.add('list', [drawed_cards[0][2], drawed_cards[1][2]]) """ result['first_cards'] = command.finalize() return result
def play_your_turn(self, base_command=None): if base_command: command = base_command else: command = Command(meta={'uid': self.player.uid}) result_cmd = command while True: # repeat until no action left # result_cmd = self.action_permutation(permutations, result_cmd) rnd_action = randint(0, 1) if rnd_action == 0: result_cmd = self.play_creature_card( result_cmd ) or self.play_spell_card(result_cmd) or self.card_attack_card( result_cmd) or self.card_attack_to_player(result_cmd) else: result_cmd = self.play_spell_card( result_cmd) or self.play_creature_card( result_cmd) or self.card_attack_to_player( result_cmd) or self.card_attack_card(result_cmd) # region old but gold """ rnd_action = randint(0, 5) if rnd_action == 0: result_cmd = self.play_spell_card(result_cmd) or self.play_creature_card( result_cmd) or self.card_attack_card(result_cmd) elif rnd_action == 1: result_cmd = self.play_spell_card(result_cmd) or self.card_attack_card( result_cmd) or self.play_creature_card(result_cmd) elif rnd_action == 2: result_cmd = self.play_creature_card(result_cmd) or self.play_spell_card( result_cmd) or self.card_attack_card(result_cmd) elif rnd_action == 3: result_cmd = self.play_creature_card(result_cmd) or self.card_attack_card( result_cmd) or self.play_spell_card(result_cmd) elif rnd_action == 4: result_cmd = self.card_attack_card(result_cmd) or self.play_creature_card( result_cmd) or self.play_spell_card(result_cmd) elif rnd_action == 5: result_cmd = self.card_attack_card(result_cmd) or self.play_spell_card( result_cmd) or self.play_creature_card(result_cmd) """ # endregion # result_cmd = self.play_card(result_cmd) if result_cmd: command = result_cmd # logger.info("AI> HERE MY TURN RESULT {0}".format(command.items)) else: logger.info("AI> play_your_turn No more action left") break # end ai's turn # time.sleep(1) command = self.player.end_turn(base_command=command) # print("AI.play_your_turn", command.__dict__) return command