Ejemplo n.º 1
0
    def add_item_menu(self, inventory):
        # Add a nil_type so that the NOT IN clause always has a valid syntax if there are no weapons in the
        # inventory
        weapon_types = [w.type for w in inventory.weapons()] + ['nil_type']
        fetch_armors = len(inventory.armors()) == 0

        weapons_query = """
            SELECT items.*, weapons.* FROM weapons
            INNER JOIN items ON weapons.item_id = items.id
            WHERE weapons.type NOT IN {0}
              AND weapons.item_id IN (SELECT item_id FROM owns WHERE username=%(username)s)
        """.format(sql.sql_format_tuple(weapon_types))

        armors_query = """
            SELECT items.*, armors.* FROM armors
            INNER JOIN items ON armors.item_id = items.id
            WHERE armors.item_id IN (SELECT item_id FROM owns WHERE username=%(username)s)
        """

        armors = []

        with self.connection.cursor() as cursor:
            cursor.execute(weapons_query, {"username": self.player.username})
            weapons = list(sql.objects(cursor))

            if fetch_armors:
                cursor.execute(armors_query,
                               {"username": self.player.username})
                armors = list(sql.objects(cursor))

        options = weapons + armors
        descriptions = []

        for weapon in weapons:
            descriptions.append('%s -- %s, weight: %d, range: %d, damage: %d' %
                                (weapon.name, weapon.type, weapon.weight,
                                 weapon.range, weapon.damage))

        for armor in armors:
            descriptions.append('%s -- Armor, weight: %d, protection: %d' %
                                (armor.name, armor.weight, armor.protection))

        if len(options) == 0:
            print("Your inventory is already full! Please remove items first"
                  " if you want to add a different weapon or armor.")
        else:
            new_item = prompts.select_from_list(
                options,
                descriptions, "Please select an item from this list to add"
                " to your inventory",
                interactive_with_single_option=True)
            with self.connection.cursor() as cursor:
                cursor.execute(
                    "INSERT INTO inventory_contains (username, name, item_id)"
                    "VALUES (%(username)s, %(name)s, %(item_id)s)", {
                        "username": self.player.username,
                        "name": inventory.name,
                        "item_id": new_item.id
                    })
Ejemplo n.º 2
0
    def initialize_game_session(self, teams, game_map, game_type,
                                player_inventories):
        with self.connection.cursor() as cursor:
            insert_query = sql.insert_query('game_sessions',
                                            ['game_type', 'map_name'],
                                            [(game_type, game_map)],
                                            return_fields=['*'])
            cursor.execute(insert_query)

            game_session = next(sql.objects(cursor))

            # Insert records into the plays table
            plays_tuples = []

            for i, team in enumerate(teams):
                for player in team:
                    plays_tuples.append(
                        (player, player_inventories[player].name,
                         game_session.gid, i + 1))

            plays_insert_query = sql.insert_query(
                'plays', ('username', 'inventory_name', 'gid', 'team_number'),
                plays_tuples)
            cursor.execute(plays_insert_query)

        return game_session
Ejemplo n.º 3
0
    def get_for_player(connection, username):
        with connection.cursor() as cursor:
            cursor.execute(
                "SELECT * FROM inventories WHERE username=%(username)s",
                {"username": username})

            return [
                Inventory(connection, record) for record in sql.objects(cursor)
            ]
Ejemplo n.º 4
0
    def create_new_inventory(self):
        print("Please choose a name for your new inventory!")
        new_name = self.prompt_for_name()

        with self.connection.cursor() as cursor:
            query = sql.insert_query('inventories', ('username', 'name'),
                                     [(self.player.username, new_name)],
                                     return_fields='*')
            cursor.execute(query)
            inventory = next(sql.objects(cursor))
            return Inventory(self.connection, inventory)
