def evolve_card(self, dest_id, cards_to_consume): """Build and execute DB API transaction to combine cards and retrieve latest player cardlist. Args: Same as those of card.evolve(), which this method calls. Returns: If successful: boolean True or a positive integer indicating the number of rows affected. If unsuccessful: boolean False or a zero-value integer. Note: Doesn't explicitly return latest cardlist; if successful the updated results are available in the object's attributes. Raises: RuntimeError: There was an issue with the database transaction required to evolve the card. """ transaction = card.evolve(self.cards[dest_id], cards_to_consume) transaction.extend(card.get_all(self.player['id'])) trans_id = str(uuid.uuid4()) results = self._execute_db_transaction(trans_id, transaction) # Since a query that returns no rows will return a 0, explicitly check for # the False keyword value if results is False: raise RuntimeError("Unable to evolve cards for player %s!" % player['id']) # Otherwise, everything looks successful logger.info("Evolved cardID %d by consuming %d cards", dest_id, len(cards_to_consume)) return results
def _get_cards(self): """Build and execute DB API transaction to retrieve latest player cardlist. Returns: If successful: boolean True or a positive integer indicating the number of rows affected. If unsuccessful: boolean False or a zero-value integer. Note: Doesn't explicitly return latest cardlist; if successful the updated results are available in the object's attributes. Raises: RuntimeError: There was an issue retrieving the cards from the db. """ trans_id = str(uuid.uuid4()) transaction = card.get_all(self.player['id']) results = self._execute_db_transaction(trans_id, transaction) # Since a query that returns no rows will return a 0, explicitly check for # the False keyword value if results is False: raise RuntimeError( "Unable to retreive cards for player %s from the database!" % self.player['id']) return results
def play_stage(self): """Build and execute DB API transaction to simulate player playing a stage. Note: Stamina is not currently validated. Returns: If successful: boolean True or a positive integer indicating the number of rows affected. If unsuccessful: boolean False or a zero-value integer. Note: Doesn't explicitly return latest cardlist/player stats; if successful the updated results are available in the object's attributes. Raises: RuntimeError: There was an issue with the database transaction required to evolve the card. """ # Obviously this could be a call out to a key/value store to get a constantly # updating chance of drops loot_table = self.cfg['loot_tables']['std'] # Standard loot table num_rounds = 5 # rounds in this level transaction = [] # Test to see if the player failed the stage if random.random() <= self.cfg['stage']['failure_chance']: # Roll for card drops for i in range(num_rounds): if (len(self.cards) + len(transaction)) < self.player['slots']: #logger.debug(" Playing round %d" % i) card_type = None # Roll d100 roll = random.random() if roll <= loot_table['drop_chance']: # This can be replaced with a more advanced probabilistic function, just # random for now card_type = random.randint(loot_table['min'], loot_table['max']) transaction.extend(card.create(self.player['id'], card_type)) loot_msg = " Round %2d: Rolled %.2f/%.2f for player %d, dropped card %s" logger.info(loot_msg, i, roll, loot_table['drop_chance'], self.player['id'], str(card_type)) else: full_msg = "****Player (%d) doesn't have any more slots! Discarding remaining drops..." logger.warning(full_msg, self.player['id']) break logger.info(" Player completed stage - %2d loot cards acquired.", len(transaction)) # Assume player took a friend along, give them friend points updated_player = self.player.copy() updated_player['points'] = self.player['points'] + self.cfg[ 'stage']['points_per_run'] # Test that query generation is successful. Necessary as query generation # will fail if, for example, the player already has max friend points update_player_query = player.update(updated_player) if update_player_query: transaction.extend(update_player_query) else: logger.error( "Unable to update player! (continuing without update!)") # After updates, get the latest player/cardlist transaction.extend(player.get(self.player['id'])) transaction.extend(card.get_all(self.player['id'])) # Run transaction trans_id = str(uuid.uuid4()) results = self._execute_db_transaction(trans_id, transaction) # Since a query that returns no rows will return a 0, explicitly check for # the False keyword value if results is False: raise RuntimeError("Unable to Play Stage for player %s!" % self.player['id']) return results else: logger.info(" Player failed stage!") return False