Use the with statement on the game class

This is because the class is a context manager / state machine
This commit is contained in:
c0de 2022-10-24 19:55:50 -05:00
parent 7101db5394
commit 1845e42488
3 changed files with 31 additions and 15 deletions

View File

@ -7,7 +7,7 @@ import datetime
from peewee import *
# User can provide path to database, or it will be put next to models.py
# User can provide path to database, or it will be put next to main.py
DATABASE = os.environ.get('database_path', os.getcwd() + '/ghostball.db')
database = SqliteDatabase(DATABASE)

View File

@ -15,8 +15,8 @@ class GhostBallClient(discord.Client):
def __init__(self, *args, **kwargs):
super(GhostBallClient, self).__init__(*args, **kwargs)
self.game = game.Game()
self.game.discord = self
with game.Game() as self.game:
self.game.discord = self
async def on_ready(self):
print("Logged on as", self.user)

View File

@ -13,9 +13,15 @@ class Game:
The game state class
This represents a game that exists in a channel
"""
"""
def __init__(self):
def __enter__(self):
"""
Allows use of `with Game as game` for try/except statements
We are using this instead of __init__, they work very similar
to each other (https://peps.python.org/pep-0343/)
"""
# Only one game should run at at time
self.is_running = False
@ -36,18 +42,32 @@ class Game:
self.discord = None
database.connect()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
def __exit__(self, exception_type, exception_value, exception_traceback):
"""
Automagically close the database
when this class has ended execution
"""
database.close()
async def check_is_running(method, start_new_game=True):
"""
Decorator that determines if the game is running or not
"""
async def wrapper(self):
if self.is_running and start_new_game:
return await self.message.channel.send("A game is already running")
elif not self.is_running and not start_new_game:
return await self.message.channel.send("There is no game running to add guesses to")
await method(self)
return await wrapper
@check_is_running
async def start(self):
if self.is_running:
return await self.message.channel.send("A game is already running")
self.is_running = True
# game.pitch_value is unknown at the start of the game
@ -68,10 +88,8 @@ class Game:
return None, False, None, None
@check_is_running(start_new_game=False)
async def stop(self):
if not self.is_running:
return await self.message.channel.send("There is no game running to resolve")
# Determine arguments
pitch_value, has_batter, batter_id, batter_guess = self.__stopArgs__()
if not pitch_value:
@ -97,10 +115,8 @@ class Game:
self.is_running = False
self.game = None
@check_is_running(start_new_game=False)
async def guess(self):
if not self.is_running:
return await self.message.channel.send("There is no game running to add guesses to")
value = int(self.message.content.split()[1])
if value < 1 or value > 1000:
return await self.message.channel.send(f"Invalid value. It must be between 1 and 1000 inclusive")