コード例 #1
0
    def generate(width=20, height=10, treasures=5):
        """
        Returns a new random perfect maze with the given sizes.
        """
        m = Maze(width, height)
        m.randomize()

        cells = random.sample(m.cells[1:], treasures)
        for cell in cells:
            cell.treasure = True

        return m
コード例 #2
0
ファイル: werewolf.py プロジェクト: Garnet-0/IdleRPG
 async def choose_lovers(self) -> None:
     try:
         lovers = await self.choose_users(
             "Choose 2 lovers. You should not tell the town who the lovers are.",
             list_of_users=self.game.players,
             amount=2,
         )
     except asyncio.TimeoutError:
         lovers = random.sample(self.game.players, 2)
         await self.send("Timed out. Lovers will be chosen randomly.")
     for lover in lovers:
         lover.in_love = True
     await self.send(
         f"You've made **{lovers[0].user}** and **{lovers[1].user}** lovers."
     )
コード例 #3
0
    async def snowballfight(self, ctx, enemy: MemberConverter):
        _("""Make a snowball fights against another guild.""")
        if enemy is ctx.author:
            return await ctx.send(_("You may not fight yourself."))

        msg = await ctx.send(
            _("{enemy}, {author} has challenged you for an epic snowball fight! If"
              " you want to accept, react ⚔\n**IMPORTANT: This is very spammy, make"
              " sure you are using a dedicated channel!**").format(
                  enemy=enemy.mention, author=ctx.author.mention))

        def check(r, u):
            return (r.message.id == msg.id and u == enemy
                    and str(r.emoji) == "\U00002744")

        await msg.add_reaction("\U00002744")

        try:
            await self.bot.wait_for("reaction_add", check=check, timeout=60)
        except asyncio.TimeoutError:
            return await ctx.send(_("Timed out..."))
        team1 = [ctx.author]
        team2 = [enemy]

        def check1(msg):
            return (msg.content.startswith("snowballfight nominate")
                    and msg.author == ctx.author)

        def check2(msg):
            return (msg.content.startswith("snowballfight nominate")
                    and msg.author == enemy)

        await ctx.send(
            _("{author}, type `snowballfight nominate @user` to add ten of your"
              " comrades to the fight. You need 10 total!").format(
                  author=ctx.author.mention))
        while len(team1) < 10:
            try:
                msg = await self.bot.wait_for("message",
                                              check=check1,
                                              timeout=60)
            except asyncio.TimeoutError:
                return await ctx.send(_("Timed out..."))
            try:
                u = msg.mentions[0]
            except IndexError:
                continue
            if u in team1 or u in team1:
                await ctx.send(_("Taken!"))
            else:
                team1.append(u)
                await ctx.send(
                    _("{user} has been added to your team, {user2}.").format(
                        user=u.mention, user2=ctx.author.mention))
        await ctx.send(
            _("{enemy}, use `snowballfight nominate @user` to add ten of your"
              " comrades to the fight. You need 10 total!").format(
                  enemy=enemy.mention))
        while len(team2) < 10:
            try:
                msg = await self.bot.wait_for("message",
                                              check=check2,
                                              timeout=30)
            except asyncio.TimeoutError:
                return await ctx.send(_("Timed out..."))
            try:
                u = msg.mentions[0]
            except IndexError:
                continue
            if u in team2 or u in team1:
                await ctx.send(_("Taken!"))
            else:
                team2.append(u)
                await ctx.send(
                    _("{user} has been added to your team, {user2}.").format(
                        user=u.mention, user2=enemy.mention))
        points1 = 1
        points2 = 1
        while points1 < 10 and points2 < 10:
            t1 = (":black_large_square:" * (points1 - 1) + ":snowflake:" +
                  ":black_large_square:" * (10 - points1))
            t2 = (":black_large_square:" * (points2 - 1) + ":snowflake:" +
                  ":black_large_square:" * (10 - points2))
            await ctx.send(
                _("""
{author.mention}'s team vs {enemy.mention}'s team
{t1} - {author}
{t2} - {enemy}
Next round starts in 5 seconds!
""").format(author=ctx.author, enemy=enemy, t1=t1, t2=t2))
            await asyncio.sleep(5)
            game_mode = random.choice(["typeit", "maths", "hangman"])
            if game_mode == "typeit":
                w = random.sample(list(string.ascii_letters), 15)
                w.insert(random.randint(1, 14), "\u200b")
                word = "".join(w)
                real = word.replace("\u200b", "")

                def corr(msg):
                    return (msg.author in team1
                            or msg.author in team2) and msg.content == real

                await ctx.send(
                    _("It's word typing time! In 3 seconds, I will send a word."
                      " Whoever types it fastest gets one point!"))
                await asyncio.sleep(3)
                await ctx.send(f"`{word}`")
                try:
                    msg = await self.bot.wait_for("message",
                                                  check=corr,
                                                  timeout=45)
                except asyncio.TimeoutError:
                    return await ctx.send(
                        _("Noone managed to get it right, I'll cancel the fight!"
                          ))
                if msg.author in team1:
                    points1 += 1
                else:
                    points2 += 1
                await ctx.send(
                    _("{author} got it right!").format(
                        author=ctx.author.mention))
            elif game_mode == "maths":
                m = random.randint(1, 10)
                x = random.randint(1, 10)
                c = random.choice([2, 4, 5])
                d = random.randint(1, 100)
                res = (m * x) / c + d
                if int(res) == res:
                    res = str(int(res))
                else:
                    res = str(res)

                def corr(msg):
                    return (msg.author in team1
                            or msg.author in team2) and msg.content == res

                await ctx.send(
                    _("It's maths time! In 3 seconds, I'll send a simple maths task"
                      " to solve! Type the answer to get a point!"))
                await asyncio.sleep(3)
                await ctx.send(f"`({m} *\u200b {x}) \u200b/ {c} + \u200b{d}`")
                try:
                    msg = await self.bot.wait_for("message",
                                                  check=corr,
                                                  timeout=45)
                except asyncio.TimeoutError:
                    return await ctx.send(
                        _("Noone managed to get it right, I'll cancel the fight!"
                          ))
                if msg.author in team1:
                    points1 += 1
                else:
                    points2 += 1
                await ctx.send(
                    _("{user} got it right!").format(user=msg.author))
            elif game_mode == "hangman":
                word = random.choice(self.words).strip()

                def corr(msg):
                    return (msg.author in team1 or msg.author in team2) and (
                        msg.content == word or len(msg.content) == 1)

                disp = "_ " * len(word)
                guessed = []
                await ctx.send(
                    _("It's hangman time! In 3 seconds, I'll send a hangman-style"
                      " word and you will have to either send your full word as the"
                      " guess or a letter to check for!"))
                await asyncio.sleep(3)
                q = await ctx.send(f"`{disp}`")
                while True:
                    try:
                        msg = await self.bot.wait_for("message",
                                                      check=corr,
                                                      timeout=20)
                    except asyncio.TimeoutError:
                        return await ctx.send(
                            _("Noone participated, I'll cancel the fight!"))
                    if msg.content == word:
                        if msg.author in team1:
                            points1 += 1
                        else:
                            points2 += 1
                        await ctx.send(
                            _("{user} got it right!").format(user=msg.author))
                        break
                    else:
                        try:
                            await msg.delete()
                        except discord.Forbidden:
                            pass

                        if msg.content in guessed:
                            continue
                        if msg.content not in word:
                            continue
                        guessed.append(msg.content)
                        disp = " ".join(
                            [i if (i in guessed) else "_" for i in word])
                        await q.edit(content=f"`{disp}`")
        if points1 > points2:
            await ctx.send(
                _("Team 1 ({user}) won!").format(user=ctx.author.mention))
        else:
            await ctx.send(
                _("Team 2 ({user}) won!").format(user=enemy.mention))