Ejemplo n.º 5
0
    def get_recent_games(self):
        query = """
            WITH recent_games AS (
                SELECT plays.gid,
                       game_sessions.map_name,
                       game_sessions.game_type,
                       game_sessions.winning_team,
                       game_sessions.start_time,
                       game_sessions.end_time
                FROM plays
                         INNER JOIN game_sessions ON plays.gid = game_sessions.gid
                WHERE username = %(username)s
                ORDER BY start_time DESC
                LIMIT 5
            )
            SELECT inventory_name,
                   kills,
                   deaths,
                   assists,
                   map_name,
                   game_type,
                   team_number = winning_team as win,
                   start_time,
                   end_time
            FROM plays
            INNER JOIN recent_games
                ON plays.gid = recent_games.gid
            WHERE username = %(username)s;
        """
        with self.connection.cursor() as cursor:
            cursor.execute(query, {"username": self.player.username})
            game_stats = sql.objects(cursor)

            table = []
            for game in game_stats:
                outcome = 'Win' if game.win else 'Loss'
                start = game.start_time.strftime("%Y-%m-%d %H:%M:%S")
                duration_timedelta = game.end_time - game.start_time
                minutes = duration_timedelta.seconds // 60

                table.append([
                    start, outcome, game.game_type, game.map_name, game.kills,
                    game.deaths, game.assists,
                    '%.2f' % (game.kills / game.deaths),
                    '%d minutes' % minutes
                ])

            print(
                tabulate.tabulate(table, [
                    'Start Time', 'Outcome', 'Game Type', 'Map', 'Kills',
                    'Deaths', 'Assists', 'KDR', 'Duration'
                ]))
Ejemplo n.º 6
0
    def create_new_guild(self):
        print("Please choose a name for your guild")
        new_name = self.prompt_for_name()

        with self.connection.cursor() as cursor:
            query = sql.insert_query('guilds', ('admin_username', 'name'),
                                     [(self.player.username, new_name)],
                                     return_fields='*')
            cursor.execute(query)
            guild = next(sql.objects(cursor))

        self.set_player_guild(self.player, guild)
        self.connection.commit()
Ejemplo n.º 7
0
    def armors_menu(self):
        query = """
            SELECT items.*, armors.* FROM armors 
            INNER JOIN items ON armors.item_id = items.id
            WHERE items.id NOT IN (SELECT item_id FROM owns WHERE username=%(username)s)
        """
        with self.connection.cursor() as cursor:
            cursor.execute(query, {"username": self.player.username})
            armors = list(sql.objects(cursor))

        def formatter(armor):
            return 'Price: %d -- %s -- weight: %d, protection: %d' % \
                   (armor.price, armor.name, armor.weight, armor.protection)

        self.purchase_menu_loop(
            armors, formatter,
            'You have already purchased all the armors in the game!')
Ejemplo n.º 8
0
    def weapons_menu(self):
        query = """
            SELECT items.*, weapons.* FROM weapons 
            INNER JOIN items ON weapons.item_id = items.id
            WHERE items.id NOT IN (SELECT item_id FROM owns WHERE username=%(username)s)
        """
        with self.connection.cursor() as cursor:
            cursor.execute(query, {"username": self.player.username})
            weapons = list(sql.objects(cursor))

        def formatter(w):
            return 'Price: %d -- %s -- weight: %d, range: %d, damage: %d' % \
                    (w.price, w.name, w.weight, w.range, w.damage)

        self.purchase_menu_loop(
            weapons, formatter,
            'You have already purchased all the weapons in the game!')
Ejemplo n.º 9
0
    def add_new_attachment(self, inventory, weapon, current_attachments):
        query = """
            SELECT items.id, items.name, items.weight FROM attachments
            INNER JOIN items ON attachments.item_id = items.id
            WHERE attachments.attaches_to_id = %(weapon_item_id)s
              AND attachments.item_id NOT IN (
                SELECT item_id AS id FROM inventory_contains
                WHERE username=%(username)s AND name=%(name)s
              )
              AND attachments.item_id IN (
                SELECT item_id AS id FROM owns
                WHERE username=%(username)s
              )
        """

        with self.connection.cursor() as cursor:
            cursor.execute(
                query, {
                    "weapon_item_id": weapon.id,
                    "username": self.player.username,
                    "name": inventory.name
                })
            attachments = list(sql.objects(cursor))

        if len(attachments) == 0:
            print("You don't own any additional attachments for this item!")
        else:
            print("Which attachment would you like to add.")
            descriptions = [
                "%s, weight: %d" % (a.name, a.weight) for a in attachments
            ]
            attachment = prompts.select_from_list(
                attachments,
                descriptions,
                "Choose a number from this list:",
                interactive_with_single_option=True)
            with self.connection.cursor() as cursor:
                cursor.execute(
                    "INSERT INTO inventory_contains (username, name, item_id)"
                    "VALUES (%(username)s, %(name)s, %(item_id)s)", {
                        "username": self.player.username,
                        "name": inventory.name,
                        "item_id": attachment.id
                    })
