Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
464baa3
Initial Madlibs commit
DMFriends Oct 11, 2021
adff387
Add a JSON file with the story templates
DMFriends Oct 12, 2021
bbf4de8
Some changes to fix lint errors
DMFriends Oct 12, 2021
97b08ab
Fix lint errors in the templates JSON file
DMFriends Oct 12, 2021
6afc8d5
More changes to fix lint errors
DMFriends Oct 12, 2021
a744fdc
Fixing more lint errors
DMFriends Oct 12, 2021
bb567c4
More changes to fix lint failing
DMFriends Oct 12, 2021
cab6315
Implementing changes requested by Bluenix and TizzySaurus
DMFriends Oct 18, 2021
bdc58e5
Merge branch 'main' into madlibs
DMFriends Oct 18, 2021
8f0605e
Changing some variable names and added a while loop in the async func…
DMFriends Oct 18, 2021
60d8b7a
Merge branch 'madlibs' of https://github.com/DMFriends/sir-lancebot i…
DMFriends Oct 18, 2021
753b011
Implementing changes requested by TizzySaurus (part 1)
DMFriends Oct 21, 2021
df27b0f
Merge branch 'main' into madlibs
DMFriends Oct 21, 2021
21be3b5
Restructured the Python file back to bot/exts/fun
DMFriends Oct 21, 2021
702ec9c
Fixed a typo
DMFriends Oct 21, 2021
b186d94
Added send commands to the embeds
DMFriends Oct 21, 2021
9fa62cd
Made a small mistake in calling the "_load_templates" function
DMFriends Oct 22, 2021
f4779db
Merge branch 'main' into madlibs
DMFriends Oct 22, 2021
acced6a
Merge branch 'main' into madlibs
DMFriends Oct 22, 2021
74cd5c9
Deleted parentheses where it's not needed
DMFriends Oct 22, 2021
7a11fa6
Merge branch 'madlibs' of https://github.com/DMFriends/sir-lancebot i…
DMFriends Oct 22, 2021
1f1b224
Temporarily adding a send command so the bot prints out `self.templates`
DMFriends Oct 22, 2021
b9c6b36
Temporarily adding a print statement for `self.templates`... again
DMFriends Oct 22, 2021
23391c4
Merge branch 'main' into madlibs
DMFriends Oct 24, 2021
d8004cb
Changes to Madlibs
DMFriends Oct 26, 2021
e7f5d59
Removed unnecessary spaces in the story templates
DMFriends Oct 26, 2021
3a38136
Merge branch 'main' into madlibs
DMFriends Oct 27, 2021
63794c3
Merge branch 'main' into madlibs
DMFriends Oct 31, 2021
f2bec61
Merge branch 'main' into madlibs
DMFriends Nov 3, 2021
0087de3
Removing random 0's from the story templates in the JSON file
DMFriends Nov 6, 2021
8f218c9
More changes to Madlibs
DMFriends Nov 6, 2021
ad4e17a
Merge branch 'main' into madlibs
DMFriends Nov 6, 2021
c5c77dd
Move game presentation into command description
Bluenix2 Nov 6, 2021
72f228a
Add MadlibsTemplate to improve intellisense
Bluenix2 Nov 6, 2021
65398c0
Change single quotes to double quotes
Bluenix2 Nov 6, 2021
17765e8
Change visual indent to a hanging indent
Bluenix2 Nov 6, 2021
8f6a54e
Add author check to madlibs game
Bluenix2 Nov 6, 2021
b203222
Convert while-loop into equivalent for-loop
Bluenix2 Nov 6, 2021
a5a5ee6
Remove dead `clear_fields()` code
Bluenix2 Nov 6, 2021
a275c65
More changes to Madlibs
DMFriends Nov 14, 2021
c53d169
Merge branch 'main' into madlibs
DMFriends Nov 14, 2021
7eb869b
Change the async function declaration so the arguments are on one line
DMFriends Nov 14, 2021
6f170ef
Change madlibs_embed variable definition so the arguments of the Embe…
DMFriends Nov 14, 2021
fb71557
Switch from single quotes to double quotes when appending submitted w…
DMFriends Nov 14, 2021
2b14239
Add a space before the underscores instead of concatenating when appe…
DMFriends Nov 14, 2021
50925b3
Changes to the JSON file
DMFriends Nov 14, 2021
ead8438
Add a loading embed as requested by Shom770
DMFriends Nov 17, 2021
2edb2c3
Deleting the `sleep` function as requested by Bluenix
DMFriends Nov 18, 2021
7927da3
Update the timeout embed message as requested by Bluenix
DMFriends Nov 18, 2021
5f503bb
Change the title of the timeout embed to `choice(NEGATIVE_REPLIES)` a…
DMFriends Nov 18, 2021
6269a9e
Add an edit listener
DMFriends Nov 21, 2021
9a5afa8
Remove a temporary space
DMFriends Nov 21, 2021
ece5f0b
Add the "before" parameter to the edit listener function
DMFriends Nov 21, 2021
5d579bb
Update bot/exts/fun/madlibs.py
DMFriends Nov 22, 2021
321d7dd
Update bot/exts/fun/madlibs.py
DMFriends Nov 22, 2021
d180f9c
Add a closing parentheses to the list comprehension
DMFriends Nov 22, 2021
54cc263
Add an author check to the listener
DMFriends Nov 24, 2021
394ac71
Update the docstring for `madlibs_embed` as requested by Bluenix
DMFriends Nov 24, 2021
51cd36e
Add a comment to explain why we append the last line of the story twice
DMFriends Nov 24, 2021
1f45d77
Put comment before the line of code it describes
DMFriends Nov 25, 2021
9d44761
Fixed a small mistake in one of the story templates
DMFriends Nov 25, 2021
9fb5476
Changes to Madlibs
DMFriends Nov 25, 2021
3a3de5b
Switch the position of the check removal as requested by Bluenix
DMFriends Nov 29, 2021
1208e33
Changes to Madlibs story templates
DMFriends Dec 11, 2021
e8a6471
Small changes to Madlibs
DMFriends Dec 14, 2021
f17a016
Changes to Madlibs
DMFriends Dec 20, 2021
23a386c
Changes to Madlibs
DMFriends Jan 2, 2022
b145cf2
Merge branch 'main' into madlibs
ChrisLovering Jan 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions bot/exts/fun/madlibs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import json
from asyncio import TimeoutError
from pathlib import Path
from random import choice
from typing import TypedDict