コード例 #4
0
ファイル: __init__.py プロジェクト: Gelbpunkt/IdleRPG
    async def raidbattle(self,
                         ctx,
                         money: IntGreaterThan(-1) = 0,
                         enemy: discord.Member = None):
        _("""`[money]` - A whole number that can be 0 or greater; defaults to 0
            `[enemy]` - A user who has a profile; defaults to anyone

            Fight against another player while betting money.
            To decide the players' stats, their items, race and class bonuses and raidstats are evaluated.

            The money is removed from both players at the start of the battle. Once a winner has been decided, they will receive their money, plus the enemy's money.
            The battle is divided into rounds, in which a player attacks. The first round's attacker is chosen randomly, all other rounds the attacker is the last round's defender.

            The battle ends if one player's HP drops to 0 (winner decided), or if 5 minutes after the battle started pass (tie).
            In case of a tie, both players will get their money back.

            The battle's winner will receive a PvP win, which shows on their profile.
            (This command has a cooldown of 5 minutes)""")
        if enemy == ctx.author:
            return await ctx.send(_("You can't battle yourself."))
        if ctx.character_data["money"] < money:
            return await ctx.send(_("You are too poor."))

        await self.bot.pool.execute(
            'UPDATE profile SET "money"="money"-$1 WHERE "user"=$2;',
            money,
            ctx.author.id,
        )

        if not enemy:
            text = _("{author} seeks a raidbattle! The price is **${money}**."
                     ).format(author=ctx.author.mention, money=money)
        else:
            text = _(
                "{author} seeks a raidbattle with {enemy}! The price is **${money}**."
            ).format(author=ctx.author.mention,
                     enemy=enemy.mention,
                     money=money)

        async def check(user: discord.User) -> bool:
            return await has_money(self.bot, user.id, money)

        future = asyncio.Future()
        view = SingleJoinView(
            future,
            Button(
                style=ButtonStyle.primary,
                label=_("Join the raidbattle!"),
                emoji="\U00002694",
            ),
            allowed=enemy,
            prohibited=ctx.author,
            timeout=60,
            check=check,
            check_fail_message=_(
                "You don't have enough money to join the raidbattle."),
        )

        await ctx.send(text, view=view)

        try:
            enemy_ = await future
        except asyncio.TimeoutError:
            await self.bot.reset_cooldown(ctx)
            await self.bot.pool.execute(
                'UPDATE profile SET "money"="money"+$1 WHERE "user"=$2;',
                money,
                ctx.author.id,
            )
            return await ctx.send(
                _("Noone wanted to join your raidbattle, {author}!").format(
                    author=ctx.author.mention))

        await self.bot.pool.execute(
            'UPDATE profile SET "money"="money"-$1 WHERE "user"=$2;', money,
            enemy_.id)

        players = []

        async with self.bot.pool.acquire() as conn:
            for player in (ctx.author, enemy_):
                dmg, deff = await self.bot.get_raidstats(player, conn=conn)
                u = {"user": player, "hp": 250, "armor": deff, "damage": dmg}
                players.append(u)

        # players[0] is the author, players[1] is the enemy

        battle_log = deque(
            [(
                0,
                _("Raidbattle {p1} vs. {p2} started!").format(
                    p1=players[0]["user"], p2=players[1]["user"]),
            )],
            maxlen=3,
        )

        embed = discord.Embed(description=battle_log[0][1],
                              color=self.bot.config.game.primary_colour)

        log_message = await ctx.send(
            embed=embed)  # we'll edit this message later to avoid spam
        await asyncio.sleep(4)

        start = datetime.datetime.utcnow()
        attacker, defender = random.sample(
            players, k=2
        )  # decide a random attacker and defender for the first iteration

        while (players[0]["hp"] > 0 and players[1]["hp"] > 0
               and datetime.datetime.utcnow() <
               start + datetime.timedelta(minutes=5)):
            # this is where the fun begins
            dmg = (attacker["damage"] + Decimal(random.randint(0, 100)) -
                   defender["armor"])
            dmg = 1 if dmg <= 0 else dmg  # make sure no negative damage happens
            defender["hp"] -= dmg
            if defender["hp"] < 0:
                defender["hp"] = 0
            battle_log.append((
                battle_log[-1][0] + 1,
                _("{attacker} attacks! {defender} takes **{dmg}HP** damage.").
                format(
                    attacker=attacker["user"].mention,
                    defender=defender["user"].mention,
                    dmg=dmg,
                ),
            ))

            embed = discord.Embed(
                description=_(
                    "{p1} - {hp1} HP left\n{p2} - {hp2} HP left").format(
                        p1=players[0]["user"],
                        hp1=players[0]["hp"],
                        p2=players[1]["user"],
                        hp2=players[1]["hp"],
                    ),
                color=self.bot.config.game.primary_colour,
            )

            for line in battle_log:
                embed.add_field(
                    name=_("Action #{number}").format(number=line[0]),
                    value=line[1])

            await log_message.edit(embed=embed)
            await asyncio.sleep(4)
            attacker, defender = defender, attacker  # switch places

        players = sorted(players, key=lambda x: x["hp"])
        winner = players[1]["user"]
        looser = players[0]["user"]

        async with self.bot.pool.acquire() as conn:
            await conn.execute(
                'UPDATE profile SET "money"="money"+$1, "pvpwins"="pvpwins"+1 WHERE'
                ' "user"=$2;',
                money * 2,
                winner.id,
            )
            await self.bot.log_transaction(
                ctx,
                from_=looser.id,
                to=winner.id,
                subject="money",
                data={"Amount": money},
                conn=conn,
            )
        await ctx.send(
            _("{p1} won the raidbattle vs {p2}! Congratulations!").format(
                p1=winner.mention, p2=looser.mention))