Ejemplo n.º 10
0
    def join_a_guild(self):
        query = "SELECT admin_username, name, created_date FROM guilds"
        with self.connection.cursor() as cursor:
            cursor.execute(query)
            guilds = list(sql.objects(cursor))

        descriptions = [
            '%s -- Admin: %s, active since %s' %
            (g.name, g.admin_username, g.created_date.strftime("%Y-%m-%d"))
            for g in guilds
        ] + ['Exit without joining anything']
        guilds.append('exit')

        option = prompts.select_from_list(
            guilds, descriptions, "Which guild would you like to join?")
        if option == 'exit':
            return

        self.set_player_guild(self.player, option)
        self.connection.commit()
        print("Welcome to %s!" % option.name)
Ejemplo n.º 11
0
    def attachments_menu(self):
        query = """
            SELECT items.*, attaches_to.name as attaches_to_name FROM attachments
            INNER JOIN items ON attachments.item_id = items.id
            INNER JOIN items AS attaches_to ON attachments.attaches_to_id = attaches_to.id
            WHERE attaches_to.id IN (SELECT item_id FROM owns WHERE username=%(username)s)
              AND items.id NOT IN (SELECT item_id FROM owns WHERE username=%(username)s)
            ORDER BY attaches_to_name
        """
        with self.connection.cursor() as cursor:
            cursor.execute(query, {"username": self.player.username})
            attachments = list(sql.objects(cursor))

        def formatter(att):
            return 'Price: %d -- For: %s -- %s -- weight: %d' % \
                   (att.price, att.attaches_to_name, att.name, att.weight)

        self.purchase_menu_loop(
            attachments, formatter,
            "None of the items you own have any attachments available, or you've already purchased"
            " all the available ones!")
Ejemplo n.º 12
0
    def get_inventory_stats(self):
        # Get the win rate by inventory (coalescing so that inventories that aren't used show up in the list)
        query = """
            SELECT 
                name, 
                coalesce(stats.kdr, 0) as kdr,  
                coalesce(stats.winrate, 0) as winrate, 
                coalesce(stats.games_played, 0) as games_played 
            FROM inventories
            LEFT JOIN (
                SELECT inventory_name,
                       round(sum(kills)::NUMERIC / sum(deaths)::NUMERIC, 2) as kdr,
                       round(
                                   (count(*) FILTER (WHERE game_sessions.winning_team = plays.team_number))::NUMERIC /
                                   count(*)::NUMERIC, 2
                           )                                                as winrate,
                       count(*)                                             AS games_played
                FROM plays
                         INNER JOIN game_sessions ON plays.gid = game_sessions.gid
                WHERE username = %(username)s
                GROUP BY inventory_name
            ) as stats ON inventories.name = stats.inventory_name
            WHERE username = %(username)s
            ORDER BY games_played DESC;
        """
        with self.connection.cursor() as cursor:
            cursor.execute(query, {"username": self.player.username})
            inventory_stats = list(sql.objects(cursor))

        overall_kdr = 0
        overall_winrate = 0
        total_games = 0

        for inventory_entry in inventory_stats:
            overall_kdr += inventory_entry.games_played * inventory_entry.kdr
            overall_winrate += inventory_entry.games_played * inventory_entry.winrate
            total_games += inventory_entry.games_played

        return inventory_stats, overall_kdr / total_games, overall_winrate / total_games, total_games
Ejemplo n.º 13
0
def main():
    with database.connect() as connection:
        with connection.cursor() as cursor:
            cursor.execute(
                "SELECT *, exp_requirement(level) as exp_requirement FROM players WHERE banned_date IS NULL "
                "ORDER BY username")

            players = list(sql.objects(cursor))

    try:
        print("Type q or Q at any time to exit the application.")
        # First step is to select a player
        player = prompts.select_from_list(
            players, [p.username for p in players],
            "Please pick a user from this list to play as")

        print("Welcome back %s!" % player.username)

        menu_item_descriptions = [
            flow.prompt_text for flow in flows.menu_items
        ]

        while True:
            print(end='\n\n')

            flow_class = prompts.select_from_list(
                flows.menu_items, menu_item_descriptions,
                "Please select something to do!")

            with database.connect() as connection:
                flow_object = flow_class(player, connection)
                flow_object.run()

                # Reload the player as data may have changed
                player = reload_player(player, connection)

    except prompts.QuitException:
        return
