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
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." )
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))
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))
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
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))
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
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."))