コード例 #5
0
ファイル: __init__.py プロジェクト: alexshcer/idleRPG-DBot
 async def get_inputs(self):
     all_actions = [
         (
             _("Gather as much food as you can"),
             _("gathers as much food as they can"),
             None,
         ),
         (
             _("Grab a backpack and retreat"),
             _("grabs a backpack and retreats"),
             "leave",
         ),
         (_("Take a pistol and suicide"), _("gives themselves the bullet"),
          "leave"),
         (_("Ram a knife in your body"), _("commits suicide with a knife"),
          "leave"),
         (
             _("Run away from the Cornucopia"),
             _("runs away from the Cornucopia"),
             None,
         ),
         (
             _("Search for a pair of Explosives"),
             _("finds a bag full of explosives"),
             None,
         ),
         (_("Look for water"), _("finds a canteen full of water"), None),
         (
             _("Get a first aid kit"),
             _("clutches a first aid kit and runs away"),
             None,
         ),
         (
             _("Grab a backpack"),
             _("grabs a backpack, not realizing it is empty"),
             None,
         ),
         (_("Try to assault USER"), _("kills USER"), ("kill", "USER")),
         (
             _("Kill USER at the water"),
             _("assaults USER while they were drinking water at the river"),
             ("kill", "USER"),
         ),
         (
             _("Try to hide some landmines"),
             _("hides landmines at a few locations"),
             None,
         ),
         (_("Take a bath"), _("baths in the water and enjoys the silence"),
          None),
     ]
     team_actions = [
         (_("kill USER"), ("kill", "USER")),
         (_("grill at the fireplace and tell each other spooky stories"),
          None),
         (_("annoy USER"), "user"),
         (_("kill themselves by walking into a landmine"), "killall"),
         (_("have a small party and get drunk"), None),
         (_("watch animes together"), None),
         (_("enjoy the silence"), None),
         (_("attempt to kill USER but fail"), "user"),
         (_("watch a movie together"), "user"),
         (_("track down USER and kill them silently"), ("kill", "USER")),
     ]
     team_actions_2 = [
         (_("kill themselves by walking into a landmine"), "killall"),
         (_("decide they want out of here and commit suicide"), "killall"),
         (_("watch a movie together"), None),
         (_("dance YMCA together"), None),
         (_("sing songs together"), None),
         (_("have a nice romantic evening"), None),
         (_("watch the others being dumb"), None),
         (_("kiss in the moonlight"), None),
         (
             _("watch a movie together when USER suddenly gets shot by a stranger"
               ),
             ("killtogether", "USER"),
         ),
     ]
     user_actions = []
     roundtext = _("**Round {round}**")
     status = await self.ctx.send(roundtext.format(round=self.round),
                                  delete_after=60)
     killed_this_round = []
     for p in self.rand_chunks(self.players):
         if len(p) == 1:
             text = _("Letting {user} choose their action...").format(
                 user=p[0])
             try:
                 await status.edit(content=f"{status.content}\n{text}")
             except discord.errors.NotFound:
                 status = await self.ctx.send(
                     f"{roundtext.format(round=self.round)}\n{text}",
                     delete_after=60)
             actions = random.sample(all_actions, 3)
             possible_kills = [
                 item for item in self.players
                 if item not in killed_this_round and item != p[0]
             ]
             if len(possible_kills) > 0:
                 kill = random.choice(possible_kills)
                 okay = True
             else:
                 kill = random.choice(
                     [i for i in self.players if i != p[0]])
                 okay = False
             actions2 = []
             for a, b, c in actions:
                 if c == ("kill", "USER"):
                     actions2.append((
                         a.replace("USER", kill.name),
                         b.replace("USER", kill.name),
                         ("kill", kill),
                     ))
                 else:
                     actions2.append((a, b, c))
             actions_desc = [a[0] for a in actions2]
             try:
                 action = actions2[await self.ctx.bot.paginator.Choose(
                     entries=actions_desc,
                     return_index=True,
                     title=_("Choose an action"),
                 ).paginate(self.ctx, location=p[0])]
             except (
                     self.ctx.bot.paginator.NoChoice,
                     discord.Forbidden,
                     asyncio.TimeoutError,
             ):
                 await self.ctx.send(
                     _("I couldn't send a DM to {user}! Choosing random action..."
                       ).format(user=p[0]),
                     delete_after=30,
                 )
                 action = random.choice(actions2)
             if okay or (not okay and isinstance(action[2], tuple)):
                 user_actions.append((p[0], action[1]))
             else:
                 user_actions.append(
                     (p[0], _("attempts to kill {user} but fails").format(
                         user=kill)))
             if action[2]:
                 if action[2] == "leave":
                     killed_this_round.append(p[0])
                 else:
                     if okay:
                         killed_this_round.append(action[2][1])
             text = _("Done")
             try:
                 await status.edit(content=f"{status.content} {text}")
             except discord.errors.NotFound:
                 pass
         else:
             possible_kills = [
                 item for item in p if p not in killed_this_round
             ]
             if len(possible_kills) > 0:
                 target = random.choice(possible_kills)
             else:
                 target = None
             if len(p) > 2:
                 action = random.choice(team_actions)
             else:
                 action = random.choice(team_actions_2)
             users = [u for u in p if u != target]
             if not action[1]:
                 user_actions.append(
                     (nice_join([u.name for u in p]), action[0]))
             elif not target:  # fix
                 user_actions.append(
                     (nice_join([u.name for u in p]), _("do nothing.")))
             elif action[1] == "user":
                 user_actions.append((
                     nice_join([u.name for u in users]),
                     action[0].replace("USER", target.name),
                 ))
             elif action[1] == "killall":
                 user_actions.append(
                     (nice_join([u.name for u in p]), action[0]))
                 killed_this_round.extend(p)
             else:
                 if action[1][0] == "kill":
                     user_actions.append((
                         nice_join([u.name for u in users]),
                         action[0].replace("USER", target.name),
                     ))
                 elif action[1][0] == "killtogether":
                     user_actions.append((
                         nice_join([u.name for u in p]),
                         action[0].replace("USER", target.name),
                     ))
                 killed_this_round.append(target)
     await asyncio.sleep(2)
     for p in killed_this_round:
         try:
             self.players.remove(p)
         except ValueError:
             pass
     paginator = commands.Paginator(prefix="", suffix="")
     for u, a in user_actions:
         paginator.add_line(f"{u} {a}")
     for page in paginator.pages:
         await self.ctx.send(page, delete_after=60)
     self.round += 1