import discord
from discord.ext import commands

from bot.bot import Bot
from bot.constants import Colours, NEGATIVE_REPLIES

TIMEOUT = 60.0


class MadlibsTemplate(TypedDict):
"""Structure of a template in the madlibs JSON file."""

title: str
blanks: list[str]
value: list[str]


class Madlibs(commands.Cog):
"""Cog for the Madlibs game."""

def __init__(self, bot: Bot):
self.bot = bot
self.templates = self._load_templates()
self.edited_content = {}
self.checks = set()

@staticmethod
def _load_templates() -> list[MadlibsTemplate]:
madlibs_stories = Path("bot/resources/fun/madlibs_templates.json")

with open(madlibs_stories) as file:
return json.load(file)

@staticmethod
def madlibs_embed(part_of_speech: str, number_of_inputs: int) -> discord.Embed:
"""Method to generate an embed with the game information."""
madlibs_embed = discord.Embed(title="Madlibs", color=Colours.python_blue)

madlibs_embed.add_field(
name="Enter a word that fits the given part of speech!",
value=f"Part of speech: {part_of_speech}\n\nMake sure not to spam, or you may get auto-muted!"
)

madlibs_embed.set_footer(text=f"Inputs remaining: {number_of_inputs}")

return madlibs_embed

@commands.Cog.listener()
async def on_message_edit(self, _: discord.Message, after: discord.Message) -> None:
"""A listener that checks for message edits from the user."""
for check in self.checks:
if check(after):
break
else:
return

