From c41ab294e99eed46006c23a23c231636e6b4736b Mon Sep 17 00:00:00 2001 From: Irene Sheen Date: Sat, 9 May 2026 09:06:47 +0200 Subject: [PATCH] Add absurdify, dice, random commands, response commands --- src/quadnite_bot/command_registry.py | 11 ++++ src/quadnite_bot/commands/absurdify.py | 16 ++++++ src/quadnite_bot/commands/dice.py | 69 ++++++++++++++++++++++++++ src/quadnite_bot/commands/random.py | 53 ++++++++++++++++++++ src/quadnite_bot/commands/response.py | 19 +++++++ 5 files changed, 168 insertions(+) create mode 100644 src/quadnite_bot/commands/absurdify.py create mode 100644 src/quadnite_bot/commands/dice.py create mode 100644 src/quadnite_bot/commands/random.py create mode 100644 src/quadnite_bot/commands/response.py diff --git a/src/quadnite_bot/command_registry.py b/src/quadnite_bot/command_registry.py index cf2abc5..d3cc1ba 100644 --- a/src/quadnite_bot/command_registry.py +++ b/src/quadnite_bot/command_registry.py @@ -1,6 +1,17 @@ from quadnite_bot.command import CommandDispatcher +from quadnite_bot.commands.absurdify import AbsurdifyCommand +from quadnite_bot.commands.dice import DiceMatch from quadnite_bot.commands.echo import EchoCommand +from quadnite_bot.commands.random import CoinCommand, QuestionCommand, WordCommand, WordsCommand +from quadnite_bot.commands.response import ResponseCommands dispatcher = CommandDispatcher() dispatcher.add_command(EchoCommand()) +dispatcher.add_command(AbsurdifyCommand()) +dispatcher.add_command(DiceMatch()) +dispatcher.add_command(QuestionCommand()) +dispatcher.add_command(WordCommand()) +dispatcher.add_command(WordsCommand()) +dispatcher.add_command(CoinCommand()) +dispatcher.add_command(ResponseCommands()) diff --git a/src/quadnite_bot/commands/absurdify.py b/src/quadnite_bot/commands/absurdify.py new file mode 100644 index 0000000..467a170 --- /dev/null +++ b/src/quadnite_bot/commands/absurdify.py @@ -0,0 +1,16 @@ +import random + +from deltachat2 import NewMsgEvent + +from quadnite_bot.command import Command, Context + +def _absurdify(text): + return "".join( + random.choice([char.upper(), char.lower()]) for char in text + ) + +class AbsurdifyCommand(Command): + command = "absurdify" + + def process_event(self, ctx: Context, event: NewMsgEvent) -> None: + ctx.reply(_absurdify(ctx.params)) diff --git a/src/quadnite_bot/commands/dice.py b/src/quadnite_bot/commands/dice.py new file mode 100644 index 0000000..cbd0ebd --- /dev/null +++ b/src/quadnite_bot/commands/dice.py @@ -0,0 +1,69 @@ +import random +import re +import operator + +from deltachat2 import NewMsgEvent +from quadnite_bot.command import Command, Context + + +class DiceMatch(Command): + regex = re.compile( + r"""^ + /? # optional slash at beginning + (\d*)d(\d+) # num of dice + num of side + (\s*(kh|kl)\s*(\d+))? # keep highest / lowest + (\s*([-+><]|>=|<=)\s*(\d+))? # modifier for sum / count successes + $""", + re.I | re.VERBOSE, + ) + + def process_event(self, ctx: Context, event: NewMsgEvent) -> None: + if not ctx.match: + return + num_dice = int(ctx.match.group(1) or 1) + dice_sides = int(ctx.match.group(2)) + if num_dice > 50: + ctx.reply("Maximum of 50 dice allowed") + + if dice_sides > 1000: + ctx.reply("Number of sides must be 1000 or lower") + rolls = [random.randint(1, dice_sides) for _ in range(num_dice)] + + message = "\n".join( + f"You rolled a D{dice_sides} and got a {roll}" for roll in rolls + ) + message += "\n\n" + + keep = ctx.match.group(4) + if keep: + keep_count = int(ctx.match.group(5)) + rolls = sorted(rolls, reverse=keep=="kh")[:keep_count] + + modifier = ctx.match.group(7) + modifier_value = ctx.match.group(8) + if modifier_value: + modifier_value = int(modifier_value) + else: + modifier_value = 0 + if modifier in [None, "+", "-"]: + total = sum(rolls) + if modifier == "+": + total += modifier_value + elif modifier == "-": + total -= modifier_value + message += f"Total = {total}" + elif modifier in [">", "<", "<=", ">="]: + successes = 0 + op_map = { + ">": operator.gt, + "<": operator.lt, + ">=": operator.ge, + "<=": operator.le, + } + for roll in rolls: + if op_map[modifier](roll, modifier_value): + successes += 1 + + message += f"You got {successes} successes." + + ctx.reply(message) diff --git a/src/quadnite_bot/commands/random.py b/src/quadnite_bot/commands/random.py new file mode 100644 index 0000000..77cdf94 --- /dev/null +++ b/src/quadnite_bot/commands/random.py @@ -0,0 +1,53 @@ +from pathlib import Path +import random + +from deltachat2 import NewMsgEvent + +from quadnite_bot.command import Command, Context + + +class BaseRandomCommand(Command): + filename: str + def __init__(self): + file = Path(__file__).resolve().parent.parent / "static" / self.filename + with open(file) as f: + self.options = [line.strip() for line in f.readlines()] + + def process_event(self, ctx: Context, event: NewMsgEvent) -> None: + ctx.reply(random.choice(self.options)) + + +class QuestionCommand(BaseRandomCommand): + filename = "questions.txt" + command = "question" + + +class WordCommand(BaseRandomCommand): + filename = "words.txt" + command = "word" + + +class WordsCommand(BaseRandomCommand): + filename = "words.txt" + command = "words" + + def process_event(self, ctx: Context, event: NewMsgEvent) -> None: + count = 10 + if ctx.args: + try: + count = int(ctx.args[0]) + except ValueError: + ctx.reply(f"{ctx.args[0]!r} is not a number.") + return + + if count > 50: + count = 50 + ctx.reply("Number too high. Limiting to 50.") + + ctx.reply("\n".join(random.choices(self.options, k=count))) + + +class CoinCommand(BaseRandomCommand): + command = 'coin' + def __init__(self): + self.options = ['Heads', 'Tails'] diff --git a/src/quadnite_bot/commands/response.py b/src/quadnite_bot/commands/response.py new file mode 100644 index 0000000..b638d67 --- /dev/null +++ b/src/quadnite_bot/commands/response.py @@ -0,0 +1,19 @@ +import random + +from deltachat2 import NewMsgEvent +from quadnite_bot.command import Command, Context + + +class ResponseCommands(Command): + commands = ["is", "are", "can", "will", "shall", "was", "do", "does", "did", "should"] + def process_event(self, ctx: Context, event: NewMsgEvent) -> None: + ctx.reply( + random.choice( + random.choice( + [ + ["Yes", "Yep", "Yeah", "Yus", "Ja", "Ya", "Aye", "Ay", "Oui"], + ["No", "Nopes", "Nu", "Nah", "Nein", "Naw", "Nay", "Yesn't"], + ] + ) + ) + )