コード例 #6
0
ファイル: __init__.py プロジェクト: Garnet-0/IdleRPG
    async def snowballfight(self, ctx, enemy: MemberWithCharacter):
        _("""Make a snowball fights against another guild.""")
        if enemy is ctx.author:
            return await ctx.send(_("You may not fight yourself."))
        async with self.bot.pool.acquire() as conn:
            guild1, rank1 = await conn.fetchval(
                'SELECT (guild, guildrank) FROM profile WHERE "user"=$1;',
                ctx.author.id)
            guild2, rank2 = await conn.fetchval(
                'SELECT (guild, guildrank) FROM profile WHERE "user"=$1;',
                enemy.id)
            if rank2 == "Member":
                return await ctx.send(
                    _("The enemy must be an officer or higher."))
            guild1 = await conn.fetchrow('SELECT * FROM guild WHERE "id"=$1;',
                                         guild1)
            guild2 = await conn.fetchrow('SELECT * FROM guild WHERE "id"=$1;',
                                         guild2)
            guild1_members = [
                r["user"] for r in await conn.fetch(
                    'SELECT "user" FROM profile WHERE "guild"=$1;',
                    guild1["id"])
            ]
            guild2_members = [
                r["user"] for r in await conn.fetch(
                    'SELECT "user" FROM profile WHERE "guild"=$1;',
                    guild2["id"])
            ]

        msg = await ctx.send(
            _("{enemy}, {author} has challenged you for an epic snowball fight! If"
              " you want to accept, react ⚔\n**IMPORTANT: This is very spammy, make"
              " sure you are using a dedicated channel!**").format(
                  enemy=enemy.mention, author=ctx.author.mention))

        def check(r, u):
            return (r.message.id == msg.id and u == enemy
                    and str(r.emoji) == "\U00002744")

        await msg.add_reaction("\U00002744")

        try:
            await self.bot.wait_for("reaction_add", check=check, timeout=30)
        except asyncio.TimeoutError:
            return await ctx.send(_("Timed out..."))
        conv = commands.UserConverter()
        team1 = [ctx.author]
        team2 = [enemy]

        def check1(msg):
            return (msg.content.startswith("snowballfight nominate")
                    and msg.author == ctx.author)

        def check2(msg):
            return (msg.content.startswith("snowballfight nominate")
                    and msg.author == enemy)

        await ctx.send(
            _("{author}, type `snowballfight nominate @user` to add one of your guild"
              " members to the fight!").format(author=ctx.author.mention))
        while len(team1) == 1:
            try:
                msg = await self.bot.wait_for("message",
                                              check=check1,
                                              timeout=30)
            except asyncio.TimeoutError:
                return await ctx.send(_("Timed out..."))
            try:
                u = await conv.convert(ctx, msg.content.split()[-1])
            except commands.BadArgument:
                continue
            if u.id not in guild1_members:
                await ctx.send(_("Not one of your guild members..."))
            elif u in team1:
                await ctx.send(_("That's you!"))
            else:
                team1.append(u)
        await ctx.send(
            _("{enemy}, use `snowballfight nominate @user` to add one of your guild"
              " members to the fight!").format(enemy=enemy.mention))
        while len(team2) == 1:
            try:
                msg = await self.bot.wait_for("message",
                                              check=check2,
                                              timeout=30)
            except asyncio.TimeoutError:
                return await ctx.send(_("Timed out..."))
            try:
                u = await conv.convert(ctx, msg.content.split()[-1])
            except commands.BadArgument:
                continue
            if u.id not in guild2_members:
                await ctx.send(_("Not one of your guild members..."))
            elif u in team2:
                await ctx.send(_("That's you!"))
            else:
                team2.append(u)
        points1 = 1
        points2 = 1
        while points1 < 10 and points2 < 10:
            t1 = (":black_large_square:" * (points1 - 1) + ":snowflake:" +
                  ":black_large_square:" * (10 - points1))
            t2 = (":black_large_square:" * (points2 - 1) + ":snowflake:" +
                  ":black_large_square:" * (10 - points2))
            await ctx.send(
                _("""
{author.mention}'s team vs {enemy.mention}'s team
{t1} - {author}
{t2} - {enemy}
Next round starts in 5 seconds!
""").format(author=ctx.author, enemy=enemy, t1=t1, t2=t2))
            await asyncio.sleep(5)
            game_mode = random.choice(["typeit", "maths", "hangman"])
            if game_mode == "typeit":
                w = random.sample(string.ascii_letters, 15)
                w.insert(random.randint(1, 14), "\u200b")
                word = "".join(w)
                real = word.replace("\u200b", "")

                def corr(msg):
                    return (msg.author in team1
                            or msg.author in team2) and msg.content == real

                await ctx.send(
                    _("It's word typing time! In 3 seconds, I will send a word."
                      " Whoever types it fastest gets one point!"))
                await asyncio.sleep(3)
                await ctx.send(f"`{word}`")
                try:
                    msg = await self.bot.wait_for("message",
                                                  check=corr,
                                                  timeout=45)
                except asyncio.TimeoutError:
                    return await ctx.send(
                        _("Noone managed to get it right, I'll cancel the fight!"
                          ))
                if msg.author in team1:
                    points1 += 1
                else:
                    points2 += 1
                await ctx.send(
                    _("{author} got it right!").format(
                        author=ctx.author.mention))
            elif game_mode == "maths":
                m = random.randint(1, 20)
                x = random.randint(1, 30)
                c = random.choice([2, 4, 5])
                d = random.randint(1, 100)
                res = (m * x) / c + d
                if int(res) == res:
                    res = str(int(res))
                else:
                    res = str(res)

                def corr(msg):
                    return (msg.author in team1
                            or msg.author in team2) and msg.content == res

                await ctx.send(
                    _("It's maths time! In 3 seconds, I'll send a simple maths task"
                      " to solve! Type the answer to get a point!"))
                await asyncio.sleep(3)
                await ctx.send(f"`({m} * {x}) / {c} + {d}`")
                try:
                    msg = await self.bot.wait_for("message",
                                                  check=corr,
                                                  timeout=45)
                except asyncio.TimeoutError:
                    return await ctx.send(
                        _("Noone managed to get it right, I'll cancel the fight!"
                          ))
                if msg.author in team1:
                    points1 += 1
                else:
                    points2 += 1
                await ctx.send(
                    _("{user} got it right!").format(user=msg.author))
            elif game_mode == "hangman":
                word = random.choice(self.words).strip()

                def corr(msg):
                    return (msg.author in team1 or msg.author in team2) and (
                        msg.content == word or len(msg.content) == 1)

                disp = "_ " * len(word)
                guessed = []
                await ctx.send(
                    _("It's hangman time! In 3 seconds, I'll send a hangman-style"
                      " word and you will have to either send your full word as the"
                      " guess or a letter to check for!"))
                await asyncio.sleep(3)
                q = await ctx.send(f"`{disp}`")
                while True:
                    try:
                        msg = await self.bot.wait_for("message",
                                                      check=corr,
                                                      timeout=20)
                    except asyncio.TimeoutError:
                        return await ctx.send(
                            _("Noone participated, I'll cancel the fight!"))
                    if msg.content == word:
                        if msg.author in team1:
                            points1 += 1
                        else:
                            points2 += 1
                        await ctx.send(
                            _("{user} got it right!").format(user=msg.author))
                        break
                    else:
                        try:
                            await msg.delete()
                        except discord.Forbidden:
                            pass

                        if msg.content in guessed:
                            continue
                        if msg.content not in word:
                            continue
                        guessed.append(msg.content)
                        disp = " ".join(
                            [i if (i in guessed) else "_" for i in word])
                        await q.edit(content=f"`{disp}`")
        if points1 > points2:
            await ctx.send(
                _("Team 1 ({user}) won!").format(user=ctx.author.mention))
        else:
            await ctx.send(
                _("Team 2 ({user}) won!").format(user=enemy.mention))