self.edited_content[after.id] = after.content

@commands.command()
@commands.max_concurrency(1, per=commands.BucketType.user)
async def madlibs(self, ctx: commands.Context) -> None:
"""
Play Madlibs with the bot!

Madlibs is a game where the player is asked to enter a word that
fits a random part of speech (e.g. noun, adjective, verb, plural noun, etc.)
a random amount of times, depending on the story chosen by the bot at the beginning.
"""
random_template = choice(self.templates)

def author_check(message: discord.Message) -> bool:
return message.channel.id == ctx.channel.id and message.author.id == ctx.author.id

self.checks.add(author_check)

loading_embed = discord.Embed(
title="Madlibs", description="Loading your Madlibs game...", color=Colours.python_blue
)
original_message = await ctx.send(embed=loading_embed)

submitted_words = {}

for i, part_of_speech in enumerate(random_template["blanks"]):
inputs_left = len(random_template["blanks"]) - i

madlibs_embed = self.madlibs_embed(part_of_speech, inputs_left)
await original_message.edit(embed=madlibs_embed)

try:
message = await self.bot.wait_for(event="message", check=author_check, timeout=TIMEOUT)
except TimeoutError:
timeout_embed = discord.Embed(
title=choice(NEGATIVE_REPLIES),
description="Uh oh! You took too long to respond!",
color=Colours.soft_red
)

await ctx.send(ctx.author.mention, embed=timeout_embed)

for msg_id in submitted_words:
self.edited_content.pop(msg_id, submitted_words[msg_id])

self.checks.remove(author_check)

return

submitted_words[message.id] = message.content

blanks = [self.edited_content.pop(msg_id, submitted_words[msg_id]) for msg_id in submitted_words]

self.checks.remove(author_check)

story = []
for value, blank in zip(random_template["value"], blanks):
story.append(f"{value}__{blank}__")

# In each story template, there is always one more "value"
# (fragment from the story) than there are blanks (words that the player enters)
# so we need to compensate by appending the last line of the story again.
story.append(random_template["value"][-1])

story_embed = discord.Embed(
title=random_template["title"],
description="".join(story),
color=Colours.bright_green
)

story_embed.set_footer(text=f"Generated for {ctx.author}", icon_url=ctx.author.display_avatar.url)

await ctx.send(embed=story_embed)

@madlibs.error
async def handle_madlibs_error(self, ctx: commands.Context, error: commands.CommandError) -> None:
"""Error handler for the Madlibs command."""
if isinstance(error, commands.MaxConcurrencyReached):
await ctx.send("You are already playing Madlibs!")
error.handled = True


