diff --git a/CAH/__init__.py b/CAH/__init__.py index 43b1091..eff3b60 100644 --- a/CAH/__init__.py +++ b/CAH/__init__.py @@ -42,20 +42,24 @@ import importlib __version__ = "2020.02.24+git" # XXX Replace this with an appropriate author or supybot.Author instance. -__author__ = supybot.Author('James Scott', 'jazzahn', '') -__maintainer__ = getattr(supybot.authors, 'oddluck', - supybot.Author('oddluck', 'oddluck', 'oddluck@riseup.net')) +__author__ = supybot.Author("James Scott", "jazzahn", "") +__maintainer__ = getattr( + supybot.authors, + "oddluck", + supybot.Author("oddluck", "oddluck", "oddluck@riseup.net"), +) # This is a dictionary mapping supybot.Author instances to lists of # contributions. __contributors__ = {} # This is a url where the most recent plugin package can be downloaded. -__url__ = 'https://github.com/oddluck/limnoria-plugins/' +__url__ = "https://github.com/oddluck/limnoria-plugins/" from . import config from . import plugin -importlib.reload(plugin) # In case we're being reloaded. + +importlib.reload(plugin) # In case we're being reloaded. # Add more reloads here if you add third-party modules and want them to be # reloaded when this plugin is reloaded. Don't forget to import them as well! diff --git a/CAH/cah.py b/CAH/cah.py index 9c334e5..059662a 100644 --- a/CAH/cah.py +++ b/CAH/cah.py @@ -31,25 +31,28 @@ from random import choice import os import json -from . import test # Settings you change -card_folder = 'cards' -answer_cards_file_names = ['answer_main', 'custom_answer_cards'] -question_cards_file_name = ['question_main', 'custom_question_cards'] -blank_format = '__________' +card_folder = "cards" +answer_cards_file_names = ["answer_main", "custom_answer_cards"] +question_cards_file_name = ["question_main", "custom_question_cards"] +blank_format = "__________" # Settings that are used -#this is one level higher than it should be +# this is one level higher than it should be base_directory = os.path.dirname(os.path.abspath(__file__)) + class Deck(object): def __init__(self): - self.answerDb = self.parse_card_file('answer') - self.questionDb = self.parse_card_file('question') + self.answerDb = self.parse_card_file("answer") + self.questionDb = self.parse_card_file("question") def parse_card_file(self, card_type): - card_type_map = {'answer': answer_cards_file_names, 'question': question_cards_file_name} + card_type_map = { + "answer": answer_cards_file_names, + "question": question_cards_file_name, + } # Read text file into a list containing only strings of text for the card card_text_list = [] @@ -71,7 +74,7 @@ class Deck(object): # Prepare card text by removing control chars card = card.rstrip() # Figure out how many answers are required for a question card - if card_type == 'question': + if card_type == "question": answers = self.count_answers(card) card_object_list.append(Card(index, card_type, card, answers=answers)) else: @@ -86,14 +89,17 @@ class Deck(object): return blanks def drawCard(self, typeOfCard): - typeMap = {'answer': self.answerDb, 'question': self.questionDb} + typeMap = {"answer": self.answerDb, "question": self.questionDb} type = typeMap[typeOfCard] card = choice(type) type.remove(card) return card def __repr__(self): - return json.dumps({'questions': len(self.questionDb), 'answers': len(self.answerDb)}) + return json.dumps( + {"questions": len(self.questionDb), "answers": len(self.answerDb)} + ) + class Card(object): def __init__(self, id, type, text, **kwargs): @@ -102,12 +108,13 @@ class Card(object): self.text = text for key, value in kwargs.items(): setattr(self, key, value) + def __str__(self): return self.text class Game(object): - def __init__(self, players, round_limit = 5): + def __init__(self, players, round_limit=5): self.round_limit = round_limit self.deck = Deck() self.players = self.build_player_list(players) @@ -129,8 +136,8 @@ class Game(object): else: raise IndexError - self.question = self.deck.drawCard('question') - return {'question': self.question, 'hands': self.players} + self.question = self.deck.drawCard("question") + return {"question": self.question, "hands": self.players} def end_round(self, winner_name, cards_played): self.score_keeping(winner_name) @@ -155,15 +162,17 @@ class Game(object): cardRange = list(range(5)) while cardInput not in cardRange: try: - cardInput = int(input('%s Pick a Card: ' % player)) - 1 + cardInput = int(input("%s Pick a Card: " % player)) - 1 except ValueError: pass + class Round(object): def __init__(self, deck, players): - self.question = deck.drawCard('question') + self.question = deck.drawCard("question") self.players = players + class PlayerHand(object): def __init__(self, deck): self.card_list = [] @@ -171,35 +180,38 @@ class PlayerHand(object): def deal_hand(self, deck): while len(self.card_list) < 5: - card = deck.drawCard('answer') + card = deck.drawCard("answer") self.card_list.append(card) def text_list(self): card_text = [] for index, card in enumerate(self.card_list): - card_text.append ( card.text) + card_text.append(card.text) return card_text def showHand(self): - print('%s' % self.text_list()) + print("%s" % self.text_list()) - - -if __name__=="__main__": - game = Game(['Bear','Swim', 'Jazz']) - print("\nGame started with the following players: %s \n" % list(game.players.keys())) +if __name__ == "__main__": + game = Game(["Bear", "Swim", "Jazz"]) + print( + "\nGame started with the following players: %s \n" % list(game.players.keys()) + ) round = game.next_round() print("The first question is: %s \n" % game.question.text) print("Swim's hand the easy way:") - game.players['Swim'].showHand() + game.players["Swim"].showHand() print("\nJazz's hand in a weird way") - round['hands']['Jazz'].showHand() + round["hands"]["Jazz"].showHand() print("\nBear's hand the hard way:") - for index, card in enumerate(game.players['Bear'].card_list): - print('%s: %s' % (index + 1, card.text)) + for index, card in enumerate(game.players["Bear"].card_list): + print("%s: %s" % (index + 1, card.text)) - print("\nEnd the round by picking a random cards amd winner: %s" % str(test.build_end_round_data(game))) + print( + "\nEnd the round by picking a random cards amd winner: %s" + % str(test.build_end_round_data(game)) + ) diff --git a/CAH/config.py b/CAH/config.py index c646c54..6ba69bb 100644 --- a/CAH/config.py +++ b/CAH/config.py @@ -31,16 +31,18 @@ import supybot.conf as conf import supybot.registry as registry + def configure(advanced): # This will be called by supybot to configure this module. advanced is # a bool that specifies whether the user identified himself as an advanced # user or not. You should effect your configuration by manipulating the # registry as appropriate. from supybot.questions import expect, anything, something, yn - conf.registerPlugin('CAH', True) + + conf.registerPlugin("CAH", True) -CAH = conf.registerPlugin('CAH') +CAH = conf.registerPlugin("CAH") # This is where your configuration variables (if any) should go. For example: # conf.registerGlobalValue(Cah, 'someConfigVariableName', # registry.Boolean(False, """Help for someConfigVariableName.""")) diff --git a/CAH/plugin.py b/CAH/plugin.py index 6f2d793..3b261fe 100644 --- a/CAH/plugin.py +++ b/CAH/plugin.py @@ -38,7 +38,7 @@ import supybot.callbacks as callbacks from random import randint -import operator +import operator from .cah import Game, base_directory, card_folder, blank_format @@ -46,6 +46,7 @@ import time import os import re + class CAH(callbacks.Plugin): """Cards Against Humanity""" @@ -58,7 +59,8 @@ class CAH(callbacks.Plugin): class CAHGame(object): """docstring for Game""" - def __init__(self, irc, channel, numrounds = 5): + + def __init__(self, irc, channel, numrounds=5): self.irc = irc self.channel = channel self.game = None @@ -66,24 +68,26 @@ class CAH(callbacks.Plugin): self.voting = False self.canStart = False self.roundRunning = False - self.running = False + self.running = False self.rounds = numrounds - self.maxPlayers= 5 + self.maxPlayers = 5 self.players = [] self.acceptingWhiteCards = False self.cardsPlayed = {} - + def initGame(self): - schedule.addEvent(self.startgame, time.time() + 60, "start_game_%s" % self.channel) + schedule.addEvent( + self.startgame, time.time() + 60, "start_game_%s" % self.channel + ) ###### UTIL METHODS ########## - + def _msg(self, recip, msg): - self.irc.queueMsg(ircmsgs.privmsg(recip,msg)) + self.irc.queueMsg(ircmsgs.privmsg(recip, msg)) def _notice(self, recip, msg): - self.irc.queueMsg(ircmsgs.notice(recip,msg)) - + self.irc.queueMsg(ircmsgs.notice(recip, msg)) + def _printBlackCard(self, recip): cah = self.game self._msg(recip, "Black Card: \x02\x030,1%s\x0F" % (cah.question.text)) @@ -92,8 +96,14 @@ class CAH(callbacks.Plugin): enumeratedHand = [] cah = self.game for position, card in enumerate(cah.players[nick].card_list): - enumeratedHand.append("\x02\x031,00%s: %s\x0F" % (position + 1, card.text)) - self._notice(nick, "White Cards: %s Please respond with playcard [number]" % (', '.join(enumeratedHand))) + enumeratedHand.append( + "\x02\x031,00%s: %s\x0F" % (position + 1, card.text) + ) + self._notice( + nick, + "White Cards: %s Please respond with playcard [number]" + % (", ".join(enumeratedHand)), + ) def _displayPlayedCards(self): channel = self.channel @@ -117,11 +127,10 @@ class CAH(callbacks.Plugin): elif highscore[0][1] == score: highscore.append([nick, score]) if len(highscore) > 0: - return (highscore[randint(0, len(highscore) -1)], True) + return (highscore[randint(0, len(highscore) - 1)], True) else: return (highscore[0], False) - def _tallyVotes(self, votes): ties = [] winningCanidate = [] @@ -141,17 +150,16 @@ class CAH(callbacks.Plugin): winningCanidate.append((canidate, count)) if len(winningCanidate) > 1: - return (winningCanidate[randint(0, len(winningCanidate) -1)], True) + return (winningCanidate[randint(0, len(winningCanidate) - 1)], True) return (winningCanidate[0], False) - ###### END UTIL METHODS ####### ###### PRE GAME LOGIC ######## def startgame(self): - #heh fix this - game = self + # heh fix this + game = self if game.canStart: if len(game.players) < 2: self._msg(channel, "I need more players.") @@ -159,15 +167,15 @@ class CAH(callbacks.Plugin): game.canStart = False game.running = True game.game = Game(game.players, game.rounds) - #start game logic - self.nextround() + # start game logic + self.nextround() ###### END PRE GAME LOGIC ###### ###### START GAME LOGIC ######## def playcard(self, nick, cardNumbers): - game = self + game = self cah = game.game cardlist = [] cards = cah.players[nick].card_list @@ -188,27 +196,33 @@ class CAH(callbacks.Plugin): try: self.cardsPlayed = {} cah.next_round() - #Print Black Card to channel. + # Print Black Card to channel. self._printBlackCard(self.channel) for nick in self.players: self._msgHandToPlayer(nick) - self._msg(channel, "The white cards have been sent to players, you have 60 seconds to choose.") + self._msg( + channel, + "The white cards have been sent to players, you have 60 seconds to choose.", + ) self.acceptingWhiteCards = True - #TODO: do we need a round flag? + # TODO: do we need a round flag? schedule.addEvent(self.endround, time.time() + 60, "round_%s" % channel) except Exception: - #TODO: add no more round logic - - #playerScores = sorted(cah.score.iteritems(), key=operator.itemgetter(1), reverse=True) - #scores = [] + # TODO: add no more round logic + + # playerScores = sorted(cah.score.iteritems(), key=operator.itemgetter(1), reverse=True) + # scores = [] winner = None formattedScores = [] print(cah.score) winner = self._findHighScore(cah.score) for name, score in cah.score.items(): formattedScores.append("%s: %d" % (name, score)) - self._msg(channel, "Game Over! %s is the Winner! Scores: %s " % (winner[0][0], ", ".join(formattedScores))) - + self._msg( + channel, + "Game Over! %s is the Winner! Scores: %s " + % (winner[0][0], ", ".join(formattedScores)), + ) def endround(self): channel = self.channel @@ -231,20 +245,20 @@ class CAH(callbacks.Plugin): def startcardvote(self): channel = self.channel - + game = self game.votes = {} game.voted = [] game.voting = True - self._msg(channel, "Please Vote on your favorite. votecard to vote, the entire channel can vote.") + self._msg( + channel, + "Please Vote on your favorite. votecard to vote, the entire channel can vote.", + ) schedule.addEvent(self.stopcardvote, time.time() + 60, "vote_%s" % channel) - - - def stopcardvote(self): - - #TODO: NOt quite done here + + # TODO: NOt quite done here if self.voting: game = self game.voting = False @@ -252,10 +266,12 @@ class CAH(callbacks.Plugin): print(winner) game.game.end_round(winner[0][0], self.cardsPlayed) game.voted = [] - game._msg(self.channel, "%s wins the round!" % ircutils.bold(winner[0][0])) - #game._msg(self.channel, "%s wins the round with %s" % (ircutils.bold(winner[0][0]), ircutils.bold(filledCard))) + game._msg( + self.channel, "%s wins the round!" % ircutils.bold(winner[0][0]) + ) + # game._msg(self.channel, "%s wins the round with %s" % (ircutils.bold(winner[0][0]), ircutils.bold(filledCard))) game.nextround() - + ###### END VOTING LOGIC ###### def close(self): @@ -267,20 +283,21 @@ class CAH(callbacks.Plugin): schedule.removeEvent("vote_%s" % self.channel) except: pass - try: + try: schedule.removeEvent("start_game_%s" % self.channel) except: - pass + pass + Class = CAHGame ###### CHANNEL COMMANDS ###### def forcestart(self, irc, msg, args): channel = ircutils.toLower(msg.args[0]) if channel in self.games: - try: + try: schedule.removeEvent("start_game_%s" % self.channel) except: - pass + pass self.games[channel].startgame() else: irc.reply("Game not running.") @@ -298,7 +315,14 @@ class CAH(callbacks.Plugin): else: if len(game.players) < game.maxPlayers: game.players.append(nick) - irc.reply("Added, Spots left %d/%d. Current Players %s" % (game.maxPlayers - len(game.players), game.maxPlayers, ', '.join(game.players))) + irc.reply( + "Added, Spots left %d/%d. Current Players %s" + % ( + game.maxPlayers - len(game.players), + game.maxPlayers, + ", ".join(game.players), + ) + ) else: irc.reply("Too many players") if len(game.players) > 1: @@ -310,7 +334,7 @@ class CAH(callbacks.Plugin): """Starts a cards against humanity game, takes an optional arguement of number of rounds""" channel = ircutils.toLower(msg.args[0]) - #TODO: this is prob needs fixing. + # TODO: this is prob needs fixing. if len(args) < 1: numrounds = 5 else: @@ -319,7 +343,10 @@ class CAH(callbacks.Plugin): if channel in self.games: irc.reply("There is a game running currently.") else: - irc.reply("Who wants to play IRC Aganst Humanity? To play reply with: playing", prefixNick=False) + irc.reply( + "Who wants to play IRC Aganst Humanity? To play reply with: playing", + prefixNick=False, + ) self.games[channel] = self.CAHGame(irc, channel, numrounds) self.games[channel].initGame() @@ -329,18 +356,18 @@ class CAH(callbacks.Plugin): For questions cards any number of continuous underscores will be treated as a fill-in-the-blank. """ channel = ircutils.toLower(msg.args[0]) - #TODO: assumes msg[index] is a string + # TODO: assumes msg[index] is a string text = args[1].capitalize().strip() if args[0] == "question": card_file = "custom_question_cards" - text = re.sub(r'_+', blank_format, text) + text = re.sub(r"_+", blank_format, text) elif args[0] == "answer": card_file = "custom_answer_cards" else: irc.reply("Specify type of card as either question or answer.") return path = os.path.abspath(os.path.join(base_directory, card_folder, card_file)) - with open(path, 'w') as file_handle: + with open(path, "w") as file_handle: file_handle.writelines([text]) def stopcah(self, irc, msg, args): @@ -364,16 +391,22 @@ class CAH(callbacks.Plugin): elif nick in game.cardsPlayed: irc.reply("You already played, GET OUT.") elif len(args) < game.game.question.answers: - irc.reply("Hey shitbag I need more cards, this is a %s card question." % game.game.question.answers) + irc.reply( + "Hey shitbag I need more cards, this is a %s card question." + % game.game.question.answers + ) elif len(args) > game.game.question.answers: if game.gane.question.answers == 1: irc.reply("I only want one card you idiot.") - irc.reply("Woah there tiger, I only need %s cards." % game.game.question.answers) + irc.reply( + "Woah there tiger, I only need %s cards." + % game.game.question.answers + ) elif len(args) == game.game.question.answers: game.playcard(nick, args) else: irc.reply("Game not running.") - #TODO: Card decision logic + # TODO: Card decision logic def votecard(self, irc, msg, args): channel = ircutils.toLower(msg.args[0]) @@ -385,7 +418,7 @@ class CAH(callbacks.Plugin): if msg.nick in game.voted: irc.reply("You already voted! This isn't Chicago!") elif vote > len(game.cardsPlayed) or vote < 1: - raise ValueError + raise ValueError else: game.voted.append(msg.nick) try: @@ -394,10 +427,11 @@ class CAH(callbacks.Plugin): game.votes[vote - 1] = 1 irc.reply("vote cast") except ValueError: - irc.reply("I need a value between 1 and %s" % len(game.cardsPlayed)) + irc.reply("I need a value between 1 and %s" % len(game.cardsPlayed)) else: irc.reply("A Game is not running, or the time is not to vote.") + Class = CAH