コード例 #7
0
    def generate(self,
                 pos,
                 good_enough=None,
                 tries_limit=None,
                 subgroup=None,
                 basis=None):
        """Generate the parameters by finding good polynomials and building the parameters
        according to Proposition 8 & Remark 5 of [GW15].
        @pos - the reconstruction pos
        @good_enough - amount of subfield elements sent which is good enough for us.
                       if unset - the information theoretic best is taken (which might be impossible) 
        @tries_limit - amount of polynomial sets to try. If unset - number of tries is unlimited
        @subgroup - amount of points to randomly checks before calculating the bandwidth of the scheme
        @basis - optional specific basis of gf over subfield to use
        """
        pts = [p for p in self._pts]
        if pos not in pts:
            pts.append(pos)
        n = len(pts)
        t = self._t
        ext = self._gf.get_extension()

        # Set good enough to the lower bound of information needed - at least t parties, at least one element (in the big field)
        if good_enough is None:
            good_enough = -1
        good_enough = max(good_enough, t, ext)

        if tries_limit is None:
            tries_limit = -1

        # Set subgroup size for testing bandwidth
        # Only if bandwidth on subgroup seems to be better than current bandwidth we continue
        if subgroup is None:
            subgroup_fraction, subgroup_min = Config.GW_PARAMS_SUBGROUP_SIZE
            subgroup = int(ceil(n / subgroup_fraction))
            subgroup = max(subgroup, subgroup_min)
        subgroup = min(n - 1, subgroup)
        subgroup_factor = float(subgroup) / n

        # Choose our polynomials so their evaluation in @pos will be some predefined base
        # We don't care about this degree of freedom - as it only changes our polynomial by a multiplicative scalar factor
        if basis is not None:
            assert len(basis) == ext, "Invalid size of basis supplied"
            assert self._linear_independant(basis), "Invalid basis supplied"
        else:
            # Choose the monomial basis as default
            subf = self._gf.get_subfield()
            gf_x = self._gf([subf.zero(), subf.one()])
            basis = [x for x in powers(gf_x, ext)]

        pol_deg = n - t - 2
        best_bandwidth = (n * ext) + 1  # <- More than the worst case bandwidth
        best_subgroup_bandwidth = int(ceil(subgroup_factor * best_bandwidth))
        shuffled_pts = [p for p in pts]
        best_pols = None
        done = False
        try_i = 0
        try:
            while not done and try_i != tries_limit:
                try_i += 1

                # Choose a random polynomials with a sample of the points as roots,
                # while still making sure the evaluation in `pos` will yield the `basis`
                pols = []
                for b in basis:
                    roots = random.sample(
                        pts,
                        pol_deg + 1)  # Over sample by 1 in case @pos gets in
                    try:
                        roots.remove(pos)
                    except ValueError:
                        roots.pop(-1)  # Remove someone else (arbitrary)
                    pol = LinearFactors(self._gf, roots, constraint=(pos, b))
                    pols.append(pol)

                # Sum the degree of the vector spaces spanned by {p(pt) | p in pols} for each pt (except pos)
                # First start with `subgroup` random points and see if
                random.shuffle(shuffled_pts)
                pts_iter = iter(shuffled_pts)
                bandwidth = 0
                for i in xrange(subgroup):
                    pt = pts_iter.next()
                    if pt == pos:
                        pt = pts_iter.next()
                    bandwidth += self._degree(pol(pt) for pol in pols)

                if bandwidth > best_subgroup_bandwidth:
                    continue
                #else:
                bandwidth += sum(
                    self._degree(pol(pt) for pol in pols) for pt in pts_iter
                    if pt != pos)

                if bandwidth < best_bandwidth:
                    best_pols = pols
                    best_bandwidth = bandwidth
                    best_subgroup_bandwidth = int(
                        ceil(subgroup_factor * best_bandwidth))
                    log.info("Found scheme with %d bandwidth (%d%%)",
                             best_bandwidth,
                             int(ceil((100.0 * best_bandwidth) / (ext * n))))
                    if bandwidth <= good_enough:
                        done = True

        except KeyboardInterrupt:
            if best_pols is None:
                raise
            # Else - continue normally

        basis_elements = map(
            lambda pol: -pol(pos), best_pols
        )  #Notice: Negation added for correct result (mistake in [GW15] ?)
        dual = self._dual_basis(basis_elements)
        mus, mus_basis = self._calc_mus(pos, pts, best_pols)

        return dual, mus, mus_basis, best_bandwidth
