game stuff

This commit is contained in:
NikolajDanger
2021-09-30 14:05:50 +02:00
parent 5330a51fe0
commit cbf2ca765e
12 changed files with 538 additions and 551 deletions

View File

@ -1,28 +1,80 @@
"""Base class for the games."""
import random
from shutil import copyfile
from typing import Union
from discord import File
from discord import File, User
from discord.abc import Messageable
from discord_slash.utils.manage_components import (create_button,
create_actionrow)
from discord_slash.context import InteractionContext as IntCont
from PIL import ImageFont, Image, ImageDraw
from gwendolyn.exceptions import GameNotInDatabase
from gwendolyn.utils import encode_id
class GameBase():
"""The base class for the games."""
def __init__(self, bot):
def __init__(self, bot, game_name: int, drawer):
"""Initialize the class."""
self.bot = bot
self.database = self.bot.database
self.long_strings = self.bot.long_strings
self.resources = "gwendolyn/resources/games/"
self.game_name = ""
self.old_images_path = f"{self.resources}old_images/{self.game_name}"
self.draw = BaseDrawer(bot, self)
self.game_name = game_name
self.draw = drawer
def access_document(self, channel: str, collection_name: str="games"):
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(create_button(
style=style,
label=label,
custom_id=custom_id
))
action_rows = []
for i in range(((len(button_objects)-1)//5)+1):
action_rows.append(create_actionrow(*button_objects[i*5:i*5+5]))
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)
if buttons is not None and len(buttons) < 25:
await old_image.edit(components = self._get_action_rows(buttons))
return old_image
class DatabaseGame(GameBase):
"""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 access_document(self, channel: str, collection_name: str="games",
raise_missing_error: bool=True):
collection = self.bot.database[f"{self.game_name} {collection_name}"]
return collection.find_one({"_id": channel})
game = collection.find_one({"_id": channel})
if game is None and raise_missing_error:
raise GameNotInDatabase(self.game_name, channel)
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 _update_document(self, channel: str, updater: dict,
collection_name: str="games"):
@ -46,28 +98,29 @@ class GameBase():
await old_image.delete()
async def _send_image(self, channel: Messageable):
self.draw.draw(str(channel.id))
file_path = f"{self.resources}images/blackjack{channel.id}.png"
old_image = await channel.send(file=File(file_path))
async def _send_image(self, channel: Messageable,
buttons: list[tuple[str, list]] = None, delete=True):
old_image = 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):
async def _start_new(self, channel: Messageable, new_game: dict,
buttons: list[tuple[str, list]] = None):
self._insert_document(new_game)
default_image = f"{self.resources}default_images/{self.game_name}.png"
new_image = f"{self.resources}images/{self.game_name}{channel.id}.png"
copyfile(default_image, new_image)
await self._send_image(channel, buttons)
await self._send_image(channel)
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(GameBase):
class CardGame(DatabaseGame):
"""The class for card games."""
def __init__(self, bot):
def __init__(self, bot, game_name, drawer, deck_used):
"""Initialize the class."""
super().__init__(bot)
self.decks_used = 1
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}")
@ -99,6 +152,43 @@ class CardGame(GameBase):
return drawn_card
class BoardGame(GameBase):
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 difficulty, difficulty_text
class BaseDrawer():
"""Class for drawing games."""
def __init__(self, bot, game: GameBase):