def setup(bot: Bot) -> None:
"""Load the Madlibs cog."""
bot.add_cog(Madlibs(bot))
135 changes: 135 additions & 0 deletions bot/resources/fun/madlibs_templates.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
[
{
"title": "How To Cross a Piranha-Infested River",
"blanks": ["foreign country", "adverb", "adjective", "animal",
"verb ending in 'ing'", "verb", "verb ending in 'ing'",
"adverb", "adjective", "a place", "type of liquid", "part of the body", "verb"],
"value": ["If you are traveling in ", " and find yourself having to cross a piranha-filled river, here's how to do it ",
": \n* Piranhas are more ", " during the day, so cross the river at night.\n* Avoid areas with netted ",
" traps--piranhas may be ", " there looking to ", " them!\n* When "," the river, swim ",
". You don't want to wake them up and make them ", "!\n* Whatever you do, if you have an open wound, try to find another way to get back to the ",
". Piranhas are attracted to fresh ", " and will most likely take a bite out of your ", " if you ", " in the water!"]
},
{
"title": "Three Little Pigs",
"blanks": ["adjective", "verb", "verb", "verb", "plural noun", "verb", "verb", "past tense verb", "plural noun", "adjective", "verb",
"plural noun", "noun", "verb", "past tense verb", "noun", "noun", "noun", "past tense verb", "adjective", "past tense verb",
"past tense verb", "noun", "past tense verb"],
"value": ["Once up a time, there were three ", " pigs. One day, their mother said, \"You are all grown up and must ", " on your own.\" So they left to ",
" their houses. The first little pig wanted only to ", " all day and quickly built his house out of ", ". The second little pig wanted to ",
" and ", " all day so he ", " his house with ", ". The third ", " pig knew the wolf lived nearby and worked hard to ", " his house out of ",
". One day, the wolf knocked on the first pig's ", ". \"Let me in or I'll ", " your house down!\" The pig didn't, so the wolf ", " down the ",
". The wolf knocked on the second pig's ", ". \"Let me in or I'll blow your ", " down!\" The pig didn't, so the wolf ",
" down the house. Then the wolf knocked on the third ", " pig's door. \"Let me in or I'll blow your house down!\" The little pig didn't so the wolf ",
" and ", ". He could not blow the house down. All the pigs went to live in the ", " house and they all ", " happily ever after."]
},
{
"title": "Talk Like a Pirate",
"blanks": ["noun", "adjective", "verb", "adverb", "noun", "adjective", "plural noun", "plural noun", "plural noun", "part of the body", "noun",
"noun", "noun", "noun", "part of the body"],
"value": ["Ye can always pretend to be a bloodthirsty ", ", threatening everyone by waving yer ", " sword in the air, but until ye learn to ",
" like a pirate, ye'll never be ", " accepted as an authentic ", ". So here's what ye do: Cleverly work into yer daily conversations ",
" pirate phrases such as \"Ahoy there, ", "Avast, ye ", ",\" and \"Shiver me ", ".\" Remember to drop all yer gs when ye say such words as sailin', spittin', and fightin'. This will give ye a/an ",
" start to being recognized as a swashbucklin' ", ". Once ye have the lingo down pat, it helps to wear a three-cornered ", " on yer head, stash a/an ",
" in yer pants, and keep a/an ", " perched atop yer ", ". Aye, now ye be a real pirate!"]
},
{
"title": "How to Date the Coolest Guy/Girl in School",
"blanks": ["plural noun", "adverb", "verb", "article of clothing", "body part", "adjective", "noun", "plural noun", "another body part", "plural noun",
"another body part", "noun", "noun", "verb ending in 'ing'", "adjective", "adjective", "verb"],
"value": ["It's simple. Turn the ", ". Make him/her want ", " to date you. Make sure you're always dressed to ", ". Each and every day, wear a/an ",
" that you know shows off your ", " to ", " advantage and make your ", " look like a million ", ". Even if the two of you make meaningful ",
" contact, don't admit it. No hugs or ", ". Just shake his/her ", " firmly. And remember, when he/she asks you out, even though a chill may run down your ",
" and you can't stop your ", " from ", ", just play it ", ". Take a long pause before answering in a very ", " voice. \"I'll have to ",
" it over.\""]
},
{
"title": "The Fun Park",
"blanks": ["adjective", "plural noun", "noun", "adverb", "number", "past tense verb", "adjective ending in -est", "past tense verb", "adverb", "adjective"],
"value": ["Today, my fabulous camp group went to a(an) ", " amusement park. It was a fun park with lots of cool ",
" and enjoyable play structures. When we got there, my kind counselor shouted loudly, \"Everybody off the ",
".\" My counselor handed out yellow tickets, and we scurried in. I was so excited! I couldn't figure out what exciting thing to do first. I saw a scary roller coaster I really liked so, I ",
" ran over to get in the long line that had about ", " people in it. when I finally got on the roller coaster I was ",
". In fact, I was so nervous my two knees were knocking together. This was the ", " ride I had ever been on! In about two minutes I heard the crank and grinding of the gears. Thats when the ride began! When I got to the bottom, I was a little ",
" but I was proud of myself. The rest of the day went ", ". It was a ", " day at the fun park."]
},
{
"title": "A Spooky Campfire Story",
"blanks": ["adjective", "adjective", "number", "adjective", "animal", "noun", "animal", "name", "verb", "adjective", "adjective"],
"value": ["Every summer, I get totally amped and ", " to go camping in the deep, ", " forests. It's good to get away from it all - but not too far, like getting lost! Last year, my friend and I went hiking and got lost for ",
" hour(s). We started off on a(n) ", " adventure, but we kept losing the trail. Night began to fall, and when we heard the howls of a ",
", we began to panic. It was getting darker and our flashlights were running on ", ". I'm sure glad my pet ", ", ", ", was with us. He is one gifted creature, because he was able to guide us back by ",
" the ", " s'mores by the campfire. This year, before setting off on an ", " journey, I'll be sure to have working flashlights - and of course, my gifted pet!"]
},
{
"title": "Weird News",
"blanks": ["noun", "place", "verb ending in ing", "noun", "name", "verb", "noun", "verb", "noun", "part of body", "type of liquid", "place", " past tense verb ", "foreign country", "verb", "noun", "past tense verb", "adjective", "verb", "noun", "plural noun"],
"value": ["A ", " in a ", " was arrested this morning after he was caught ", " in front of ", ". ", " had a history of ", ", but no one - not even his ", "- ever imagined he'd ", " with a ", " stuck in his ", ". After drinking a ", ", cops followed him to a ",
" where he reportedly ", " in the fry machine. Later, a woman from ", " was charged with a similar crime. But rather than ", " with a ", ", she ", " with a ", " dog. Either way, we imagine that after witnessing him ", " with a ", " there are probably a whole lot of ",
" that are going to need some therapy!"]
},
{
"title": "All About Vampires",
"blanks": ["adjective", "adjective", "body part", "verb ending in -ing", "verb", "verb", "verb", "noun", "verb", "verb", "body part", "verb (ending with -s)", "verb (ending with -s)", "verb", "noun", "body part", "adjective"],
"value": ["Vampires are ", "! They have ", " ", " for ", " blood. The sun can ", " vampires, so they only ", " at night and ", " during the day. Vampires also don't like ", " so ", " it or ", " it around your ",
" to keep them away. If a vampire ", "s a person and ", "s their blood, they become a vampire, too. The only way to ", " a vampire is with a ", " through the ", ", but ",
" luck getting close enough to one!"]
},
{
"title": "Our Cafeteria",
"blanks": ["adjective", "verb", "adjective", "noun", "verb", "adjective", "noun", "adjective", "adjective", "noun", "noun"],
"value": ["Our school cafeteria has really ", " food. Just thinking about it makes my stomach ", ". The spaghetti is ", " and tastes like ", ". One day, I swear one of my meatballs started to ",
"! The turkey tacos are totally ", " and look kind of like old ", ". My friend Dana actually likes the meatloaf, even though it's ", " and ", ". I call it \"Mystery Meatloaf\" and think it's really made out of ",
". My dad said he'd make my lunches, but the first day, he made me a sandwich out of ", " and peanut butter! I think I'd rather take my chances with the cafeteria!"]
},
{
"title": "Trip to the Park",
"blanks": ["adjective", "adjective", "noun", "adjective", "adjective", "verb", "verb", "verb", "adjective", "verb"],
"value": ["Yesterday, my friend and I went to the park. On our way to the ", " park, we saw big ", " balloons tied to a ", ". Once we got to the ", " park, the sky turned ",
". It started to ", " and ", ". My friend and I ", " all the way home. Tomorrow we will try to go to the ", " park again and hopefully it doesn't ", "!"]
},
{
"title": "A Scary Halloween Story",
"blanks": ["adjective", "name", "adjective", "noun", "verb", "animal", "adjective", "name", "adjective", "noun", "noun"],
"value": ["They say my school is haunted; my ", " friend ", " says they saw a ", " ", " floating at the end of the hall near the cafeteria. Some say if you ",
" down that hallway at night, you'll hear a ", " growling deeply. My ", " friend ", " saw a ", " ", " slithering under the tables once. I hope I never see any ",
" crawling; eating lunch there is scary enough!"]
},
{
"title": "Zombie Picnic",
"blanks": ["verb", "verb", "body part", "body part", "body part", "noun", "adjective", "type of liquid", "body part", "verb", "adjective", "body part", "body part"],
"value": ["If zombies had a picnic, what would they ", " to eat? Everybody knows zombies love to ", " ", ", but did you know they also enjoy ", " and even ",
"? The best ", " for a zombie picnic is when the moon is ", ". At least one zombie will bring ", " to drink, and it's not a picnic without ",
" with extra flesh on top. After eating, zombies will ", " ", " games like kick the ", " and ", " toss. What fun!"]
},
{
"title": "North Pole",
"blanks": ["plural noun", "adjective", "plural noun", "verb", "verb", "number", "noun", "adjective", "plural noun", "plural noun", "animal", "verb", "verb", "plural noun"],
"value": ["Santa, Mrs. Claus, and the ", " live at the North pole. The weather is always ", " there, but the ", " ", " toys for Santa to ",
" to children on Christmas, so holiday cheer lasts year-round there. There's no land at the North Pole; instead there is a ", "-inch thick sheet of ",
" there, ", " enough to hold Santa's Village! The ", " help load Santa's sleigh with ", ", and Santa's ", " ", " his sleigh on Christmas Eve to ",
" ", " to children around the entire world."]
},
{
"title": "Snowstorm!",
"blanks": ["plural noun", "adjective", "noun", "noun", "adjective", "adjective", "adjective", "noun", "noun", "adjective"],
"value": ["Weather plays an important part in our ", " everyday. What is weather, you ask? According to ", " scientists, who are known as meteorologists, weather is what the ",
" is like at any given time of the ", ". It doesn't matter if the air is ", " or ", ", it's all weather. When vapors in ", " clouds condense, we have ",
" and snow. A lot of ", " means a ", " snowstorm!"]
},
{
"title": "Learning About History",
"blanks": ["adjective", "noun", "nouns", "adjective", "nouns", "nouns", "animals", "nouns", "nouns", "number", "number", "nouns", "adjective", "nouns"],
"value": ["History is ", " because we learn about ", " and ", " that happened long ago. I can't believe people used to dress in ", " clothing and kids played with ",
" and ", " instead of video games. Also, before cars were invented, people actually rode ", "! People read ", " instead of computers and tablets, and sent messages via ",
" that took ", " days to arrive. I wonder how kids will view my life in ", " year(s); maybe they will ride flying cars to school and play with ", " and ", " ", "!"]
},
{
"title": "Star Wars",
"blanks": ["adjective", "noun", "adjective", "noun; place", "adjective", "adjective", "adjective", "adjective", "plural noun", "adjective", "plural noun", "plural noun", "adjective",
"noun", "verb (ending with -s)", "adjective", "verb", "plural noun; type of job", "adjective", "verb", "adjective"],
"value": ["Star Wars is a ", " ", " of ", " versus evil in a ", " far far away. There are ", " battles between ", " ships in ", " space and ", " duels with ", " called ",
" sabers. ", " called \"droids\" are helpers and ", " to the heroes. A ", " power called The ", " ", " people to do ", " things, like ", " ", " use The Force for the ",
" side and the Sith ", " it for the ", " side."]
}
]