✨
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -13,306 +13,306 @@ from gwendolyn_old.exceptions import GameNotInDatabase
|
||||
from gwendolyn_old.utils import encode_id
|
||||
|
||||
class GameBase():
|
||||
"""The base class for the games."""
|
||||
"""The base class for the games."""
|
||||
|
||||
def __init__(self, bot, game_name: int, drawer):
|
||||
"""Initialize the class."""
|
||||
self.bot = bot
|
||||
self.long_strings = self.bot.long_strings
|
||||
self.resources = "gwendolyn/resources/games/"
|
||||
self.game_name = game_name
|
||||
self.draw = drawer(bot, self)
|
||||
def __init__(self, bot, game_name: int, drawer):
|
||||
"""Initialize the class."""
|
||||
self.bot = bot
|
||||
self.long_strings = self.bot.long_strings
|
||||
self.resources = "gwendolyn/resources/games/"
|
||||
self.game_name = game_name
|
||||
self.draw = drawer(bot, self)
|
||||
|
||||
def _get_action_rows(self, buttons: list[tuple[str, list]]):
|
||||
self.bot.log("Generation action rows")
|
||||
button_objects = []
|
||||
for label, data, style in buttons:
|
||||
custom_id = encode_id([self.game_name] + data)
|
||||
button_objects.append(Button(
|
||||
style=style,
|
||||
label=label,
|
||||
custom_id=custom_id
|
||||
))
|
||||
def _get_action_rows(self, buttons: list[tuple[str, list]]):
|
||||
self.bot.log("Generation action rows")
|
||||
button_objects = []
|
||||
for label, data, style in buttons:
|
||||
custom_id = encode_id([self.game_name] + data)
|
||||
button_objects.append(Button(
|
||||
style=style,
|
||||
label=label,
|
||||
custom_id=custom_id
|
||||
))
|
||||
|
||||
action_rows = []
|
||||
for i in range(((len(button_objects)-1)//5)+1):
|
||||
action_rows.append(ActionRow(*button_objects[i*5:i*5+5]))
|
||||
action_rows = []
|
||||
for i in range(((len(button_objects)-1)//5)+1):
|
||||
action_rows.append(ActionRow(*button_objects[i*5:i*5+5]))
|
||||
|
||||
return action_rows
|
||||
return action_rows
|
||||
|
||||
async def _send_image(self, channel: Messageable,
|
||||
buttons: list[tuple[str, list]] = None, delete=True):
|
||||
self.draw.draw(str(channel.id))
|
||||
file_path = f"{self.resources}images/{self.game_name}{channel.id}.png"
|
||||
old_image = await channel.send(
|
||||
file=File(file_path), delete_after=120 if delete else None)
|
||||
async def _send_image(self, channel: Messageable,
|
||||
buttons: list[tuple[str, list]] = None, delete=True):
|
||||
self.draw.draw(str(channel.id))
|
||||
file_path = f"{self.resources}images/{self.game_name}{channel.id}.png"
|
||||
old_image = await channel.send(
|
||||
file=File(file_path), delete_after=120 if delete else None)
|
||||
|
||||
if buttons is not None and len(buttons) < 25:
|
||||
await old_image.edit(components = self._get_action_rows(buttons))
|
||||
if buttons is not None and len(buttons) < 25:
|
||||
await old_image.edit(components = self._get_action_rows(buttons))
|
||||
|
||||
return old_image
|
||||
return old_image
|
||||
|
||||
class DatabaseGame(GameBase):
|
||||
"""The base class for the games."""
|
||||
"""The base class for the games."""
|
||||
|
||||
def __init__(self, bot, game_name, drawer):
|
||||
"""Initialize the class."""
|
||||
super().__init__(bot, game_name, drawer)
|
||||
self.database = self.bot.database
|
||||
self.old_images_path = f"{self.resources}old_images/{self.game_name}"
|
||||
def __init__(self, bot, game_name, drawer):
|
||||
"""Initialize the class."""
|
||||
super().__init__(bot, game_name, drawer)
|
||||
self.database = self.bot.database
|
||||
self.old_images_path = f"{self.resources}old_images/{self.game_name}"
|
||||
|
||||
def access_document(self, channel: str, collection_name: str="games",
|
||||
raise_missing_error: bool=True):
|
||||
collection = self.bot.database[f"{self.game_name} {collection_name}"]
|
||||
game = collection.find_one({"_id": channel})
|
||||
if game is None and raise_missing_error:
|
||||
raise GameNotInDatabase(self.game_name, channel)
|
||||
def access_document(self, channel: str, collection_name: str="games",
|
||||
raise_missing_error: bool=True):
|
||||
collection = self.bot.database[f"{self.game_name} {collection_name}"]
|
||||
game = collection.find_one({"_id": channel})
|
||||
if game is None and raise_missing_error:
|
||||
raise GameNotInDatabase(self.game_name, channel)
|
||||
|
||||
return game
|
||||
return game
|
||||
|
||||
def _test_document(self, channel: str, collection_name: str="games"):
|
||||
collection = self.bot.database[f"{self.game_name} {collection_name}"]
|
||||
game = collection.find_one({"_id": channel})
|
||||
return game is not None
|
||||
def _test_document(self, channel: str, collection_name: str="games"):
|
||||
collection = self.bot.database[f"{self.game_name} {collection_name}"]
|
||||
game = collection.find_one({"_id": channel})
|
||||
return game is not None
|
||||
|
||||
def _update_document(self, channel: str, updater: dict,
|
||||
collection_name: str="games"):
|
||||
self.database[f"{self.game_name} {collection_name}"].update_one(
|
||||
{"_id": channel},
|
||||
updater,
|
||||
upsert=True
|
||||
)
|
||||
def _update_document(self, channel: str, updater: dict,
|
||||
collection_name: str="games"):
|
||||
self.database[f"{self.game_name} {collection_name}"].update_one(
|
||||
{"_id": channel},
|
||||
updater,
|
||||
upsert=True
|
||||
)
|
||||
|
||||
def _delete_document(self, channel: str, collection_name: str="games"):
|
||||
self.database[f"{self.game_name} {collection_name}"].delete_one(
|
||||
{"_id": channel}
|
||||
)
|
||||
def _delete_document(self, channel: str, collection_name: str="games"):
|
||||
self.database[f"{self.game_name} {collection_name}"].delete_one(
|
||||
{"_id": channel}
|
||||
)
|
||||
|
||||
def _insert_document(self, data: dict, collection_name: str="games"):
|
||||
self.database[f"{self.game_name} {collection_name}"].insert_one(data)
|
||||
def _insert_document(self, data: dict, collection_name: str="games"):
|
||||
self.database[f"{self.game_name} {collection_name}"].insert_one(data)
|
||||
|
||||
async def _delete_old_image(self, channel: Messageable):
|
||||
with open(self.old_images_path + str(channel.id), "r") as file_pointer:
|
||||
old_image = await channel.fetch_message(int(file_pointer.read()))
|
||||
async def _delete_old_image(self, channel: Messageable):
|
||||
with open(self.old_images_path + str(channel.id), "r") as file_pointer:
|
||||
old_image = await channel.fetch_message(int(file_pointer.read()))
|
||||
|
||||
await old_image.delete()
|
||||
await old_image.delete()
|
||||
|
||||
async def _send_image(self, channel: Messageable,
|
||||
buttons: list[tuple[str, list]] = None, delete=True):
|
||||
old_image = await super()._send_image(channel, buttons, delete)
|
||||
with open(self.old_images_path + str(channel.id), "w") as file_pointer:
|
||||
file_pointer.write(str(old_image.id))
|
||||
async def _send_image(self, channel: Messageable,
|
||||
buttons: list[tuple[str, list]] = None, delete=True):
|
||||
old_image = await super()._send_image(channel, buttons, delete)
|
||||
with open(self.old_images_path + str(channel.id), "w") as file_pointer:
|
||||
file_pointer.write(str(old_image.id))
|
||||
|
||||
async def _start_new(self, channel: Messageable, new_game: dict,
|
||||
buttons: list[tuple[str, list]] = None,
|
||||
delete = True):
|
||||
new_game['_id'] = str(channel.id)
|
||||
self._insert_document(new_game)
|
||||
await self._send_image(channel, buttons, delete)
|
||||
async def _start_new(self, channel: Messageable, new_game: dict,
|
||||
buttons: list[tuple[str, list]] = None,
|
||||
delete = True):
|
||||
new_game['_id'] = str(channel.id)
|
||||
self._insert_document(new_game)
|
||||
await self._send_image(channel, buttons, delete)
|
||||
|
||||
async def _end_game(self, channel: Messageable):
|
||||
await self._delete_old_image(channel)
|
||||
await self._send_image(channel, delete=False)
|
||||
self._delete_document(str(channel.id))
|
||||
async def _end_game(self, channel: Messageable):
|
||||
await self._delete_old_image(channel)
|
||||
await self._send_image(channel, delete=False)
|
||||
self._delete_document(str(channel.id))
|
||||
|
||||
|
||||
class CardGame(DatabaseGame):
|
||||
"""The class for card games."""
|
||||
def __init__(self, bot, game_name, drawer, deck_used):
|
||||
"""Initialize the class."""
|
||||
super().__init__(bot, game_name, drawer)
|
||||
self.decks_used = deck_used
|
||||
"""The class for card games."""
|
||||
def __init__(self, bot, game_name, drawer, deck_used):
|
||||
"""Initialize the class."""
|
||||
super().__init__(bot, game_name, drawer)
|
||||
self.decks_used = deck_used
|
||||
|
||||
def _shuffle_cards(self, channel: str):
|
||||
self.bot.log(f"Shuffling cards for {self.game_name}")
|
||||
with open(f"{self.resources}deck_of_cards.txt", "r") as file_pointer:
|
||||
deck = file_pointer.read()
|
||||
def _shuffle_cards(self, channel: str):
|
||||
self.bot.log(f"Shuffling cards for {self.game_name}")
|
||||
with open(f"{self.resources}deck_of_cards.txt", "r") as file_pointer:
|
||||
deck = file_pointer.read()
|
||||
|
||||
all_decks = deck.split("\n") * self.decks_used
|
||||
random.shuffle(all_decks)
|
||||
all_decks = deck.split("\n") * self.decks_used
|
||||
random.shuffle(all_decks)
|
||||
|
||||
self._update_document(
|
||||
channel,
|
||||
{"$set": {"_id": channel, "cards": all_decks}},
|
||||
"cards"
|
||||
)
|
||||
self._update_document(
|
||||
channel,
|
||||
{"$set": {"_id": channel, "cards": all_decks}},
|
||||
"cards"
|
||||
)
|
||||
|
||||
def _draw_card(self, channel: str):
|
||||
"""
|
||||
Draw a card from the stack.
|
||||
def _draw_card(self, channel: str):
|
||||
"""
|
||||
Draw a card from the stack.
|
||||
|
||||
*Parameters*
|
||||
------------
|
||||
channel: str
|
||||
The id of the channel the card is drawn in.
|
||||
"""
|
||||
self.bot.log("drawing a card")
|
||||
*Parameters*
|
||||
------------
|
||||
channel: str
|
||||
The id of the channel the card is drawn in.
|
||||
"""
|
||||
self.bot.log("drawing a card")
|
||||
|
||||
drawn_card = self.access_document(channel, "cards")["cards"][0]
|
||||
self._update_document(channel, {"$pop": {"cards": -1}}, "cards")
|
||||
drawn_card = self.access_document(channel, "cards")["cards"][0]
|
||||
self._update_document(channel, {"$pop": {"cards": -1}}, "cards")
|
||||
|
||||
return drawn_card
|
||||
return drawn_card
|
||||
|
||||
class BoardGame(GameBase):
|
||||
async def _test_opponent(self, ctx: IntCont, opponent: Union[int, User]):
|
||||
if isinstance(opponent, int):
|
||||
# Opponent is Gwendolyn
|
||||
if opponent in range(1, 6):
|
||||
difficulty = int(opponent)
|
||||
difficulty_text = f" with difficulty {difficulty}"
|
||||
opponent = self.bot.user.id
|
||||
else:
|
||||
await ctx.send("Difficulty doesn't exist")
|
||||
self.bot.log("They challenged a difficulty that doesn't exist")
|
||||
return False
|
||||
elif isinstance(opponent, User):
|
||||
if opponent.bot:
|
||||
# User has challenged a bot
|
||||
if opponent == self.bot.user:
|
||||
# It was Gwendolyn
|
||||
difficulty = 3
|
||||
difficulty_text = f" with difficulty {difficulty}"
|
||||
opponent = self.bot.user.id
|
||||
else:
|
||||
await ctx.send("You can't challenge a bot!")
|
||||
self.bot.log("They tried to challenge a bot")
|
||||
return False
|
||||
else:
|
||||
# Opponent is another player
|
||||
if ctx.author != opponent:
|
||||
opponent = opponent.id
|
||||
difficulty = 5
|
||||
difficulty_text = ""
|
||||
else:
|
||||
await ctx.send("You can't play against yourself")
|
||||
self.bot.log("They tried to play against themself")
|
||||
return False
|
||||
async def _test_opponent(self, ctx: IntCont, opponent: Union[int, User]):
|
||||
if isinstance(opponent, int):
|
||||
# Opponent is Gwendolyn
|
||||
if opponent in range(1, 6):
|
||||
difficulty = int(opponent)
|
||||
difficulty_text = f" with difficulty {difficulty}"
|
||||
opponent = self.bot.user.id
|
||||
else:
|
||||
await ctx.send("Difficulty doesn't exist")
|
||||
self.bot.log("They challenged a difficulty that doesn't exist")
|
||||
return False
|
||||
elif isinstance(opponent, User):
|
||||
if opponent.bot:
|
||||
# User has challenged a bot
|
||||
if opponent == self.bot.user:
|
||||
# It was Gwendolyn
|
||||
difficulty = 3
|
||||
difficulty_text = f" with difficulty {difficulty}"
|
||||
opponent = self.bot.user.id
|
||||
else:
|
||||
await ctx.send("You can't challenge a bot!")
|
||||
self.bot.log("They tried to challenge a bot")
|
||||
return False
|
||||
else:
|
||||
# Opponent is another player
|
||||
if ctx.author != opponent:
|
||||
opponent = opponent.id
|
||||
difficulty = 5
|
||||
difficulty_text = ""
|
||||
else:
|
||||
await ctx.send("You can't play against yourself")
|
||||
self.bot.log("They tried to play against themself")
|
||||
return False
|
||||
|
||||
return opponent, (difficulty, difficulty_text)
|
||||
return opponent, (difficulty, difficulty_text)
|
||||
|
||||
class BaseDrawer():
|
||||
"""Class for drawing games."""
|
||||
def __init__(self, bot, game: GameBase):
|
||||
self.bot = bot
|
||||
self.game = game
|
||||
self.fonts_path = "gwendolyn/resources/fonts/"
|
||||
self.font_name = "futura-bold"
|
||||
"""Class for drawing games."""
|
||||
def __init__(self, bot, game: GameBase):
|
||||
self.bot = bot
|
||||
self.game = game
|
||||
self.fonts_path = "gwendolyn/resources/fonts/"
|
||||
self.font_name = "futura-bold"
|
||||
|
||||
self.resources = game.resources
|
||||
game_name = game.game_name
|
||||
self.default_image = f"{self.resources}default_images/{game_name}.png"
|
||||
self.default_size = None
|
||||
self.default_color = None
|
||||
self.images_path = f"{self.resources}images/{game_name}"
|
||||
self.resources = game.resources
|
||||
game_name = game.game_name
|
||||
self.default_image = f"{self.resources}default_images/{game_name}.png"
|
||||
self.default_size = None
|
||||
self.default_color = None
|
||||
self.images_path = f"{self.resources}images/{game_name}"
|
||||
|
||||
def _get_size(self, game: dict):
|
||||
return self.default_size
|
||||
def _get_size(self, game: dict):
|
||||
return self.default_size
|
||||
|
||||
def _draw_image(self, game: dict, image: Image.Image):
|
||||
pass
|
||||
def _draw_image(self, game: dict, image: Image.Image):
|
||||
pass
|
||||
|
||||
def draw(self, channel: str):
|
||||
game = self.game.access_document(channel)
|
||||
if self.default_image is not None:
|
||||
image = Image.open(self.default_image)
|
||||
else:
|
||||
image = Image.new("RGB", self._get_size(game), self.default_color)
|
||||
self._draw_image(game, image)
|
||||
self._save_image(image, channel)
|
||||
def draw(self, channel: str):
|
||||
game = self.game.access_document(channel)
|
||||
if self.default_image is not None:
|
||||
image = Image.open(self.default_image)
|
||||
else:
|
||||
image = Image.new("RGB", self._get_size(game), self.default_color)
|
||||
self._draw_image(game, image)
|
||||
self._save_image(image, channel)
|
||||
|
||||
def _get_font(self, size: int, font_name: str = None):
|
||||
if font_name is None:
|
||||
font_name = self.font_name
|
||||
return ImageFont.truetype(f"{self.fonts_path}{font_name}.ttf", size)
|
||||
def _get_font(self, size: int, font_name: str = None):
|
||||
if font_name is None:
|
||||
font_name = self.font_name
|
||||
return ImageFont.truetype(f"{self.fonts_path}{font_name}.ttf", size)
|
||||
|
||||
def _adjust_font(self, max_font_size: int, text: str, max_text_size: int,
|
||||
font_name: str = None):
|
||||
font_size = max_font_size
|
||||
font = self._get_font(font_size, font_name)
|
||||
text_width = font.getsize(text)[0]
|
||||
def _adjust_font(self, max_font_size: int, text: str, max_text_size: int,
|
||||
font_name: str = None):
|
||||
font_size = max_font_size
|
||||
font = self._get_font(font_size, font_name)
|
||||
text_width = font.getsize(text)[0]
|
||||
|
||||
while text_width > max_text_size:
|
||||
font_size -= 1
|
||||
font = self._get_font(font_size, font_name)
|
||||
text_width = font.getsize(text)[0]
|
||||
while text_width > max_text_size:
|
||||
font_size -= 1
|
||||
font = self._get_font(font_size, font_name)
|
||||
text_width = font.getsize(text)[0]
|
||||
|
||||
return font, font_size
|
||||
return font, font_size
|
||||
|
||||
def _save_image(self, image: Image.Image, channel: str):
|
||||
self.bot.log("Saving image")
|
||||
image.save(f"{self.images_path}{channel}.png")
|
||||
def _save_image(self, image: Image.Image, channel: str):
|
||||
self.bot.log("Saving image")
|
||||
image.save(f"{self.images_path}{channel}.png")
|
||||
|
||||
def _draw_shadow_text(self, text: str, colors: list[tuple[int, int, int]],
|
||||
font_size: int):
|
||||
font = self._get_font(font_size)
|
||||
offset = font_size//20
|
||||
shadow_offset = font_size//10
|
||||
def _draw_shadow_text(self, text: str, colors: list[tuple[int, int, int]],
|
||||
font_size: int):
|
||||
font = self._get_font(font_size)
|
||||
offset = font_size//20
|
||||
shadow_offset = font_size//10
|
||||
|
||||
text_size = list(font.getsize(text))
|
||||
text_size[0] += 1 + (offset * 2)
|
||||
text_size[1] += 1 + (offset * 2) + shadow_offset
|
||||
text_size = list(font.getsize(text))
|
||||
text_size[0] += 1 + (offset * 2)
|
||||
text_size[1] += 1 + (offset * 2) + shadow_offset
|
||||
|
||||
image = Image.new("RGBA", tuple(text_size), (0, 0, 0, 0))
|
||||
text_image = ImageDraw.Draw(image)
|
||||
image = Image.new("RGBA", tuple(text_size), (0, 0, 0, 0))
|
||||
text_image = ImageDraw.Draw(image)
|
||||
|
||||
for color_index, color in enumerate(colors[:-1]):
|
||||
color_offset = offset//(color_index+1)
|
||||
if color_index == 0:
|
||||
color_shadow_offset = shadow_offset
|
||||
else:
|
||||
color_shadow_offset = 0
|
||||
for color_index, color in enumerate(colors[:-1]):
|
||||
color_offset = offset//(color_index+1)
|
||||
if color_index == 0:
|
||||
color_shadow_offset = shadow_offset
|
||||
else:
|
||||
color_shadow_offset = 0
|
||||
|
||||
for i in range(4):
|
||||
x_pos = [-1,1][i % 2] * color_offset
|
||||
y_pos = [-1,1][(i//2) % 2] * color_offset + color_shadow_offset
|
||||
position = (offset + x_pos, offset + y_pos)
|
||||
text_image.text(position, text, fill=color, font=font)
|
||||
for i in range(4):
|
||||
x_pos = [-1,1][i % 2] * color_offset
|
||||
y_pos = [-1,1][(i//2) % 2] * color_offset + color_shadow_offset
|
||||
position = (offset + x_pos, offset + y_pos)
|
||||
text_image.text(position, text, fill=color, font=font)
|
||||
|
||||
text_image.text((offset, offset), text, fill=colors[-1], font=font)
|
||||
text_image.text((offset, offset), text, fill=colors[-1], font=font)
|
||||
|
||||
return image
|
||||
return image
|
||||
|
||||
class CardDrawer(BaseDrawer):
|
||||
def __init__(self, bot, game: GameBase):
|
||||
super().__init__(bot, game)
|
||||
self.cards_path = f"{self.resources}cards/"
|
||||
def __init__(self, bot, game: GameBase):
|
||||
super().__init__(bot, game)
|
||||
self.cards_path = f"{self.resources}cards/"
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
self.CARD_WIDTH = 691
|
||||
self.CARD_HEIGHT = 1065
|
||||
# pylint: disable=invalid-name
|
||||
self.CARD_WIDTH = 691
|
||||
self.CARD_HEIGHT = 1065
|
||||
|
||||
self.CARD_BORDER = 100
|
||||
self.CARD_OFFSET = 125
|
||||
# pylint: enable=invalid-name
|
||||
self.CARD_BORDER = 100
|
||||
self.CARD_OFFSET = 125
|
||||
# pylint: enable=invalid-name
|
||||
|
||||
def _set_card_size(self, wanted_card_width: int):
|
||||
ratio = wanted_card_width / self.CARD_WIDTH
|
||||
self.CARD_WIDTH = wanted_card_width
|
||||
self.CARD_HEIGHT = int(self.CARD_HEIGHT * ratio)
|
||||
self.CARD_BORDER = int(self.CARD_BORDER * ratio)
|
||||
self.CARD_OFFSET = int(self.CARD_OFFSET * ratio)
|
||||
def _set_card_size(self, wanted_card_width: int):
|
||||
ratio = wanted_card_width / self.CARD_WIDTH
|
||||
self.CARD_WIDTH = wanted_card_width
|
||||
self.CARD_HEIGHT = int(self.CARD_HEIGHT * ratio)
|
||||
self.CARD_BORDER = int(self.CARD_BORDER * ratio)
|
||||
self.CARD_OFFSET = int(self.CARD_OFFSET * ratio)
|
||||
|
||||
def _draw_cards(self, hand: list[str], hidden_cards: int = 0):
|
||||
image_width = (self.CARD_BORDER * 2) + self.CARD_WIDTH
|
||||
image_width += (self.CARD_OFFSET * (len(hand)-1))
|
||||
image_size = (image_width, (self.CARD_BORDER * 2) + self.CARD_HEIGHT)
|
||||
background = Image.new("RGBA", image_size, (0, 0, 0, 0))
|
||||
def _draw_cards(self, hand: list[str], hidden_cards: int = 0):
|
||||
image_width = (self.CARD_BORDER * 2) + self.CARD_WIDTH
|
||||
image_width += (self.CARD_OFFSET * (len(hand)-1))
|
||||
image_size = (image_width, (self.CARD_BORDER * 2) + self.CARD_HEIGHT)
|
||||
background = Image.new("RGBA", image_size, (0, 0, 0, 0))
|
||||
|
||||
for i, card in enumerate(hand):
|
||||
position = (
|
||||
self.CARD_BORDER + (self.CARD_OFFSET*i),
|
||||
self.CARD_BORDER
|
||||
)
|
||||
for i, card in enumerate(hand):
|
||||
position = (
|
||||
self.CARD_BORDER + (self.CARD_OFFSET*i),
|
||||
self.CARD_BORDER
|
||||
)
|
||||
|
||||
if i + hidden_cards < len(hand):
|
||||
card_image = Image.open(f"{self.cards_path}{card.upper()}.png")
|
||||
else:
|
||||
card_image = Image.open(f"{self.cards_path}red_back.png")
|
||||
if i + hidden_cards < len(hand):
|
||||
card_image = Image.open(f"{self.cards_path}{card.upper()}.png")
|
||||
else:
|
||||
card_image = Image.open(f"{self.cards_path}red_back.png")
|
||||
|
||||
card_image = card_image.resize(
|
||||
(self.CARD_WIDTH, self.CARD_HEIGHT),
|
||||
resample=Image.BILINEAR
|
||||
)
|
||||
background.paste(card_image, position, card_image)
|
||||
card_image = card_image.resize(
|
||||
(self.CARD_WIDTH, self.CARD_HEIGHT),
|
||||
resample=Image.BILINEAR
|
||||
)
|
||||
background.paste(card_image, position, card_image)
|
||||
|
||||
return background
|
||||
return background
|
||||
|
||||
@@ -3,8 +3,8 @@ Has a container for game functions.
|
||||
|
||||
*Classes*
|
||||
---------
|
||||
Games
|
||||
Container for game functions.
|
||||
Games
|
||||
Container for game functions.
|
||||
"""
|
||||
|
||||
|
||||
@@ -17,30 +17,30 @@ from .wordle import WordleGame
|
||||
|
||||
|
||||
class Games():
|
||||
"""
|
||||
Contains game classes.
|
||||
"""
|
||||
Contains game classes.
|
||||
|
||||
*Attributes*
|
||||
------------
|
||||
bot: Gwendolyn
|
||||
The instance of Gwendolyn.
|
||||
blackjack
|
||||
Contains blackjack functions.
|
||||
connect_four
|
||||
Contains connect four functions.
|
||||
hangman
|
||||
Contains hangman functions.
|
||||
hex
|
||||
Contains hex functions
|
||||
"""
|
||||
*Attributes*
|
||||
------------
|
||||
bot: Gwendolyn
|
||||
The instance of Gwendolyn.
|
||||
blackjack
|
||||
Contains blackjack functions.
|
||||
connect_four
|
||||
Contains connect four functions.
|
||||
hangman
|
||||
Contains hangman functions.
|
||||
hex
|
||||
Contains hex functions
|
||||
"""
|
||||
|
||||
def __init__(self, bot):
|
||||
"""Initialize the container."""
|
||||
self.bot = bot
|
||||
def __init__(self, bot):
|
||||
"""Initialize the container."""
|
||||
self.bot = bot
|
||||
|
||||
self.trivia = Trivia(bot)
|
||||
self.blackjack = Blackjack(bot)
|
||||
self.connect_four = ConnectFour(bot)
|
||||
self.hangman = Hangman(bot)
|
||||
self.hex = HexGame(bot)
|
||||
self.wordle = WordleGame(bot)
|
||||
self.trivia = Trivia(bot)
|
||||
self.blackjack = Blackjack(bot)
|
||||
self.connect_four = ConnectFour(bot)
|
||||
self.hangman = Hangman(bot)
|
||||
self.hex = HexGame(bot)
|
||||
self.wordle = WordleGame(bot)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,149 +3,149 @@ Contains the code that deals with money.
|
||||
|
||||
*Classes*
|
||||
---------
|
||||
Money
|
||||
Deals with money.
|
||||
Money
|
||||
Deals with money.
|
||||
"""
|
||||
import interactions # Used for typehints
|
||||
import discord # Used for typehints
|
||||
|
||||
|
||||
class Money():
|
||||
"""
|
||||
Deals with money.
|
||||
|
||||
*Methods*
|
||||
---------
|
||||
checkBalance(user: str)
|
||||
sendBalance(ctx: interactions.SlashContext)
|
||||
addMoney(user: str, amount: int)
|
||||
giveMoney(ctx: interactions.SlashContext, user: discord.User,
|
||||
amount: int)
|
||||
|
||||
*Attributes*
|
||||
------------
|
||||
bot: Gwendolyn
|
||||
The instance of Gwendolyn
|
||||
database: pymongo.Client
|
||||
The mongo database
|
||||
"""
|
||||
|
||||
def __init__(self, bot):
|
||||
"""Initialize the class."""
|
||||
self.bot = bot
|
||||
self.database = bot.database
|
||||
|
||||
def checkBalance(self, user: str):
|
||||
"""
|
||||
Deals with money.
|
||||
Get the account balance of a user.
|
||||
|
||||
*Methods*
|
||||
---------
|
||||
checkBalance(user: str)
|
||||
sendBalance(ctx: interactions.SlashContext)
|
||||
addMoney(user: str, amount: int)
|
||||
giveMoney(ctx: interactions.SlashContext, user: discord.User,
|
||||
amount: int)
|
||||
|
||||
*Attributes*
|
||||
*Parameters*
|
||||
------------
|
||||
bot: Gwendolyn
|
||||
The instance of Gwendolyn
|
||||
database: pymongo.Client
|
||||
The mongo database
|
||||
user: str
|
||||
The user to get the balance of.
|
||||
|
||||
*Returns*
|
||||
---------
|
||||
balance: int
|
||||
The balance of the user's account.
|
||||
"""
|
||||
self.bot.log("checking "+user+"'s account balance")
|
||||
|
||||
def __init__(self, bot):
|
||||
"""Initialize the class."""
|
||||
self.bot = bot
|
||||
self.database = bot.database
|
||||
user_data = self.database["users"].find_one({"_id": user})
|
||||
|
||||
def checkBalance(self, user: str):
|
||||
"""
|
||||
Get the account balance of a user.
|
||||
if user_data is not None:
|
||||
return user_data["money"]
|
||||
else:
|
||||
return 0
|
||||
|
||||
*Parameters*
|
||||
------------
|
||||
user: str
|
||||
The user to get the balance of.
|
||||
async def sendBalance(self, ctx: interactions.SlashContext):
|
||||
"""
|
||||
Get your own account balance.
|
||||
|
||||
*Returns*
|
||||
---------
|
||||
balance: int
|
||||
The balance of the user's account.
|
||||
"""
|
||||
self.bot.log("checking "+user+"'s account balance")
|
||||
*Parameters*
|
||||
------------
|
||||
ctx: interactions.SlashContext
|
||||
The context of the command.
|
||||
"""
|
||||
await self.bot.defer(ctx)
|
||||
response = self.checkBalance("#"+str(ctx.author.id))
|
||||
user_name = ctx.author.display_name
|
||||
if response == 1:
|
||||
new_message = f"{user_name} has {response} GwendoBuck"
|
||||
else:
|
||||
new_message = f"{user_name} has {response} GwendoBucks"
|
||||
await ctx.send(new_message)
|
||||
|
||||
user_data = self.database["users"].find_one({"_id": user})
|
||||
# Adds money to the account of a user
|
||||
def addMoney(self, user: str, amount: int):
|
||||
"""
|
||||
Add money to a user account.
|
||||
|
||||
if user_data is not None:
|
||||
return user_data["money"]
|
||||
else:
|
||||
return 0
|
||||
*Parameters*
|
||||
------------
|
||||
user: str
|
||||
The id of the user to give money.
|
||||
amount: int
|
||||
The amount to add to the user's account.
|
||||
"""
|
||||
self.bot.log("adding "+str(amount)+" to "+user+"'s account")
|
||||
|
||||
async def sendBalance(self, ctx: interactions.SlashContext):
|
||||
"""
|
||||
Get your own account balance.
|
||||
user_data = self.database["users"].find_one({"_id": user})
|
||||
|
||||
*Parameters*
|
||||
------------
|
||||
ctx: interactions.SlashContext
|
||||
The context of the command.
|
||||
"""
|
||||
await self.bot.defer(ctx)
|
||||
response = self.checkBalance("#"+str(ctx.author.id))
|
||||
user_name = ctx.author.display_name
|
||||
if response == 1:
|
||||
new_message = f"{user_name} has {response} GwendoBuck"
|
||||
else:
|
||||
new_message = f"{user_name} has {response} GwendoBucks"
|
||||
await ctx.send(new_message)
|
||||
if user_data is not None:
|
||||
updater = {"$inc": {"money": amount}}
|
||||
self.database["users"].update_one({"_id": user}, updater)
|
||||
else:
|
||||
new_user = {
|
||||
"_id": user,
|
||||
"user name": self.bot.database_funcs.get_name(user),
|
||||
"money": amount
|
||||
}
|
||||
self.database["users"].insert_one(new_user)
|
||||
|
||||
# Adds money to the account of a user
|
||||
def addMoney(self, user: str, amount: int):
|
||||
"""
|
||||
Add money to a user account.
|
||||
# Transfers money from one user to another
|
||||
async def giveMoney(self, ctx: interactions.SlashContext,
|
||||
user: discord.User, amount: int):
|
||||
"""
|
||||
Give someone else money from your account.
|
||||
|
||||
*Parameters*
|
||||
------------
|
||||
user: str
|
||||
The id of the user to give money.
|
||||
amount: int
|
||||
The amount to add to the user's account.
|
||||
"""
|
||||
self.bot.log("adding "+str(amount)+" to "+user+"'s account")
|
||||
*Parameters*
|
||||
------------
|
||||
ctx: interactions.SlashContext
|
||||
The context of the command.
|
||||
user: discord.User
|
||||
The user to give money.
|
||||
amount: int
|
||||
The amount to transfer.
|
||||
"""
|
||||
await self.bot.defer(ctx)
|
||||
username = user.display_name
|
||||
if self.bot.database_funcs.get_id(username) is None:
|
||||
async for member in ctx.guild.fetch_members(limit=None):
|
||||
if member.display_name.lower() == username.lower():
|
||||
username = member.display_name
|
||||
user_id = f"#{member.id}"
|
||||
new_user = {
|
||||
"_id": user_id,
|
||||
"user name": username,
|
||||
"money": 0
|
||||
}
|
||||
self.bot.database["users"].insert_one(new_user)
|
||||
|
||||
user_data = self.database["users"].find_one({"_id": user})
|
||||
userid = f"#{ctx.author.id}"
|
||||
user_data = self.database["users"].find_one({"_id": userid})
|
||||
targetUser = self.bot.database_funcs.get_id(username)
|
||||
|
||||
if user_data is not None:
|
||||
updater = {"$inc": {"money": amount}}
|
||||
self.database["users"].update_one({"_id": user}, updater)
|
||||
else:
|
||||
new_user = {
|
||||
"_id": user,
|
||||
"user name": self.bot.database_funcs.get_name(user),
|
||||
"money": amount
|
||||
}
|
||||
self.database["users"].insert_one(new_user)
|
||||
|
||||
# Transfers money from one user to another
|
||||
async def giveMoney(self, ctx: interactions.SlashContext,
|
||||
user: discord.User, amount: int):
|
||||
"""
|
||||
Give someone else money from your account.
|
||||
|
||||
*Parameters*
|
||||
------------
|
||||
ctx: interactions.SlashContext
|
||||
The context of the command.
|
||||
user: discord.User
|
||||
The user to give money.
|
||||
amount: int
|
||||
The amount to transfer.
|
||||
"""
|
||||
await self.bot.defer(ctx)
|
||||
username = user.display_name
|
||||
if self.bot.database_funcs.get_id(username) is None:
|
||||
async for member in ctx.guild.fetch_members(limit=None):
|
||||
if member.display_name.lower() == username.lower():
|
||||
username = member.display_name
|
||||
user_id = f"#{member.id}"
|
||||
new_user = {
|
||||
"_id": user_id,
|
||||
"user name": username,
|
||||
"money": 0
|
||||
}
|
||||
self.bot.database["users"].insert_one(new_user)
|
||||
|
||||
userid = f"#{ctx.author.id}"
|
||||
user_data = self.database["users"].find_one({"_id": userid})
|
||||
targetUser = self.bot.database_funcs.get_id(username)
|
||||
|
||||
if amount <= 0:
|
||||
self.bot.log("They tried to steal")
|
||||
await ctx.send("Yeah, no. You can't do that")
|
||||
elif targetUser is None:
|
||||
self.bot.log("They weren't in the system")
|
||||
await ctx.send("The target doesn't exist")
|
||||
elif user_data is None or user_data["money"] < amount:
|
||||
self.bot.log("They didn't have enough GwendoBucks")
|
||||
await ctx.send("You don't have that many GwendoBuck")
|
||||
else:
|
||||
self.addMoney(f"#{ctx.author.id}", -1 * amount)
|
||||
self.addMoney(targetUser, amount)
|
||||
await ctx.send(f"Transferred {amount} GwendoBucks to {username}")
|
||||
if amount <= 0:
|
||||
self.bot.log("They tried to steal")
|
||||
await ctx.send("Yeah, no. You can't do that")
|
||||
elif targetUser is None:
|
||||
self.bot.log("They weren't in the system")
|
||||
await ctx.send("The target doesn't exist")
|
||||
elif user_data is None or user_data["money"] < amount:
|
||||
self.bot.log("They didn't have enough GwendoBucks")
|
||||
await ctx.send("You don't have that many GwendoBuck")
|
||||
else:
|
||||
self.addMoney(f"#{ctx.author.id}", -1 * amount)
|
||||
self.addMoney(targetUser, amount)
|
||||
await ctx.send(f"Transferred {amount} GwendoBucks to {username}")
|
||||
|
||||
@@ -3,8 +3,8 @@ Contains code for trivia games.
|
||||
|
||||
*Classes*
|
||||
---------
|
||||
Trivia
|
||||
Contains all the code for the trivia commands.
|
||||
Trivia
|
||||
Contains all the code for the trivia commands.
|
||||
"""
|
||||
import urllib # Used to get data from api
|
||||
import json # Used to read data from api
|
||||
@@ -15,191 +15,191 @@ from interactions import SlashContext # Used for type hints
|
||||
|
||||
|
||||
class Trivia():
|
||||
"""
|
||||
Contains the code for trivia games.
|
||||
"""
|
||||
Contains the code for trivia games.
|
||||
|
||||
*Methods*
|
||||
*Methods*
|
||||
---------
|
||||
triviaStart(channel: str) -> str, str, str
|
||||
triviaAnswer(user: str, channel: str, command: str) -> str
|
||||
triviaCountPoints(channel: str)
|
||||
triviaParse(ctx: SlashContext, answer: str)
|
||||
"""
|
||||
|
||||
def __init__(self, bot):
|
||||
"""Initialize the class."""
|
||||
self.bot = bot
|
||||
|
||||
def triviaStart(self, channel: str):
|
||||
"""
|
||||
Start a game of trivia.
|
||||
|
||||
Downloads a question with answers, shuffles the wrong answers
|
||||
with the correct answer and returns the questions and answers.
|
||||
Also saves the question in the database.
|
||||
|
||||
*Parameters*
|
||||
------------
|
||||
channel: str
|
||||
The id of the channel to start the game in
|
||||
|
||||
*Returns*
|
||||
---------
|
||||
triviaStart(channel: str) -> str, str, str
|
||||
triviaAnswer(user: str, channel: str, command: str) -> str
|
||||
triviaCountPoints(channel: str)
|
||||
triviaParse(ctx: SlashContext, answer: str)
|
||||
send_message: str
|
||||
The message to return to the user.
|
||||
"""
|
||||
triviaQuestions = self.bot.database["trivia questions"]
|
||||
question = triviaQuestions.find_one({"_id": channel})
|
||||
|
||||
def __init__(self, bot):
|
||||
"""Initialize the class."""
|
||||
self.bot = bot
|
||||
self.bot.log(f"Trying to find a trivia question for {channel}")
|
||||
|
||||
def triviaStart(self, channel: str):
|
||||
"""
|
||||
Start a game of trivia.
|
||||
if question is None:
|
||||
apiUrl = "https://opentdb.com/api.php?amount=10&type=multiple"
|
||||
with urllib.request.urlopen(apiUrl) as response:
|
||||
data = json.loads(response.read())
|
||||
|
||||
Downloads a question with answers, shuffles the wrong answers
|
||||
with the correct answer and returns the questions and answers.
|
||||
Also saves the question in the database.
|
||||
question = data["results"][0]["question"]
|
||||
self.bot.log(f"Found the question \"{question}\"")
|
||||
answers = data["results"][0]["incorrect_answers"]
|
||||
answers.append(data["results"][0]["correct_answer"])
|
||||
random.shuffle(answers)
|
||||
correctAnswer = data["results"][0]["correct_answer"]
|
||||
correctAnswer = answers.index(correctAnswer) + 97
|
||||
|
||||
*Parameters*
|
||||
------------
|
||||
channel: str
|
||||
The id of the channel to start the game in
|
||||
newQuestion = {
|
||||
"_id": channel,
|
||||
"answer": str(chr(correctAnswer)),
|
||||
"players": {}
|
||||
}
|
||||
triviaQuestions.insert_one(newQuestion)
|
||||
|
||||
*Returns*
|
||||
---------
|
||||
send_message: str
|
||||
The message to return to the user.
|
||||
"""
|
||||
triviaQuestions = self.bot.database["trivia questions"]
|
||||
question = triviaQuestions.find_one({"_id": channel})
|
||||
replacements = {
|
||||
"'": "\'",
|
||||
""": "\"",
|
||||
"“": "\"",
|
||||
"”": "\"",
|
||||
"é": "é"
|
||||
}
|
||||
question = data["results"][0]["question"]
|
||||
|
||||
self.bot.log(f"Trying to find a trivia question for {channel}")
|
||||
for key, value in replacements.items():
|
||||
question = question.replace(key, value)
|
||||
|
||||
if question is None:
|
||||
apiUrl = "https://opentdb.com/api.php?amount=10&type=multiple"
|
||||
with urllib.request.urlopen(apiUrl) as response:
|
||||
data = json.loads(response.read())
|
||||
for answer in answers:
|
||||
for key, value in replacements.items():
|
||||
answer = answer.replace(key, value)
|
||||
|
||||
question = data["results"][0]["question"]
|
||||
self.bot.log(f"Found the question \"{question}\"")
|
||||
answers = data["results"][0]["incorrect_answers"]
|
||||
answers.append(data["results"][0]["correct_answer"])
|
||||
random.shuffle(answers)
|
||||
correctAnswer = data["results"][0]["correct_answer"]
|
||||
correctAnswer = answers.index(correctAnswer) + 97
|
||||
return question, answers, correctAnswer
|
||||
else:
|
||||
log_message = "There was already a trivia question for that channel"
|
||||
self.bot.log(log_message)
|
||||
return self.bot.long_strings["Trivia going on"], "", ""
|
||||
|
||||
newQuestion = {
|
||||
"_id": channel,
|
||||
"answer": str(chr(correctAnswer)),
|
||||
"players": {}
|
||||
}
|
||||
triviaQuestions.insert_one(newQuestion)
|
||||
def triviaAnswer(self, user: str, channel: str, command: str):
|
||||
"""
|
||||
Answer the current trivia question.
|
||||
|
||||
replacements = {
|
||||
"'": "\'",
|
||||
""": "\"",
|
||||
"“": "\"",
|
||||
"”": "\"",
|
||||
"é": "é"
|
||||
}
|
||||
question = data["results"][0]["question"]
|
||||
*Parameters*
|
||||
------------
|
||||
user: str
|
||||
The id of the user who answered.
|
||||
channel: str
|
||||
The id of the channel the game is in.
|
||||
command: str
|
||||
The user's answer.
|
||||
|
||||
for key, value in replacements.items():
|
||||
question = question.replace(key, value)
|
||||
*Returns*
|
||||
---------
|
||||
send_message: str
|
||||
The message to send if the function failed.
|
||||
"""
|
||||
triviaQuestions = self.bot.database["trivia questions"]
|
||||
question = triviaQuestions.find_one({"_id": channel})
|
||||
|
||||
for answer in answers:
|
||||
for key, value in replacements.items():
|
||||
answer = answer.replace(key, value)
|
||||
if command not in ["a", "b", "c", "d"]:
|
||||
self.bot.log("I didn't quite understand that")
|
||||
return "I didn't quite understand that"
|
||||
elif question is None:
|
||||
self.bot.log("There's no question right now")
|
||||
return "There's no question right now"
|
||||
elif user in question["players"]:
|
||||
self.bot.log(f"{user} has already answered this question")
|
||||
return f"{user} has already answered this question"
|
||||
else:
|
||||
self.bot.log(f"{user} answered the question in {channel}")
|
||||
|
||||
return question, answers, correctAnswer
|
||||
else:
|
||||
log_message = "There was already a trivia question for that channel"
|
||||
self.bot.log(log_message)
|
||||
return self.bot.long_strings["Trivia going on"], "", ""
|
||||
updater = {"$set": {f"players.{user}": command}}
|
||||
triviaQuestions.update_one({"_id": channel}, updater)
|
||||
return None
|
||||
|
||||
def triviaAnswer(self, user: str, channel: str, command: str):
|
||||
"""
|
||||
Answer the current trivia question.
|
||||
def triviaCountPoints(self, channel: str):
|
||||
"""
|
||||
Add money to every winner's account.
|
||||
|
||||
*Parameters*
|
||||
------------
|
||||
user: str
|
||||
The id of the user who answered.
|
||||
channel: str
|
||||
The id of the channel the game is in.
|
||||
command: str
|
||||
The user's answer.
|
||||
*Parameters*
|
||||
------------
|
||||
channel: str
|
||||
The id of the channel the game is in.
|
||||
"""
|
||||
triviaQuestions = self.bot.database["trivia questions"]
|
||||
question = triviaQuestions.find_one({"_id": channel})
|
||||
|
||||
*Returns*
|
||||
---------
|
||||
send_message: str
|
||||
The message to send if the function failed.
|
||||
"""
|
||||
triviaQuestions = self.bot.database["trivia questions"]
|
||||
question = triviaQuestions.find_one({"_id": channel})
|
||||
self.bot.log("Counting points for question in "+channel)
|
||||
|
||||
if command not in ["a", "b", "c", "d"]:
|
||||
self.bot.log("I didn't quite understand that")
|
||||
return "I didn't quite understand that"
|
||||
elif question is None:
|
||||
self.bot.log("There's no question right now")
|
||||
return "There's no question right now"
|
||||
elif user in question["players"]:
|
||||
self.bot.log(f"{user} has already answered this question")
|
||||
return f"{user} has already answered this question"
|
||||
else:
|
||||
self.bot.log(f"{user} answered the question in {channel}")
|
||||
if question is not None:
|
||||
for player, answer in question["players"].items():
|
||||
if answer == question["answer"]:
|
||||
self.bot.money.addMoney(player, 1)
|
||||
else:
|
||||
self.bot.log("Couldn't find the questio")
|
||||
|
||||
updater = {"$set": {f"players.{user}": command}}
|
||||
triviaQuestions.update_one({"_id": channel}, updater)
|
||||
return None
|
||||
return None
|
||||
|
||||
def triviaCountPoints(self, channel: str):
|
||||
"""
|
||||
Add money to every winner's account.
|
||||
async def triviaParse(self, ctx: SlashContext, answer: str):
|
||||
"""
|
||||
Parse a trivia command.
|
||||
|
||||
*Parameters*
|
||||
------------
|
||||
channel: str
|
||||
The id of the channel the game is in.
|
||||
"""
|
||||
triviaQuestions = self.bot.database["trivia questions"]
|
||||
question = triviaQuestions.find_one({"_id": channel})
|
||||
*Parameters*
|
||||
------------
|
||||
ctx: SlashContext
|
||||
The context of the command.
|
||||
answer: str
|
||||
The answer, if any.
|
||||
"""
|
||||
await self.bot.defer(ctx)
|
||||
channelId = str(ctx.channel_id)
|
||||
if answer == "":
|
||||
question, options, correctAnswer = self.triviaStart(channelId)
|
||||
if options != "":
|
||||
results = "**"+question+"**\n"
|
||||
for x, option in enumerate(options):
|
||||
results += chr(x+97) + ") "+option+"\n"
|
||||
|
||||
self.bot.log("Counting points for question in "+channel)
|
||||
await ctx.send(results)
|
||||
|
||||
if question is not None:
|
||||
for player, answer in question["players"].items():
|
||||
if answer == question["answer"]:
|
||||
self.bot.money.addMoney(player, 1)
|
||||
else:
|
||||
self.bot.log("Couldn't find the questio")
|
||||
await asyncio.sleep(60)
|
||||
|
||||
return None
|
||||
self.triviaCountPoints(channelId)
|
||||
|
||||
async def triviaParse(self, ctx: SlashContext, answer: str):
|
||||
"""
|
||||
Parse a trivia command.
|
||||
delete_gameParams = ["trivia questions", channelId]
|
||||
self.bot.database_funcs.delete_game(*delete_gameParams)
|
||||
|
||||
*Parameters*
|
||||
------------
|
||||
ctx: SlashContext
|
||||
The context of the command.
|
||||
answer: str
|
||||
The answer, if any.
|
||||
"""
|
||||
await self.bot.defer(ctx)
|
||||
channelId = str(ctx.channel_id)
|
||||
if answer == "":
|
||||
question, options, correctAnswer = self.triviaStart(channelId)
|
||||
if options != "":
|
||||
results = "**"+question+"**\n"
|
||||
for x, option in enumerate(options):
|
||||
results += chr(x+97) + ") "+option+"\n"
|
||||
self.bot.log("Time's up for the trivia question", channelId)
|
||||
send_message = self.bot.long_strings["Trivia time up"]
|
||||
format_parameters = [chr(correctAnswer), options[correctAnswer-97]]
|
||||
send_message = send_message.format(*format_parameters)
|
||||
await ctx.send(send_message)
|
||||
else:
|
||||
await ctx.send(question, hidden=True)
|
||||
|
||||
await ctx.send(results)
|
||||
|
||||
await asyncio.sleep(60)
|
||||
|
||||
self.triviaCountPoints(channelId)
|
||||
|
||||
delete_gameParams = ["trivia questions", channelId]
|
||||
self.bot.database_funcs.delete_game(*delete_gameParams)
|
||||
|
||||
self.bot.log("Time's up for the trivia question", channelId)
|
||||
send_message = self.bot.long_strings["Trivia time up"]
|
||||
format_parameters = [chr(correctAnswer), options[correctAnswer-97]]
|
||||
send_message = send_message.format(*format_parameters)
|
||||
await ctx.send(send_message)
|
||||
else:
|
||||
await ctx.send(question, hidden=True)
|
||||
|
||||
elif answer in ["a", "b", "c", "d"]:
|
||||
userId = f"#{ctx.author.id}"
|
||||
response = self.triviaAnswer(userId, channelId, answer)
|
||||
if response is None:
|
||||
user_name = ctx.author.display_name
|
||||
await ctx.send(f"{user_name} answered **{answer}**")
|
||||
else:
|
||||
await ctx.send(response)
|
||||
else:
|
||||
self.bot.log("I didn't understand that", channelId)
|
||||
await ctx.send("I didn't understand that")
|
||||
elif answer in ["a", "b", "c", "d"]:
|
||||
userId = f"#{ctx.author.id}"
|
||||
response = self.triviaAnswer(userId, channelId, answer)
|
||||
if response is None:
|
||||
user_name = ctx.author.display_name
|
||||
await ctx.send(f"{user_name} answered **{answer}**")
|
||||
else:
|
||||
await ctx.send(response)
|
||||
else:
|
||||
self.bot.log("I didn't understand that", channelId)
|
||||
await ctx.send("I didn't understand that")
|
||||
|
||||
@@ -25,177 +25,177 @@ PRESENT_COLOR = "#0f7aa8"
|
||||
COLORS = [INCORRECT_COLOR, PRESENT_COLOR, CORRECT_COLOR]
|
||||
|
||||
class WordleGame(DatabaseGame):
|
||||
"""Implementation of wordle game."""
|
||||
def __init__(self, bot):
|
||||
super().__init__(bot, "wordle", WordleDrawer)
|
||||
self._API_url = "https://api.wordnik.com/v4/words.json/randomWords?" # pylint: disable=invalid-name
|
||||
api_key = self.bot.credentials["wordnik_key"]
|
||||
self._APIPARAMS = { # pylint: disable=invalid-name
|
||||
"hasDictionaryDef": True,
|
||||
"minCorpusCount": 5000,
|
||||
"maxCorpusCount": -1,
|
||||
"minDictionaryCount": 1,
|
||||
"maxDictionaryCount": -1,
|
||||
"limit": 1,
|
||||
"api_key": api_key
|
||||
}
|
||||
"""Implementation of wordle game."""
|
||||
def __init__(self, bot):
|
||||
super().__init__(bot, "wordle", WordleDrawer)
|
||||
self._API_url = "https://api.wordnik.com/v4/words.json/randomWords?" # pylint: disable=invalid-name
|
||||
api_key = self.bot.credentials["wordnik_key"]
|
||||
self._APIPARAMS = { # pylint: disable=invalid-name
|
||||
"hasDictionaryDef": True,
|
||||
"minCorpusCount": 5000,
|
||||
"maxCorpusCount": -1,
|
||||
"minDictionaryCount": 1,
|
||||
"maxDictionaryCount": -1,
|
||||
"limit": 1,
|
||||
"api_key": api_key
|
||||
}
|
||||
|
||||
async def start(self, ctx, letters: int):
|
||||
if self._test_document(str(ctx.channel_id)):
|
||||
await ctx.send("There is already a wordle game in this channel.")
|
||||
self.bot.log("There was already a game going on")
|
||||
return
|
||||
async def start(self, ctx, letters: int):
|
||||
if self._test_document(str(ctx.channel_id)):
|
||||
await ctx.send("There is already a wordle game in this channel.")
|
||||
self.bot.log("There was already a game going on")
|
||||
return
|
||||
|
||||
params = self._APIPARAMS
|
||||
params["minLength"] = letters
|
||||
params["maxLength"] = letters
|
||||
word = "-"
|
||||
while "-" in word or "." in word:
|
||||
response = requests.get(self._API_url, params=params)
|
||||
if response.json() == []:
|
||||
ctx.send("Could not find a word. Try again")
|
||||
return
|
||||
word = list(response.json()[0]["word"].upper())
|
||||
params = self._APIPARAMS
|
||||
params["minLength"] = letters
|
||||
params["maxLength"] = letters
|
||||
word = "-"
|
||||
while "-" in word or "." in word:
|
||||
response = requests.get(self._API_url, params=params)
|
||||
if response.json() == []:
|
||||
ctx.send("Could not find a word. Try again")
|
||||
return
|
||||
word = list(response.json()[0]["word"].upper())
|
||||
|
||||
self.bot.log(f"Found the word \"{''.join(word)}\"")
|
||||
game = {"word": word, "guesses": [], "results": []}
|
||||
await ctx.send("Starting a wordle game.")
|
||||
await self._start_new(ctx.channel, game, delete=False)
|
||||
self.bot.log(f"Found the word \"{''.join(word)}\"")
|
||||
game = {"word": word, "guesses": [], "results": []}
|
||||
await ctx.send("Starting a wordle game.")
|
||||
await self._start_new(ctx.channel, game, delete=False)
|
||||
|
||||
def _get_result(self, guess: list[str], word: list[str]):
|
||||
result = ["_" for _ in guess]
|
||||
for i, letter in enumerate(guess):
|
||||
if letter == word[i]:
|
||||
result[i] = "*"
|
||||
def _get_result(self, guess: list[str], word: list[str]):
|
||||
result = ["_" for _ in guess]
|
||||
for i, letter in enumerate(guess):
|
||||
if letter == word[i]:
|
||||
result[i] = "*"
|
||||
|
||||
for i, letter in enumerate(guess):
|
||||
if letter in word and result[i] != "*":
|
||||
same_letter = guess[:i].count(letter)
|
||||
same_letter += len(
|
||||
[
|
||||
l for j,l in
|
||||
enumerate(guess[i:])
|
||||
if guess[i:][j] == letter and result[i:][j] == "*"
|
||||
]
|
||||
)
|
||||
if same_letter < word.count(letter):
|
||||
result[i] = "-"
|
||||
for i, letter in enumerate(guess):
|
||||
if letter in word and result[i] != "*":
|
||||
same_letter = guess[:i].count(letter)
|
||||
same_letter += len(
|
||||
[
|
||||
l for j,l in
|
||||
enumerate(guess[i:])
|
||||
if guess[i:][j] == letter and result[i:][j] == "*"
|
||||
]
|
||||
)
|
||||
if same_letter < word.count(letter):
|
||||
result[i] = "-"
|
||||
|
||||
return result
|
||||
return result
|
||||
|
||||
async def guess(self, ctx, guess: str):
|
||||
if not guess.isalpha():
|
||||
await ctx.send("You can only use letters in your guess")
|
||||
return
|
||||
async def guess(self, ctx, guess: str):
|
||||
if not guess.isalpha():
|
||||
await ctx.send("You can only use letters in your guess")
|
||||
return
|
||||
|
||||
guess = list(guess.upper())
|
||||
try:
|
||||
game = self.access_document(str(ctx.channel_id))
|
||||
except GameNotInDatabase:
|
||||
await ctx.send("No game in channel")
|
||||
return
|
||||
guess = list(guess.upper())
|
||||
try:
|
||||
game = self.access_document(str(ctx.channel_id))
|
||||
except GameNotInDatabase:
|
||||
await ctx.send("No game in channel")
|
||||
return
|
||||
|
||||
if len(guess) != len(game['word']):
|
||||
await ctx.send(
|
||||
f"Your guess must be {len(game['word'])} letters long")
|
||||
return
|
||||
if len(guess) != len(game['word']):
|
||||
await ctx.send(
|
||||
f"Your guess must be {len(game['word'])} letters long")
|
||||
return
|
||||
|
||||
await ctx.send(f"Guessed {''.join(guess)}")
|
||||
result = self._get_result(guess, game['word'])
|
||||
await ctx.send(f"Guessed {''.join(guess)}")
|
||||
result = self._get_result(guess, game['word'])
|
||||
|
||||
updater = {
|
||||
"$set": {
|
||||
f"guesses.{len(game['guesses'])}": guess,
|
||||
f"results.{len(game['guesses'])}": result
|
||||
}
|
||||
}
|
||||
self._update_document(str(ctx.channel_id), updater)
|
||||
updater = {
|
||||
"$set": {
|
||||
f"guesses.{len(game['guesses'])}": guess,
|
||||
f"results.{len(game['guesses'])}": result
|
||||
}
|
||||
}
|
||||
self._update_document(str(ctx.channel_id), updater)
|
||||
|
||||
if result == ["*" for _ in game['word']]:
|
||||
await ctx.send("You guessed the word! Adding 15 GwendoBucks to your account")
|
||||
self.bot.money.addMoney(f"#{ctx.author_id}", 15)
|
||||
await self._end_game(ctx.channel)
|
||||
elif len(game['guesses']) == 5:
|
||||
await ctx.send(f"You used up all available guesses. The word was '{''.join(game['word'])}'")
|
||||
await self._end_game(ctx.channel)
|
||||
else:
|
||||
print(len(game['guesses']))
|
||||
await self._delete_old_image(ctx.channel)
|
||||
await self._send_image(ctx.channel, delete=False)
|
||||
if result == ["*" for _ in game['word']]:
|
||||
await ctx.send("You guessed the word! Adding 15 GwendoBucks to your account")
|
||||
self.bot.money.addMoney(f"#{ctx.author_id}", 15)
|
||||
await self._end_game(ctx.channel)
|
||||
elif len(game['guesses']) == 5:
|
||||
await ctx.send(f"You used up all available guesses. The word was '{''.join(game['word'])}'")
|
||||
await self._end_game(ctx.channel)
|
||||
else:
|
||||
print(len(game['guesses']))
|
||||
await self._delete_old_image(ctx.channel)
|
||||
await self._send_image(ctx.channel, delete=False)
|
||||
|
||||
class WordleDrawer(BaseDrawer):
|
||||
def __init__(self, bot, game: WordleGame):
|
||||
super().__init__(bot, game)
|
||||
self.default_image = None
|
||||
self.default_color = BACKGROUND_COLOR
|
||||
self.default_size = (0, 0)
|
||||
def __init__(self, bot, game: WordleGame):
|
||||
super().__init__(bot, game)
|
||||
self.default_image = None
|
||||
self.default_color = BACKGROUND_COLOR
|
||||
self.default_size = (0, 0)
|
||||
|
||||
def _get_size(self, game: dict):
|
||||
width = (
|
||||
(len(game['word']) * SQUARE_SIZE) +
|
||||
((len(game['word']) - 1) * SQUARE_PADDING) +
|
||||
(2 * IMAGE_MARGIN)
|
||||
)
|
||||
height = (
|
||||
(6 * SQUARE_SIZE) +
|
||||
(5 * ROW_PADDING) +
|
||||
(2 * IMAGE_MARGIN)
|
||||
)
|
||||
size = (width, height)
|
||||
def _get_size(self, game: dict):
|
||||
width = (
|
||||
(len(game['word']) * SQUARE_SIZE) +
|
||||
((len(game['word']) - 1) * SQUARE_PADDING) +
|
||||
(2 * IMAGE_MARGIN)
|
||||
)
|
||||
height = (
|
||||
(6 * SQUARE_SIZE) +
|
||||
(5 * ROW_PADDING) +
|
||||
(2 * IMAGE_MARGIN)
|
||||
)
|
||||
size = (width, height)
|
||||
|
||||
return size
|
||||
return size
|
||||
|
||||
def _draw_row(self, row, drawer, font, word: str, colors: list[str] = None,
|
||||
border_color: str = None):
|
||||
if colors is None:
|
||||
colors = [BACKGROUND_COLOR for _ in range(len(word))]
|
||||
def _draw_row(self, row, drawer, font, word: str, colors: list[str] = None,
|
||||
border_color: str = None):
|
||||
if colors is None:
|
||||
colors = [BACKGROUND_COLOR for _ in range(len(word))]
|
||||
|
||||
for i, letter in enumerate(word):
|
||||
y_pos = IMAGE_MARGIN + (row * (SQUARE_SIZE + ROW_PADDING))
|
||||
x_pos = IMAGE_MARGIN + (i * (SQUARE_SIZE + SQUARE_PADDING))
|
||||
top_left = (x_pos, y_pos)
|
||||
bottom_right = (x_pos + SQUARE_SIZE, y_pos + SQUARE_SIZE)
|
||||
for i, letter in enumerate(word):
|
||||
y_pos = IMAGE_MARGIN + (row * (SQUARE_SIZE + ROW_PADDING))
|
||||
x_pos = IMAGE_MARGIN + (i * (SQUARE_SIZE + SQUARE_PADDING))
|
||||
top_left = (x_pos, y_pos)
|
||||
bottom_right = (x_pos + SQUARE_SIZE, y_pos + SQUARE_SIZE)
|
||||
|
||||
drawer.rounded_rectangle(
|
||||
(top_left,bottom_right),
|
||||
10,
|
||||
colors[i],
|
||||
border_color,
|
||||
3
|
||||
)
|
||||
drawer.rounded_rectangle(
|
||||
(top_left,bottom_right),
|
||||
10,
|
||||
colors[i],
|
||||
border_color,
|
||||
3
|
||||
)
|
||||
|
||||
text_pos = (
|
||||
x_pos + (SQUARE_SIZE//2),
|
||||
y_pos + int(SQUARE_SIZE * 0.6)
|
||||
)
|
||||
text_pos = (
|
||||
x_pos + (SQUARE_SIZE//2),
|
||||
y_pos + int(SQUARE_SIZE * 0.6)
|
||||
)
|
||||
|
||||
drawer.text(text_pos, letter, TEXT_COLOR, font=font, anchor="mm")
|
||||
drawer.text(text_pos, letter, TEXT_COLOR, font=font, anchor="mm")
|
||||
|
||||
def _determine_colors(self, results):
|
||||
return [COLORS[["_","-","*"].index(symbol)] for symbol in results]
|
||||
def _determine_colors(self, results):
|
||||
return [COLORS[["_","-","*"].index(symbol)] for symbol in results]
|
||||
|
||||
def _draw_image(self, game: dict, image: Image.Image):
|
||||
drawer = ImageDraw.Draw(image)
|
||||
font = self._get_font(FONT_SIZE)
|
||||
for i, guess in enumerate(game['guesses']):
|
||||
colors = self._determine_colors(game['results'][i])
|
||||
self._draw_row(i, drawer, font, guess, colors)
|
||||
def _draw_image(self, game: dict, image: Image.Image):
|
||||
drawer = ImageDraw.Draw(image)
|
||||
font = self._get_font(FONT_SIZE)
|
||||
for i, guess in enumerate(game['guesses']):
|
||||
colors = self._determine_colors(game['results'][i])
|
||||
self._draw_row(i, drawer, font, guess, colors)
|
||||
|
||||
if len(game["guesses"]) < 6:
|
||||
self._draw_row(
|
||||
len(game['guesses']),
|
||||
drawer,
|
||||
font,
|
||||
" "*len(game['word']),
|
||||
border_color=WRITING_BORDER_COLOR
|
||||
)
|
||||
if len(game["guesses"]) < 6:
|
||||
self._draw_row(
|
||||
len(game['guesses']),
|
||||
drawer,
|
||||
font,
|
||||
" "*len(game['word']),
|
||||
border_color=WRITING_BORDER_COLOR
|
||||
)
|
||||
|
||||
for i in range(5 - len(game['guesses'])):
|
||||
self._draw_row(
|
||||
len(game['guesses']) + i + 1,
|
||||
drawer,
|
||||
font, " "*len(game['word']),
|
||||
border_color=INACTIVE_BORDER_COLOR
|
||||
)
|
||||
for i in range(5 - len(game['guesses'])):
|
||||
self._draw_row(
|
||||
len(game['guesses']) + i + 1,
|
||||
drawer,
|
||||
font, " "*len(game['word']),
|
||||
border_color=INACTIVE_BORDER_COLOR
|
||||
)
|
||||
|
||||
return super()._draw_image(game, image)
|
||||
return super()._draw_image(game, image)
|
||||
|
||||
Reference in New Issue
Block a user