Skip to content

Instantly share code, notes, and snippets.

@PurpleMyst
Created January 24, 2018 16:52
Show Gist options
  • Save PurpleMyst/363021b853fdb91e6c49e99975196e92 to your computer and use it in GitHub Desktop.
Save PurpleMyst/363021b853fdb91e6c49e99975196e92 to your computer and use it in GitHub Desktop.
A bot to play Jeopardy! in your favorite IRC channels.
#!/usr/bin/env python3
import json
import random
import curio
from nettirely import IrcBot, NO_SPLITTING
bot = IrcBot(state_path="jeopardy_state.json")
# The questions that the bot can ask, loaded at startup from "questions.json".
# http://skeeto.s3.amazonaws.com/share/JEOPARDY_QUESTIONS1.json.gz
questions = []
# We use a few global variables to keep some volatile state.
games = {}
@bot.on_command("!start", NO_SPLITTING)
async def start_game(self, sender, recipient, _args):
if recipient in games:
await self.send_privmsg(recipient,
f"{sender.nick}: Game is already running.")
return
games[recipient] = {}
await self.send_privmsg(recipient,
f"{sender.nick}: Game has been started!")
await curio.sleep(0.5)
await _ask_question(self, recipient)
@bot.on_command("!leaderboard", NO_SPLITTING)
@bot.on_command("!scoreboard", NO_SPLITTING)
async def print_leaderboard(self, sender, recipient, _args):
await self.send_privmsg(recipient,
"Here's the leaderboard:")
leaderboard = sorted(games[recipient].get("money", {}).items(),
key=lambda x: x[1], reverse=True)
for index, (user, money) in enumerate(leaderboard, start=1):
await self.send_privmsg(recipient,
f"{index}. {user} with ${money}")
await curio.sleep(1 / 10)
@bot.on_command("!stop", NO_SPLITTING)
async def stop_game(self, sender, recipient, _args):
if recipient not in games:
await self.send_privmsg(recipient,
f"{sender.nick}: Game is not running.")
return
await self.send_privmsg(recipient,
f"{sender.nick}: Game has been stopped!")
await print_leaderboard(self, sender, recipient, _args)
del games[recipient]
@bot.on_command("!skip", NO_SPLITTING)
async def skip_question(self, sender, recipient, _args):
if recipient not in games:
await self.send_privmsg(recipient,
f"{sender.nick}: Game is not running.")
return
await self.send_privmsg(recipient,
f"The answer was: {games[recipient]['question']['answer']}")
await self.send_privmsg(recipient,
"Skipping question...")
del games[recipient]
await curio.sleep(0.5)
await self.send_privmsg(recipient,
"Let's ask another one.")
await _ask_question(self, recipient)
async def _ask_question(self, channel):
question = random.choice(questions)
games.setdefault(channel, {})["question"] = question
await self.send_privmsg(channel, f"Category: {question['category']}")
await self.send_privmsg(channel, f"Reward: {question['value']}")
await self.send_privmsg(channel, f"Question: {question['question']}")
@bot.on_regexp("(?i)^w(?:hat|o)\s+is\s+(.+)")
@bot.on_command("!answer", NO_SPLITTING)
async def check_for_answer(self, sender, recipient, guess):
if recipient not in games:
return
elif "question" not in games[recipient]:
return
if hasattr(guess, "group"):
guess = guess.group(1)
game = games[recipient]
question = game["question"]
guess = guess.casefold().strip()
answer = question["answer"].casefold().strip()
if guess == answer:
moneys = game.setdefault("money", {})
money = moneys.get(sender.nick, 0) + int(question["value"][1:])
moneys[sender.nick] = money
await self.send_privmsg(recipient,
f"{sender.nick} has gotten the right answer! "
f"They now have ${money}.")
del game["question"]
await curio.sleep(1)
await _ask_question(self, recipient)
async def main():
async with curio.aopen("questions.json") as f:
with f.blocking() as sync_f:
questions.extend(json.load(sync_f))
await bot.connect("jeopardy8_bot", "chat.freenode.net", 6667)
await bot.join_channel("#8banana")
await bot.mainloop()
if __name__ == "__main__":
try:
curio.run(main)
except KeyboardInterrupt:
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment