예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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