didier/cogs/hangman.py

171 lines
6.0 KiB
Python

from decorators import help
from discord.ext import commands
from enums.help_categories import Category
from functions import checks
import json
import os
import random
def randomWord():
lineb = random.randrange(os.stat("files/words-dutch.txt").st_size)
with open("files/words-dutch.txt", encoding="latin-1") as file:
file.seek(lineb)
file.readline()
return file.readline().rstrip().upper()
class Hangman(commands.Cog):
def __init__(self, client):
self.client = client
# Don't allow any commands to work when locked
def cog_check(self, ctx):
return not self.client.locked
@commands.group(name="Hangman", aliases=["Hm"], usage="[Letter]*", case_insensitive=True, invoke_without_command=True)
@commands.check(checks.allowedChannels)
@help.Category(category=Category.Games)
async def hangman(self, ctx, letter=None):
if letter and letter.strip():
greek = "αβΓγΔδεζηΘθικΛλμνΞξΠπρΣσςτυΦφχΨψΩω"
if len(letter) == 1 and (letter.isalpha() or letter.isdigit()) and letter not in greek:
await self.guessLetter(ctx, letter)
else:
await ctx.send("Dit is geen geldige letter.")
return
await self.gameStatus(ctx)
async def guessLetter(self, ctx, letter):
with open("files/hangman.json", "r") as fp:
file = json.load(fp)
if letter.upper() in file["guessed"]:
await ctx.send("Deze letter is al eens geprobeerd.")
return
file["guessed"] += letter.upper()
if letter.upper() not in file["word"]:
file["guesses"] += 1
if int(file["guesses"] >= 9):
await ctx.send(self.endGame(file["word"]))
return
with open("files/hangman.json", "w") as fp:
json.dump(file, fp)
await self.gameStatus(ctx)
@hangman.command(name="Start", usage="[Woord]*")
async def start(self, ctx, *, word=None):
with open("files/hangman.json", "r") as fp:
file = json.load(fp)
# Can't play two games at once
if file["word"]:
await ctx.send("Er is al een spel bezig.")
return
if word:
if not all(letter.isalpha() or letter.isdigit() or letter in [" "] for letter in word):
await ctx.send("Dit is geen geldig woord.")
return
# Can only supply your own words in DM
if str(ctx.channel.type) != "private":
await ctx.message.delete()
await ctx.author.send("Het is niet slim om hangman games aan te maken waar iedereen het kan zien."
"\nGebruik dit commando hier zodat niemand het woord op voorhand weet.")
return
# Choose a random word when none were passed
if not word:
word = randomWord()
with open("files/hangman.json", "w") as fp:
json.dump({"guessed": [], "guesses": 0, "word": word}, fp)
await self.gameStatus(ctx)
async def gameStatus(self, ctx):
with open("files/hangman.json", "r") as fp:
file = json.load(fp)
if not file["word"]:
await ctx.send("Er is geen spel bezig.")
return
guessed = " ".join(letter for letter in file["guessed"] if letter not in file["word"])
filled = self.fillWord(file)
if filled.replace(" ", "") == file["word"]:
self.clearGame()
await ctx.send("**Het woord is geraden.**")
await ctx.message.add_reaction("")
return
await ctx.send("{}\n{}\nFoute letters: {}".format(filled, self.hangManString(file["guesses"]), guessed))
@hangman.command(name="Guess", usage="[Woord]")
async def guess(self, ctx, *, word=None):
if not word:
await ctx.send("Geef een woord op.")
return
with open("files/hangman.json", "r") as fp:
file = json.load(fp)
if not file["word"]:
await ctx.send("Er is geen spel bezig.")
return
if word.upper() == file["word"].upper():
self.clearGame()
await ctx.send("**Het woord is geraden**")
await ctx.message.add_reaction("")
else:
file["guesses"] += 1
await ctx.send("**{}** is een foute gok.".format(word))
await ctx.message.add_reaction("")
if file["guesses"] >= 9:
await ctx.send(self.endGame(file["word"]))
else:
with open("files/hangman.json", "w") as fp:
json.dump(file, fp)
await self.gameStatus(ctx)
# Create a representation of the word by filling in letters that have been guessed, and dots otherwise
def fillWord(self, file):
return "**" + " ".join(
letter if letter in file["guessed"] else "." if letter.isalpha() or letter.isdigit() else letter for letter
in file["word"]) + "**"
def endGame(self, word):
self.clearGame()
return self.hangManString(9) + "\nHet woord was **{}**.".format(word)
def clearGame(self):
with open("files/hangman.json", "w") as fp:
json.dump({"guessed": [], "guesses": 0, "word": ""}, fp)
def hangManString(self, number):
dic = {
0: "\n \n \n \n",
1: "\n \n \n \n ===",
2: "\n |\n |\n |\n ===",
3: "--+---+\n |\n |\n |\n ===",
4: "--+---+\n | O\n |\n |\n ===",
5: "--+---+\n | O\n | |\n |\n ===",
6: "--+---+\n | O\n | /|\n |\n ===",
7: "--+---+\n | O\n | /|\\\n |\n ===",
8: "--+---+\n | O\n | /|\\\n | /\n ===",
9: "--+---+\n | O\n | /|\\\n | / \\\n ===",
}
return dic[number]
def setup(client):
client.add_cog(Hangman(client))