From 3525ea42e11540e801e6193db8abe8cb42e28ed8 Mon Sep 17 00:00:00 2001 From: Zed Date: Tue, 23 Apr 2024 22:19:20 +0000 Subject: [PATCH] Jack's Changes (#1) First merge after adding branch Co-authored-by: c0de Reviewed-on: https://c0de.dev/c0de/BaseballBot/pulls/1 Co-authored-by: Zed Co-committed-by: Zed --- Dockerfile | 2 +- game/base.py | 14 ++++++++++++++ game/clear.py | 30 ++++++++++++++++++++++++++++++ game/end_game.py | 30 ++++-------------------------- game/help.py | 5 ++--- game/manager.py | 3 ++- game/new_game.py | 2 +- game/points.py | 4 ++-- game/process_guess.py | 37 +++++++++++++++++++++++++++++++++++++ 9 files changed, 93 insertions(+), 34 deletions(-) create mode 100644 game/clear.py diff --git a/Dockerfile b/Dockerfile index 1850210..4b5495c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,4 +15,4 @@ FROM build AS run ENV discord_token "" ENV database_path "/tmp/baseball.db" -CMD ["python", "/app/main.py"] +CMD ["python", "-u", "/app/main.py"] \ No newline at end of file diff --git a/game/base.py b/game/base.py index a57ccbe..5074ec8 100644 --- a/game/base.py +++ b/game/base.py @@ -4,6 +4,8 @@ # pylint: disable=missing-module-docstring +import logging + from database.models import database, GameModel as Game @@ -24,6 +26,18 @@ class BaseGameManager: # Discord client instance self.discord = None + logger = logging.getLogger() + console = logging.StreamHandler() + + format_str = '%(asctime)s\t%(levelname)s -- %(processName)s %(filename)s:%(lineno)s -- %(message)s' + console.setFormatter(logging.Formatter(format_str)) + + logger.addHandler(console) + + logger.setLevel(logging.DEBUG) + + self.logger = logger + def __enter__(self): """ Allows use of `with Game() as game` for try/except statements diff --git a/game/clear.py b/game/clear.py new file mode 100644 index 0000000..14d2e42 --- /dev/null +++ b/game/clear.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +# Copyright 2022 - c0de +# Licensed under the MIT License (https://opensource.org/licenses/MIT) + +# pylint: disable=missing-module-docstring,too-few-public-methods + +from database.models import PlayerModel as Player +from game.base import BaseGameManager + + +class ClearManager(BaseGameManager): + """Commands that run when a player clears the session leaderboard""" + + def __init__(self): + super().__init__() + self.commands.append(("clear", self.clear)) + + async def clear(self): + """Clear command - Clears the session scoreboard""" + + players = Player.select(Player.player_id, Player.total_points) + + for player in players: + player.total_points = 0 + + Player.bulk_update(players, fields=[Player.total_points]) + + clear_message = "The score has been cleared!" + + await self.message.channel.send(clear_message) diff --git a/game/end_game.py b/game/end_game.py index f269dcf..ec52fbd 100644 --- a/game/end_game.py +++ b/game/end_game.py @@ -12,42 +12,20 @@ from game.process_guess import ProcessGuess class EndGameManager(BaseGameManager): - """Commands that run at the end of a game""" + """Commands that run at the end of a play""" def __init__(self): super().__init__() self.commands.append(("resolve", self.stop)) - def __stop_args__(self): - pieces = self.message.content.split() - - if len(pieces) == 2: - return pieces[1], False, None, None - - if len(pieces) == 4: - return pieces[1], True, pieces[2], pieces[3] - - return None, False, None, None - async def update_pitch_value(self): """Update game state database for closing arguments""" - # Determine arguments - pitch_value, has_batter, batter_id, batter_guess = self.__stop_args__() + pitch_value = self.message.content.split()[1] if not pitch_value: return await self.message.channel.send( f"Invalid command <@{ str(self.message.author.id) }>!" ) - if has_batter: - player_id = batter_id[3:] - player_name = await self.discord.get_user(int(player_id).name) - Guess.create( - game_id=self.game.game_id, - player_id=player_id, - player_name=player_name, - guess=int(batter_guess), - ).save() - # Save the pitch value Game.update( { @@ -76,7 +54,7 @@ class EndGameManager(BaseGameManager): ) # Discard the game if there weren't enough players - if guess_count < 3: + if guess_count < 2: self.game = None self.is_running = False return await self.message.channel.send( @@ -85,7 +63,7 @@ class EndGameManager(BaseGameManager): message = ( "Closed this play! Here are the results\n" - + "PLAYER | GUESS | DIFFERENCE | POINTS GAINED | TOTAL POINTS\n" + + "__PLAYER | GUESS | DIFFERENCE | POINTS GAINED | TOTAL POINTS__\n" ) pitch_value = await self.update_pitch_value() diff --git a/game/help.py b/game/help.py index dae7229..9e7f01b 100644 --- a/game/help.py +++ b/game/help.py @@ -24,10 +24,9 @@ class HelpManager(BaseGameManager): + "!guess - While a game is running, add a guess" + " (or update an existing one) from 1-1000\n" + "!resolve - 1-1000 to resolve the game\n" - + " You can also add a batter's guess with: " - + "!resolve \n" + + "!clear - Clear the session scoreboard\n" + "!points - Shows a table of the most recent players, and their scores\n" - + "!reset - Removes all players and total points" + + "!reset - Removes all players and total points\n" + "!help - Shows this message" ) diff --git a/game/manager.py b/game/manager.py index 28210aa..5dfe589 100644 --- a/game/manager.py +++ b/game/manager.py @@ -16,10 +16,11 @@ from game.guess import GuessManager from game.points import PointsManager from game.reset import ResetManager from game.help import HelpManager +from game.clear import ClearManager class GameManager( - NewGameManager, EndGameManager, GuessManager, PointsManager, ResetManager, HelpManager + NewGameManager, EndGameManager, GuessManager, PointsManager, ResetManager, HelpManager, ClearManager ): """ Represents what this bot is able to do on a channel (or DMs) diff --git a/game/new_game.py b/game/new_game.py index 7b12849..e781665 100644 --- a/game/new_game.py +++ b/game/new_game.py @@ -13,7 +13,7 @@ class NewGameManager(BaseGameManager): def __init__(self): super().__init__() - self.commands.append(("braveball", self.start)) + self.commands.append(("bb", self.start)) async def start(self): """ diff --git a/game/points.py b/game/points.py index b0bc284..58a7b7e 100644 --- a/game/points.py +++ b/game/points.py @@ -9,7 +9,7 @@ from game.base import BaseGameManager class PointsManager(BaseGameManager): - """Commands that run when a player makes a guess""" + """Commands that run when a player wants to view the session leaderboard""" def __init__(self): super().__init__() @@ -27,7 +27,7 @@ class PointsManager(BaseGameManager): players = Player.select( Player.player_name, Player.total_points, Player.last_update - ).order_by(Player.last_update.desc(), Player.total_points.desc()) + ).order_by(Player.total_points.desc()) for player in players: message += ( diff --git a/game/process_guess.py b/game/process_guess.py index f0b907a..e5325a1 100644 --- a/game/process_guess.py +++ b/game/process_guess.py @@ -40,6 +40,7 @@ class ProcessGuess: Player.player_id, Player.player_name, Player.total_points, + Guess.difference ) .join(Player) .where( @@ -71,14 +72,25 @@ class ProcessGuess: def get_difference(self, guess=None): """Difference calculation, includes "loop over" effect""" + self.game_manager.logger.debug("get_difference") + + self.game_manager.logger.debug(guess if guess else "") + if not guess: guess = self.guess.guess + self.game_manager.logger.debug(f"guess: {guess}") + difference = abs(guess - self.pitch_value) + self.game_manager.logger.debug(f"Difference:{difference}") + if difference > 500: difference = 1000 - difference + self.game_manager.logger.debug("Diff loop over 500") + self.game_manager.logger.debug(f"{difference}") + self.difference = difference return self.difference @@ -88,32 +100,51 @@ class ProcessGuess: they are (within range of 0-500) to the pitch_value """ + self.game_manager.logger.debug("> get_difference_score") + self.game_manager.logger.debug(self.difference) + if self.difference == 0: self.difference_score = 15 + self.game_manager.logger.debug("0 Diff") elif self.difference > 0 and self.difference < 21: self.difference_score = 8 + self.game_manager.logger.debug("0 to 20 diff") elif self.difference > 20 and self.difference < 51: self.difference_score = 5 + self.game_manager.logger.debug("21 to 50 Diff") elif self.difference > 50 and self.difference < 101: self.difference_score = 3 + self.game_manager.logger.debug("51 to 100 Diff") elif self.difference > 100 and self.difference < 151: self.difference_score = 2 + self.game_manager.logger.debug("101 to 150 Diff") elif self.difference > 150 and self.difference < 201: self.difference_score = 1 + self.game_manager.logger.debug("151 to 200 Diff") elif self.difference > 200 and self.difference < 495: self.difference_score = 0 + self.game_manager.logger.debug("Diff too big") else: self.difference_score = -5 + self.game_manager.logger.debug("Big succ") return self.difference_score def get_winner_loser(self): """Determine which guesses are closest and furthest from the pitch_value""" + + self.game_manager.logger.debug("> get_winner_loser") + guess_values = [record.guess for record in self.get_guesses()] + self.game_manager.logger.debug(", ".join([str(guess) for guess in guess_values])) + # Closest to the pitch_value winner = min(guess_values, key=lambda guess: self.get_difference(guess)) + self.game_manager.logger.debug(f"winner: {winner}") + # Furthest from the pitch_value loser = max(guess_values, key=lambda guess: self.get_difference(guess)) + self.game_manager.logger.debug(f"loser: {loser}") return winner, loser @@ -129,6 +160,9 @@ class ProcessGuess: for guess in self.get_guesses(): self.guess = guess + self.game_manager.logger.debug(f"Current guess: {guess}") + + difference = self.get_difference() difference_score = self.get_difference_score() self.update_difference_value() @@ -136,10 +170,13 @@ class ProcessGuess: self.message += f"{guess.player.player_name} | {guess.guess} | {difference} | {difference_score} | {(guess.player.total_points + difference_score)}\n" + self.game_manager.logger.debug(f"new total: {(guess.player.total_points + difference_score)}") + if guess.guess == winner: closest_player_id = guess.player.player_id if guess.guess == loser: furthest_player_id = guess.player.player_id + self.game_manager.logger.debug(self.message) return self.message, closest_player_id, furthest_player_id