diff --git a/acro/ircplugin.py b/acro/ircplugin.py index 07114d2..6b4af87 100644 --- a/acro/ircplugin.py +++ b/acro/ircplugin.py @@ -1,5 +1,4 @@ """An acromania style game for IRC.""" - import logging import random import threading @@ -9,40 +8,34 @@ from irc.client import NickMask, is_channel from ircbot.lib import Plugin - -log = logging.getLogger('acro.ircplugin') +logger = logging.getLogger('acro.ircplugin') class Acro(Plugin): - """Play a game where users come up with silly definitions for randomly-generated acronyms.""" class AcroGame(object): - """Track game details.""" - + def __init__(self): """Initialize basic stuff.""" - # running state self.state = 0 self.quit = False self.scores = dict() self.rounds = [] self.channel = '' - + class AcroRound(object): - """Track a particular round of a game.""" - + def __init__(self): """Initialize basic stuff.""" - self.acro = "" self.submissions = dict() self.sub_shuffle = [] self.votes = dict() - + # default options self.seconds_to_submit = 60 self.seconds_to_vote = 45 @@ -51,7 +44,6 @@ class Acro(Plugin): def __init__(self, bot, connection, event): """Set up the game tracking and such.""" - # game state self.game = self.AcroGame() @@ -59,7 +51,6 @@ class Acro(Plugin): def start(self): """Set up handlers.""" - self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!acro\s+status$', self.handle_status, -20) self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!acro\s+start$', @@ -75,7 +66,6 @@ class Acro(Plugin): def stop(self): """Tear down handlers.""" - self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_status) self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_start) self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_submit) @@ -86,7 +76,6 @@ class Acro(Plugin): def handle_status(self, connection, event, match): """Return the status of the currently-running game, if there is one.""" - if self.game.state == 0: return self.bot.reply(event, "there currently isn't a game running.") else: @@ -94,7 +83,6 @@ class Acro(Plugin): def handle_start(self, connection, event, match): """Start the game, notify the channel, and begin timers.""" - if self.game.state != 0: return self.bot.reply(event, "the game is already running.") else: @@ -105,7 +93,6 @@ class Acro(Plugin): def handle_submit(self, connection, event, match): """Take a submission for an acro.""" - nick = NickMask(event.source).nick submission = match.group(1) @@ -113,7 +100,6 @@ class Acro(Plugin): def handle_vote(self, connection, event, match): """Take a vote for an acro.""" - nick = NickMask(event.source).nick vote = match.group(1) @@ -121,26 +107,22 @@ class Acro(Plugin): def handle_quit(self, connection, event, match): """Quit the game after the current round ends.""" - if self.game.state != 0: self.game.quit = True return self.bot.reply(event, "the game will end after the current round.") def thread_do_process_submissions(self, sleep_time): """Wait for players to provide acro submissions, and then kick off voting.""" - time.sleep(sleep_time) self._start_voting() def thread_do_process_votes(self): """Wait for players to provide votes, and then continue or quit.""" - time.sleep(self.game.rounds[-1].seconds_to_vote) self._end_current_round() def _start_new_game(self, channel): """Begin a new game, which will have multiple rounds.""" - self.game.state = 1 self.game.channel = channel self.bot.reply(None, "starting a new game of acro. it will run until you tell it to quit.", @@ -150,12 +132,12 @@ class Acro(Plugin): def _start_new_round(self): """Start a new round for play.""" - self.game.state = 2 self.game.rounds.append(self.AcroRound()) acro = self._generate_acro() self.game.rounds[-1].acro = acro - sleep_time = self.game.rounds[-1].seconds_to_submit + (self.game.rounds[-1].seconds_to_submit_step * (len(acro)-3)) + sleep_time = (self.game.rounds[-1].seconds_to_submit + + (self.game.rounds[-1].seconds_to_submit_step * (len(acro)-3))) self.bot.reply(None, "the round has started! your acronym is '{0:s}'. " "submit within {1:d} seconds via !acro submit [meaning]".format(acro, sleep_time), @@ -166,17 +148,16 @@ class Acro(Plugin): t.start() @staticmethod - def _generate_acro(): + def _generate_acro(): # noqa: C901 """Generate an acro to play with. Letter frequencies pinched from http://www.math.cornell.edu/~mec/2003-2004/cryptography/subs/frequencies.html """ - acro = [] # generate acro 3-8 characters long - for i in range(1, random.randint(4, 9)): - letter = random.randint(1, 182303) + for i in range(1, random.SystemRandom.randint(4, 9)): + letter = random.SystemRandom.randint(1, 182303) if letter <= 21912: acro.append('E') elif letter <= 38499: @@ -234,7 +215,6 @@ class Acro(Plugin): def _take_acro_submission(self, nick, submission): """Take an acro submission and record it.""" - if self.game.state == 2: sub_acro = self._turn_text_into_acro(submission) @@ -247,7 +227,6 @@ class Acro(Plugin): @staticmethod def _turn_text_into_acro(text): """Turn text into an acronym.""" - words = text.split() acro = [] for w in words: @@ -256,10 +235,9 @@ class Acro(Plugin): def _start_voting(self): """Begin the voting period.""" - self.game.state = 3 self.game.rounds[-1].sub_shuffle = list(self.game.rounds[-1].submissions.keys()) - random.shuffle(self.game.rounds[-1].sub_shuffle) + random.SystemRandom.shuffle(self.game.rounds[-1].sub_shuffle) self.bot.reply(None, "here are the results. vote with !acro vote [number]", explicit_target=self.game.channel) self._print_round_acros() @@ -269,21 +247,19 @@ class Acro(Plugin): def _print_round_acros(self): """Take the current round's acros and spit them to the channel.""" - i = 0 for s in self.game.rounds[-1].sub_shuffle: - log.debug("%s is %s", str(i), s) + logger.debug("%s is %s", str(i), s) self.bot.reply(None, " {0:d}: {1:s}".format(i+1, self.game.rounds[-1].submissions[s]), explicit_target=self.game.channel) i += 1 def _take_acro_vote(self, nick, vote): """Take an acro vote and record it.""" - if self.game.state == 3: acros = self.game.rounds[-1].submissions if int(vote) > 0 and int(vote) <= len(acros): - log.debug("%s is %s", vote, self.game.rounds[-1].sub_shuffle[int(vote)-1]) + logger.debug("%s is %s", vote, self.game.rounds[-1].sub_shuffle[int(vote)-1]) key = self.game.rounds[-1].sub_shuffle[int(vote)-1] if key != nick: @@ -296,7 +272,6 @@ class Acro(Plugin): def _end_current_round(self): """Clean up and output for ending the current round.""" - self.game.state = 4 self.bot.reply(None, "voting's over! here are the scores for the round:", explicit_target=self.game.channel) self._print_round_scores() @@ -308,7 +283,6 @@ class Acro(Plugin): def _print_round_scores(self): """For the acros in the round, find the votes for them.""" - i = 0 for s in list(self.game.rounds[-1].submissions.keys()): votes = [x for x in list(self.game.rounds[-1].votes.values()) if x == s] @@ -318,7 +292,6 @@ class Acro(Plugin): def _add_round_scores_to_game_scores(self): """Apply the final round scores to the totall scores for the game.""" - for s in list(self.game.rounds[-1].votes.values()): votes = [x for x in list(self.game.rounds[-1].votes.values()) if x == s] if s in list(self.game.scores.keys()): @@ -328,7 +301,6 @@ class Acro(Plugin): def _continue_or_quit(self): """Decide whether the game should continue or quit.""" - if self.game.state == 4: if self.game.quit: self._end_game() @@ -337,7 +309,6 @@ class Acro(Plugin): def _end_game(self): """Clean up the entire game.""" - self.game.state = 0 self.game.quit = False self.bot.reply(None, "game's over! here are the final scores:", explicit_target=self.game.channel) @@ -345,7 +316,6 @@ class Acro(Plugin): def _print_game_scores(self): """Print the final calculated scores.""" - for s in list(self.game.scores.keys()): self.bot.reply(None, " {0:s}: {1:d}".format(s, self.game.scores[s]), explicit_target=self.game.channel)