コード例 #8
0
    async def raidbattle(self,
                         ctx,
                         money: IntGreaterThan(-1) = 0,
                         enemy: MemberConverter = None):
        _("""`[money]` - A whole number that can be 0 or greater; defaults to 0
            `[enemy]` - A user who has a profile; defaults to anyone

            Fight against another player while betting money.
            To decide the players' stats, their items, race and class bonuses and raidstats are evaluated.

            The money is removed from both players at the start of the battle. Once a winner has been decided, they will receive their money, plus the enemy's money.
            The battle is divided into rounds, in which a player attacks. The first round's attacker is chosen randomly, all other rounds the attacker is the last round's defender.

            The battle ends if one player's HP drops to 0 (winner decided), or if 5 minutes after the battle started pass (tie).
            In case of a tie, both players will get their money back.

            The battle's winner will receive a PvP win, which shows on their profile.
            (This command has a cooldown of 5 minutes)""")
        if enemy == ctx.author:
            return await ctx.send(_("You can't battle yourself."))
        if ctx.character_data["money"] < money:
            return await ctx.send(_("You are too poor."))

        await self.bot.pool.execute(
            'UPDATE profile SET money=money-$1 WHERE "user"=$2;',
            money,
            ctx.author.id,
        )

        if not enemy:
            msg = await ctx.send(
                _("{author} seeks a raidbattle! React with тЪФ now to duel them! The"
                  " price is **${money}**.").format(author=ctx.author.mention,
                                                    money=money))
        else:
            msg = await ctx.send(
                _("{author} seeks a raidbattle with {enemy}! React with тЪФ now to duel"
                  " them! The price is **${money}**.").format(
                      author=ctx.author.mention,
                      enemy=enemy.mention,
                      money=money))

        def check(r, u):
            if enemy:
                if u != enemy:
                    return False
            return (str(r.emoji) == "\U00002694" and r.message.id == msg.id
                    and u != ctx.author and not u.bot)

        await msg.add_reaction("\U00002694")
        seeking = True

        while seeking:
            try:
                _reaction, enemy_ = await self.bot.wait_for("reaction_add",
                                                            timeout=60,
                                                            check=check)
            except asyncio.TimeoutError:
                await self.bot.reset_cooldown(ctx)
                await self.bot.pool.execute(
                    'UPDATE profile SET money=money+$1 WHERE "user"=$2;',
                    money,
                    ctx.author.id,
                )
                return await ctx.send(
                    _("Noone wanted to join your raidbattle, {author}!").
                    format(author=ctx.author.mention))
            if await has_money(self.bot, enemy_.id, money):
                seeking = False
            else:
                enemy_ = None
                await ctx.send(
                    _("You don't have enough money to join the raidbattle."))

        await self.bot.pool.execute(
            'UPDATE profile SET money=money-$1 WHERE "user"=$2;', money,
            enemy_.id)

        players = []

        async with self.bot.pool.acquire() as conn:
            for player in (ctx.author, enemy_):
                dmg, deff = await self.bot.get_raidstats(player, conn=conn)
                u = {"user": player, "hp": 250, "armor": deff, "damage": dmg}
                players.append(u)

        # players[0] is the author, players[1] is the enemy

        battle_log = deque(
            [(
                0,
                _("Raidbattle {p1} vs. {p2} started!").format(
                    p1=players[0]["user"], p2=players[1]["user"]),
            )],
            maxlen=3,
        )

        embed = discord.Embed(description=battle_log[0][1],
                              color=self.bot.config.primary_colour)

        log_message = await ctx.send(
            embed=embed)  # we'll edit this message later to avoid spam
        await asyncio.sleep(4)

        start = datetime.datetime.utcnow()
        attacker, defender = random.sample(
            players, k=2
        )  # decide a random attacker and defender for the first iteration

        while (players[0]["hp"] > 0 and players[1]["hp"] > 0
               and datetime.datetime.utcnow() <
               start + datetime.timedelta(minutes=5)):
            # this is where the fun begins
            dmg = (attacker["damage"] + Decimal(random.randint(0, 100)) -
                   defender["armor"])
            dmg = 1 if dmg <= 0 else dmg  # make sure no negative damage happens
            defender["hp"] -= dmg
            if defender["hp"] < 0:
                defender["hp"] = 0
            battle_log.append((
                battle_log[-1][0] + 1,
                _("{attacker} attacks! {defender} takes **{dmg}HP** damage.").
                format(
                    attacker=attacker["user"].mention,
                    defender=defender["user"].mention,
                    dmg=dmg,
                ),
            ))

            embed = discord.Embed(
                description=_(
                    "{p1} - {hp1} HP left\n{p2} - {hp2} HP left").format(
                        p1=players[0]["user"],
                        hp1=players[0]["hp"],
                        p2=players[1]["user"],
                        hp2=players[1]["hp"],
                    ),
                color=self.bot.config.primary_colour,
            )

            for line in battle_log:
                embed.add_field(
                    name=_("Action #{number}").format(number=line[0]),
                    value=line[1])

            await log_message.edit(embed=embed)
            await asyncio.sleep(4)
            attacker, defender = defender, attacker  # switch places

        if players[1]["hp"] == 0:  # command author wins
            async with self.bot.pool.acquire() as conn:
                await conn.execute(
                    'UPDATE profile SET money=money+$1 WHERE "user"=$2;',
                    money * 2,
                    ctx.author.id,
                )
                await conn.execute(
                    'UPDATE profile SET pvpwins=pvpwins+1 WHERE "user"=$1;',
                    ctx.author.id,
                )
            await self.bot.log_transaction(
                ctx,
                from_=enemy_.id,
                to=ctx.author.id,
                subject="money",
                data={"Amount": money},
            )
            await ctx.send(
                _("{p1} won the raidbattle vs {p2}! Congratulations!").format(
                    p1=ctx.author.mention, p2=enemy_.mention))
        elif players[0]["hp"] == 0:  # enemy wins
            async with self.bot.pool.acquire() as conn:
                await conn.execute(
                    'UPDATE profile SET money=money+$1 WHERE "user"=$2;',
                    money * 2,
                    enemy_.id,
                )
                await conn.execute(
                    'UPDATE profile SET pvpwins=pvpwins+1 WHERE "user"=$1;',
                    enemy_.id)
            await self.bot.log_transaction(
                ctx,
                from_=ctx.author.id,
                to=enemy_.id,
                subject="money",
                data={"Amount": money},
            )
            await ctx.send(
                _("{p1} won the raidbattle vs {p2}! Congratulations!").format(
                    p1=enemy_.mention, p2=ctx.author.mention))

        else:  # timeout after 5 min
            async with self.bot.pool.acquire() as conn:
                await conn.execute(
                    'UPDATE profile SET money=money+$1 WHERE "user"=$2;',
                    money,
                    ctx.author.id,
                )
                await conn.execute(
                    'UPDATE profile SET money=money+$1 WHERE "user"=$2;',
                    money,
                    enemy_.id,
                )
            await ctx.send(_("Raidbattle took too long, aborting."))