Refactor profile generation in modern.py to improve SVG card rendering, including enhanced stats presentation and avatar handling. Update pyproject.toml to remove unnecessary dependencies, streamlining project requirements.
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run
This commit is contained in:
parent
58b7e586d6
commit
df23ae0fbc
4 changed files with 4817 additions and 0 deletions
6
hangman/__init__.py
Normal file
6
hangman/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
from .hangman import Hangman
|
||||
|
||||
__red_end_user_data_statement__ = 'This cog does not store user data.'
|
||||
|
||||
async def setup(bot):
|
||||
await bot.add_cog(Hangman(bot))
|
4554
hangman/data/words.txt
Normal file
4554
hangman/data/words.txt
Normal file
File diff suppressed because it is too large
Load diff
245
hangman/hangman.py
Normal file
245
hangman/hangman.py
Normal file
|
@ -0,0 +1,245 @@
|
|||
import discord
|
||||
from redbot.core.data_manager import bundled_data_path
|
||||
from redbot.core.data_manager import cog_data_path
|
||||
from redbot.core import commands
|
||||
from redbot.core import Config
|
||||
from redbot.core import checks
|
||||
from random import randint
|
||||
import asyncio, os
|
||||
|
||||
|
||||
class Hangman(commands.Cog):
|
||||
"""Play hangman with the bot."""
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, identifier=7345167902)
|
||||
self.config.register_guild(
|
||||
fp = str(bundled_data_path(self) / 'words.txt'),
|
||||
doEdit = True
|
||||
)
|
||||
self.man = [
|
||||
(
|
||||
' ___ \n'
|
||||
' | | \n'
|
||||
' | O \n'
|
||||
' | \n'
|
||||
' | \n'
|
||||
' | \n'
|
||||
' | \n'
|
||||
), (
|
||||
' ___ \n'
|
||||
' | | \n'
|
||||
' | O \n'
|
||||
' | | \n'
|
||||
' | | \n'
|
||||
' | \n'
|
||||
' | \n'
|
||||
), (
|
||||
' ___ \n'
|
||||
' | | \n'
|
||||
' | O \n'
|
||||
' | \\| \n'
|
||||
' | | \n'
|
||||
' | \n'
|
||||
' | \n'
|
||||
), (
|
||||
' ___ \n'
|
||||
' | | \n'
|
||||
' | O \n'
|
||||
' | \\|/ \n'
|
||||
' | | \n'
|
||||
' | \n'
|
||||
' | \n'
|
||||
), (
|
||||
' ___ \n'
|
||||
' | | \n'
|
||||
' | O \n'
|
||||
' | \\|/ \n'
|
||||
' | | \n'
|
||||
' | / \n'
|
||||
' | \n'
|
||||
), (
|
||||
' ___ \n'
|
||||
' | | \n'
|
||||
' | O \n'
|
||||
' | \\|/ \n'
|
||||
' | | \n'
|
||||
' | / \\ \n'
|
||||
' | \n'
|
||||
), (
|
||||
' ___ \n'
|
||||
' | | \n'
|
||||
' | X \n'
|
||||
' | \\|/ \n'
|
||||
' | | \n'
|
||||
' | / \\ \n'
|
||||
' | \n'
|
||||
)
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def _get_message(word, guessed):
|
||||
"""Returns a string of the guessing text."""
|
||||
p = ''
|
||||
for l in word:
|
||||
if l not in 'abcdefghijklmnopqrstuvwxyz': #auto print non letter characters
|
||||
p += l + ' '
|
||||
elif l in guessed: #print already guessed characters
|
||||
p += l + ' '
|
||||
else:
|
||||
p += '_ '
|
||||
p += ' ('
|
||||
for l in guessed:
|
||||
if l not in word:
|
||||
p += l #add the incorrect guessed letters
|
||||
p += ')'
|
||||
return p
|
||||
|
||||
@commands.command()
|
||||
async def hangman(self, ctx):
|
||||
"""Play hangman with the bot."""
|
||||
if ctx.guild is None: #default vars in pms
|
||||
fp = str(bundled_data_path(self) / 'words.txt')
|
||||
doEdit = False #cant delete messages in pms
|
||||
else: #server specific vars
|
||||
fp = await self.config.guild(ctx.guild).fp()
|
||||
doEdit = await self.config.guild(ctx.guild).doEdit()
|
||||
try:
|
||||
f = open(fp)
|
||||
except FileNotFoundError:
|
||||
await ctx.send('Your wordlist was not found, using the default wordlist.')
|
||||
f = open(str(bundled_data_path(self) / 'words.txt'))
|
||||
wordlist = [line.strip().lower() for line in f]
|
||||
word = wordlist[randint(0,len(wordlist)-1)] #pick and format random word
|
||||
guessed = ''
|
||||
fails = 0
|
||||
game = True
|
||||
err = 0
|
||||
boardmsg = None
|
||||
check = lambda m: (
|
||||
m.channel == ctx.message.channel
|
||||
and m.author == ctx.message.author
|
||||
and len(m.content) == 1
|
||||
and m.content.lower() in 'abcdefghijklmnopqrstuvwxyz'
|
||||
)
|
||||
while game:
|
||||
p = self._get_message(word, guessed)
|
||||
p = f'```{self.man[fails]}\n{p}```'
|
||||
if err == 1:
|
||||
p += 'You already guessed that letter.\n'
|
||||
if boardmsg is None or not doEdit:
|
||||
boardmsg = await ctx.send(p+'Guess:')
|
||||
else:
|
||||
await boardmsg.edit(content=str(p+'Guess:'))
|
||||
try:
|
||||
umsg = await self.bot.wait_for('message', check=check, timeout=60)
|
||||
except asyncio.TimeoutError:
|
||||
return await ctx.send(
|
||||
f'Canceling selection. You took too long.\nThe word was {word}.'
|
||||
)
|
||||
t = umsg.content.lower()
|
||||
if doEdit:
|
||||
await asyncio.sleep(.2)
|
||||
try:
|
||||
await umsg.delete()
|
||||
except (discord.errors.Forbidden, discord.errors.NotFound):
|
||||
pass
|
||||
if t in guessed:
|
||||
err = 1
|
||||
continue
|
||||
err = 0
|
||||
guessed += t
|
||||
if t not in word:
|
||||
fails += 1
|
||||
if fails == 6: #too many fails
|
||||
p = self._get_message(word, guessed)
|
||||
p = f'```{self.man[fails]}\n{p}```Game Over\nThe word was {word}.'
|
||||
if doEdit:
|
||||
await boardmsg.edit(content=p)
|
||||
else:
|
||||
await ctx.send(p)
|
||||
game = False
|
||||
continue
|
||||
#guessed entire word
|
||||
if not (set('abcdefghijklmnopqrstuvwxyz') & set(word)) - set(guessed):
|
||||
p = self._get_message(word, guessed)
|
||||
p = f'```{self.man[fails]}\n{p}```You win!\nThe word was {word}.'
|
||||
if doEdit:
|
||||
await boardmsg.edit(content=p)
|
||||
else:
|
||||
await ctx.send(p)
|
||||
game = False
|
||||
|
||||
@commands.guild_only()
|
||||
@checks.guildowner()
|
||||
@commands.group()
|
||||
async def hangmanset(self, ctx):
|
||||
"""Config options for hangman."""
|
||||
pass
|
||||
|
||||
@hangmanset.group(invoke_without_command=True)
|
||||
async def wordlist(self, ctx, value: str):
|
||||
"""
|
||||
Change the wordlist used.
|
||||
|
||||
Extra wordlists can be put in the data folder.
|
||||
Wordlists are a .txt file with every new line being a new word.
|
||||
This value is server specific.
|
||||
"""
|
||||
wordlists = [p.resolve() for p in cog_data_path(self).glob("*.txt")]
|
||||
try:
|
||||
fp = next(p for p in wordlists if p.stem == value)
|
||||
await self.config.guild(ctx.guild).fp.set(str(fp))
|
||||
await ctx.send(f'The wordlist is now set to `{value}`.')
|
||||
except StopIteration:
|
||||
await ctx.send(f'Wordlist `{value}` not found.')
|
||||
|
||||
@wordlist.command()
|
||||
async def default(self, ctx):
|
||||
"""Set the wordlist to the default list."""
|
||||
fp = str(bundled_data_path(self) / 'words.txt')
|
||||
await self.config.guild(ctx.guild).fp.set(fp)
|
||||
await ctx.send('The wordlist is now set to the default list.')
|
||||
|
||||
@wordlist.command()
|
||||
async def list(self, ctx):
|
||||
"""List available wordlists."""
|
||||
wordlists = [p.resolve().stem for p in cog_data_path(self).glob("*.txt")]
|
||||
if wordlists == []:
|
||||
return await ctx.send('You do not have any wordlists.')
|
||||
msg = '\n'.join(wordlists).strip()
|
||||
await ctx.send(f'Available wordlists:```\n{msg}```')
|
||||
|
||||
@wordlist.command()
|
||||
async def current(self, ctx):
|
||||
"""Show the current wordlist."""
|
||||
v = await self.config.guild(ctx.guild).fp()
|
||||
if str(v) == str(bundled_data_path(self) / 'words.txt'):
|
||||
await ctx.send('The wordlist is set to the default list.')
|
||||
else:
|
||||
await ctx.send(f'The wordlist is set to `{str(v)[str(v).find("Hangman")+8:-4]}`.')
|
||||
|
||||
@hangmanset.command()
|
||||
async def edit(self, ctx, value: bool=None):
|
||||
"""
|
||||
Set if hangman messages should be one edited message or many individual messages.
|
||||
|
||||
Defaults to True.
|
||||
This value is server specific.
|
||||
"""
|
||||
if value is None:
|
||||
v = await self.config.guild(ctx.guild).doEdit()
|
||||
if v:
|
||||
await ctx.send('Games are currently being played on a single, edited message.')
|
||||
else:
|
||||
await ctx.send('Games are currently being played on multiple messages.')
|
||||
else:
|
||||
await self.config.guild(ctx.guild).doEdit.set(value)
|
||||
if value:
|
||||
await ctx.send('Games will now be played on a single, edited message.')
|
||||
else:
|
||||
await ctx.send('Games will now be played on multiple messages.')
|
||||
|
||||
async def red_delete_data_for_user(self, **kwargs):
|
||||
"""Nothing to delete."""
|
||||
return
|
12
hangman/info.json
Normal file
12
hangman/info.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"author" : ["Flame442"],
|
||||
"install_msg" : "Thanks for installing hangman. Use `[p]hangman` to play.\nThis cog comes with bundled data.",
|
||||
"name" : "Hangman",
|
||||
"short" : "Play hangman with the bot.",
|
||||
"requirements" : [],
|
||||
"description" : "Play hangman, guessing a random word from the bot. By default, a list of english nouns is used when picking the word, but a custom list can be configured by the bot owner. Run [p]hangman to play!",
|
||||
"tags" : ["fun", "games", "hangman"],
|
||||
"min_bot_version": "3.5.0.dev1",
|
||||
"min_python_version": [3, 6, 0],
|
||||
"end_user_data_statement": "This cog does not store user data."
|
||||
}
|
Loading…
Add table
Reference in a new issue