Ejemplo n.º 14
0
    def attachments(self):
        if 'attachments' in self.cache:
            return self.cache['attachments']

        with self.connection.cursor() as cursor:
            query = """
            SELECT items.id, items.name, attachments.attaches_to_id FROM inventory_contains
            INNER JOIN items 
              ON items.id = inventory_contains.item_id
            INNER JOIN attachments 
              ON items.id = attachments.item_id
            WHERE inventory_contains.username = %(username)s 
              AND inventory_contains.name = %(name)s
            """
            cursor.execute(
                query, {
                    "username": self.inventory_record.username,
                    "name": self.inventory_record.name
                })

            attachments = list(sql.objects(cursor))
            self.cache['attachments'] = attachments

            return attachments
Ejemplo n.º 15
0
    def weapons(self):
        if 'weapons' in self.cache:
            return self.cache['weapons']

        with self.connection.cursor() as cursor:
            query = """
            SELECT items.id, items.name, weapons.type FROM inventory_contains
            INNER JOIN items 
              ON items.id = inventory_contains.item_id
            INNER JOIN weapons 
              ON items.id = weapons.item_id
            WHERE inventory_contains.username = %(username)s 
              AND inventory_contains.name = %(name)s
            """
            cursor.execute(
                query, {
                    "username": self.inventory_record.username,
                    "name": self.inventory_record.name
                })

            weapons = list(sql.objects(cursor))
            self.cache['weapons'] = weapons

            return weapons
Ejemplo n.º 16
0
def reload_player(player, connection):
    query = "SELECT *, exp_requirement(level) as exp_requirement FROM players WHERE username=%(username)s"
    with connection.cursor() as cursor:
        cursor.execute(query, {"username": player.username})
        return next(sql.objects(cursor))
Ejemplo n.º 17
0
 def reload_player(self):
     with self.connection.cursor() as cursor:
         cursor.execute("SELECT * FROM players WHERE username=%(username)s",
                        {"username": self.player.username})
         self.player = next(sql.objects(cursor))
Ejemplo n.º 18
0
    def run(self):
        print()
        print("Simulating a game!")

        teams, player_inventories = self.select_teams_and_inventories()
        print(tabulate.tabulate(teams, headers=["Team1", "Team2"]))
        print()

        game_map = random.choice(MAPS)
        game_type = random.choice(GAME_TYPES)

        print("Playing %s on the map: %s" %
              (game_type.replace("-", " "), game_map))
        print()

        inventory = self.choose_inventory()
        player_inventories[self.player.username] = inventory

        game_session = self.initialize_game_session(teams, game_map, game_type,
                                                    player_inventories)
        kills, deaths, assists, winning_team = self.simulate_game_events(
            teams, game_session)

        self.update_player_kda(game_session, kills, deaths, assists)

        previous_level = self.player.level

        # Close out the game session using the close_game prepared statement.
        query = """
            SELECT * FROM close_game(%(gid)s, %(winning_team)s, %(game_end)s);
        """
        with self.connection.cursor() as cursor:
            cursor.execute(
                query, {
                    "gid": game_session.gid,
                    "winning_team": winning_team,
                    "game_end": game_session.start_time + timedelta(minutes=20)
                })
            leaderboard = list(sql.objects(cursor))

        print("\nFinal leaderboard:")
        for team, players in itertools.groupby(
                leaderboard, key=lambda player: player.team_number):
            print("Team %d" % team)

            table = [[
                i + 1, player.username, player.kills, player.deaths,
                player.assists, player.exp_gained
            ] for i, player in enumerate(players)]

            print(
                tabulate.tabulate(table,
                                  headers=[
                                      'Rank', 'Player', 'Kills', 'Deaths',
                                      'Assists', 'XP Gain'
                                  ]))
            print()

        self.connection.commit()

        with self.connection.cursor() as cursor:
            cursor.execute(
                "SELECT level, experience, exp_requirement(level) as req FROM players WHERE username=%(username)s",
                {"username": self.player.username})
            updated_pts = next(sql.objects(cursor))

        exp_we_gained = [
            p.exp_gained for p in leaderboard
            if p.username == self.player.username
        ][0]

        if updated_pts.level > previous_level:
            print("Congratulations, you've leveled up to %d!" %
                  updated_pts.level)
            print("You have %d/%d experience points to reach level %d" %
                  (updated_pts.experience, updated_pts.req,
                   updated_pts.level + 1))
        else:
            print(
                "You gained %d experience points, you now have %d/%d experience points required to reach level %d"
                % (exp_we_gained, updated_pts.experience, updated_pts.req,
                   updated_pts.level + 1))