CAH: fix missing import

This commit is contained in:
oddluck 2020-04-28 22:02:49 +00:00
parent 55484b7c7d
commit e26ef66af8
4 changed files with 144 additions and 92 deletions

View File

@ -42,20 +42,24 @@ import importlib
__version__ = "2020.02.24+git" __version__ = "2020.02.24+git"
# XXX Replace this with an appropriate author or supybot.Author instance. # XXX Replace this with an appropriate author or supybot.Author instance.
__author__ = supybot.Author('James Scott', 'jazzahn', '') __author__ = supybot.Author("James Scott", "jazzahn", "")
__maintainer__ = getattr(supybot.authors, 'oddluck', __maintainer__ = getattr(
supybot.Author('oddluck', 'oddluck', 'oddluck@riseup.net')) supybot.authors,
"oddluck",
supybot.Author("oddluck", "oddluck", "oddluck@riseup.net"),
)
# This is a dictionary mapping supybot.Author instances to lists of # This is a dictionary mapping supybot.Author instances to lists of
# contributions. # contributions.
__contributors__ = {} __contributors__ = {}
# This is a url where the most recent plugin package can be downloaded. # 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 config
from . import plugin 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 # 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! # reloaded when this plugin is reloaded. Don't forget to import them as well!

View File

@ -31,25 +31,28 @@
from random import choice from random import choice
import os import os
import json import json
from . import test
# Settings you change # Settings you change
card_folder = 'cards' card_folder = "cards"
answer_cards_file_names = ['answer_main', 'custom_answer_cards'] answer_cards_file_names = ["answer_main", "custom_answer_cards"]
question_cards_file_name = ['question_main', 'custom_question_cards'] question_cards_file_name = ["question_main", "custom_question_cards"]
blank_format = '__________' blank_format = "__________"
# Settings that are used # 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__)) base_directory = os.path.dirname(os.path.abspath(__file__))
class Deck(object): class Deck(object):
def __init__(self): def __init__(self):
self.answerDb = self.parse_card_file('answer') self.answerDb = self.parse_card_file("answer")
self.questionDb = self.parse_card_file('question') self.questionDb = self.parse_card_file("question")
def parse_card_file(self, card_type): 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 # Read text file into a list containing only strings of text for the card
card_text_list = [] card_text_list = []
@ -71,7 +74,7 @@ class Deck(object):
# Prepare card text by removing control chars # Prepare card text by removing control chars
card = card.rstrip() card = card.rstrip()
# Figure out how many answers are required for a question card # Figure out how many answers are required for a question card
if card_type == 'question': if card_type == "question":
answers = self.count_answers(card) answers = self.count_answers(card)
card_object_list.append(Card(index, card_type, card, answers=answers)) card_object_list.append(Card(index, card_type, card, answers=answers))
else: else:
@ -86,14 +89,17 @@ class Deck(object):
return blanks return blanks
def drawCard(self, typeOfCard): def drawCard(self, typeOfCard):
typeMap = {'answer': self.answerDb, 'question': self.questionDb} typeMap = {"answer": self.answerDb, "question": self.questionDb}
type = typeMap[typeOfCard] type = typeMap[typeOfCard]
card = choice(type) card = choice(type)
type.remove(card) type.remove(card)
return card return card
def __repr__(self): 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): class Card(object):
def __init__(self, id, type, text, **kwargs): def __init__(self, id, type, text, **kwargs):
@ -102,12 +108,13 @@ class Card(object):
self.text = text self.text = text
for key, value in kwargs.items(): for key, value in kwargs.items():
setattr(self, key, value) setattr(self, key, value)
def __str__(self): def __str__(self):
return self.text return self.text
class Game(object): class Game(object):
def __init__(self, players, round_limit = 5): def __init__(self, players, round_limit=5):
self.round_limit = round_limit self.round_limit = round_limit
self.deck = Deck() self.deck = Deck()
self.players = self.build_player_list(players) self.players = self.build_player_list(players)
@ -129,8 +136,8 @@ class Game(object):
else: else:
raise IndexError raise IndexError
self.question = self.deck.drawCard('question') self.question = self.deck.drawCard("question")
return {'question': self.question, 'hands': self.players} return {"question": self.question, "hands": self.players}
def end_round(self, winner_name, cards_played): def end_round(self, winner_name, cards_played):
self.score_keeping(winner_name) self.score_keeping(winner_name)
@ -155,15 +162,17 @@ class Game(object):
cardRange = list(range(5)) cardRange = list(range(5))
while cardInput not in cardRange: while cardInput not in cardRange:
try: try:
cardInput = int(input('%s Pick a Card: ' % player)) - 1 cardInput = int(input("%s Pick a Card: " % player)) - 1
except ValueError: except ValueError:
pass pass
class Round(object): class Round(object):
def __init__(self, deck, players): def __init__(self, deck, players):
self.question = deck.drawCard('question') self.question = deck.drawCard("question")
self.players = players self.players = players
class PlayerHand(object): class PlayerHand(object):
def __init__(self, deck): def __init__(self, deck):
self.card_list = [] self.card_list = []
@ -171,35 +180,38 @@ class PlayerHand(object):
def deal_hand(self, deck): def deal_hand(self, deck):
while len(self.card_list) < 5: while len(self.card_list) < 5:
card = deck.drawCard('answer') card = deck.drawCard("answer")
self.card_list.append(card) self.card_list.append(card)
def text_list(self): def text_list(self):
card_text = [] card_text = []
for index, card in enumerate(self.card_list): for index, card in enumerate(self.card_list):
card_text.append ( card.text) card_text.append(card.text)
return card_text return card_text
def showHand(self): def showHand(self):
print('%s' % self.text_list()) print("%s" % self.text_list())
if __name__ == "__main__":
game = Game(["Bear", "Swim", "Jazz"])
if __name__=="__main__": print(
game = Game(['Bear','Swim', 'Jazz']) "\nGame started with the following players: %s \n" % list(game.players.keys())
print("\nGame started with the following players: %s \n" % list(game.players.keys())) )
round = game.next_round() round = game.next_round()
print("The first question is: %s \n" % game.question.text) print("The first question is: %s \n" % game.question.text)
print("Swim's hand the easy way:") print("Swim's hand the easy way:")
game.players['Swim'].showHand() game.players["Swim"].showHand()
print("\nJazz's hand in a weird way") print("\nJazz's hand in a weird way")
round['hands']['Jazz'].showHand() round["hands"]["Jazz"].showHand()
print("\nBear's hand the hard way:") print("\nBear's hand the hard way:")
for index, card in enumerate(game.players['Bear'].card_list): for index, card in enumerate(game.players["Bear"].card_list):
print('%s: %s' % (index + 1, card.text)) 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))
)

View File

@ -31,16 +31,18 @@
import supybot.conf as conf import supybot.conf as conf
import supybot.registry as registry import supybot.registry as registry
def configure(advanced): def configure(advanced):
# This will be called by supybot to configure this module. advanced is # This will be called by supybot to configure this module. advanced is
# a bool that specifies whether the user identified himself as an advanced # a bool that specifies whether the user identified himself as an advanced
# user or not. You should effect your configuration by manipulating the # user or not. You should effect your configuration by manipulating the
# registry as appropriate. # registry as appropriate.
from supybot.questions import expect, anything, something, yn 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: # This is where your configuration variables (if any) should go. For example:
# conf.registerGlobalValue(Cah, 'someConfigVariableName', # conf.registerGlobalValue(Cah, 'someConfigVariableName',
# registry.Boolean(False, """Help for someConfigVariableName.""")) # registry.Boolean(False, """Help for someConfigVariableName."""))

View File

@ -46,6 +46,7 @@ import time
import os import os
import re import re
class CAH(callbacks.Plugin): class CAH(callbacks.Plugin):
"""Cards Against Humanity""" """Cards Against Humanity"""
@ -58,7 +59,8 @@ class CAH(callbacks.Plugin):
class CAHGame(object): class CAHGame(object):
"""docstring for Game""" """docstring for Game"""
def __init__(self, irc, channel, numrounds = 5):
def __init__(self, irc, channel, numrounds=5):
self.irc = irc self.irc = irc
self.channel = channel self.channel = channel
self.game = None self.game = None
@ -66,23 +68,25 @@ class CAH(callbacks.Plugin):
self.voting = False self.voting = False
self.canStart = False self.canStart = False
self.roundRunning = False self.roundRunning = False
self.running = False self.running = False
self.rounds = numrounds self.rounds = numrounds
self.maxPlayers= 5 self.maxPlayers = 5
self.players = [] self.players = []
self.acceptingWhiteCards = False self.acceptingWhiteCards = False
self.cardsPlayed = {} self.cardsPlayed = {}
def initGame(self): 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 ########## ###### UTIL METHODS ##########
def _msg(self, recip, msg): def _msg(self, recip, msg):
self.irc.queueMsg(ircmsgs.privmsg(recip,msg)) self.irc.queueMsg(ircmsgs.privmsg(recip, msg))
def _notice(self, 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): def _printBlackCard(self, recip):
cah = self.game cah = self.game
@ -92,8 +96,14 @@ class CAH(callbacks.Plugin):
enumeratedHand = [] enumeratedHand = []
cah = self.game cah = self.game
for position, card in enumerate(cah.players[nick].card_list): for position, card in enumerate(cah.players[nick].card_list):
enumeratedHand.append("\x02\x031,00%s: %s\x0F" % (position + 1, card.text)) enumeratedHand.append(
self._notice(nick, "White Cards: %s Please respond with playcard <number> [number]" % (', '.join(enumeratedHand))) "\x02\x031,00%s: %s\x0F" % (position + 1, card.text)
)
self._notice(
nick,
"White Cards: %s Please respond with playcard <number> [number]"
% (", ".join(enumeratedHand)),
)
def _displayPlayedCards(self): def _displayPlayedCards(self):
channel = self.channel channel = self.channel
@ -117,11 +127,10 @@ class CAH(callbacks.Plugin):
elif highscore[0][1] == score: elif highscore[0][1] == score:
highscore.append([nick, score]) highscore.append([nick, score])
if len(highscore) > 0: if len(highscore) > 0:
return (highscore[randint(0, len(highscore) -1)], True) return (highscore[randint(0, len(highscore) - 1)], True)
else: else:
return (highscore[0], False) return (highscore[0], False)
def _tallyVotes(self, votes): def _tallyVotes(self, votes):
ties = [] ties = []
winningCanidate = [] winningCanidate = []
@ -141,16 +150,15 @@ class CAH(callbacks.Plugin):
winningCanidate.append((canidate, count)) winningCanidate.append((canidate, count))
if len(winningCanidate) > 1: if len(winningCanidate) > 1:
return (winningCanidate[randint(0, len(winningCanidate) -1)], True) return (winningCanidate[randint(0, len(winningCanidate) - 1)], True)
return (winningCanidate[0], False) return (winningCanidate[0], False)
###### END UTIL METHODS ####### ###### END UTIL METHODS #######
###### PRE GAME LOGIC ######## ###### PRE GAME LOGIC ########
def startgame(self): def startgame(self):
#heh fix this # heh fix this
game = self game = self
if game.canStart: if game.canStart:
if len(game.players) < 2: if len(game.players) < 2:
@ -159,7 +167,7 @@ class CAH(callbacks.Plugin):
game.canStart = False game.canStart = False
game.running = True game.running = True
game.game = Game(game.players, game.rounds) game.game = Game(game.players, game.rounds)
#start game logic # start game logic
self.nextround() self.nextround()
###### END PRE GAME LOGIC ###### ###### END PRE GAME LOGIC ######
@ -188,27 +196,33 @@ class CAH(callbacks.Plugin):
try: try:
self.cardsPlayed = {} self.cardsPlayed = {}
cah.next_round() cah.next_round()
#Print Black Card to channel. # Print Black Card to channel.
self._printBlackCard(self.channel) self._printBlackCard(self.channel)
for nick in self.players: for nick in self.players:
self._msgHandToPlayer(nick) 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 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) schedule.addEvent(self.endround, time.time() + 60, "round_%s" % channel)
except Exception: except Exception:
#TODO: add no more round logic # TODO: add no more round logic
#playerScores = sorted(cah.score.iteritems(), key=operator.itemgetter(1), reverse=True) # playerScores = sorted(cah.score.iteritems(), key=operator.itemgetter(1), reverse=True)
#scores = [] # scores = []
winner = None winner = None
formattedScores = [] formattedScores = []
print(cah.score) print(cah.score)
winner = self._findHighScore(cah.score) winner = self._findHighScore(cah.score)
for name, score in cah.score.items(): for name, score in cah.score.items():
formattedScores.append("%s: %d" % (name, score)) 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): def endround(self):
channel = self.channel channel = self.channel
@ -236,15 +250,15 @@ class CAH(callbacks.Plugin):
game.votes = {} game.votes = {}
game.voted = [] game.voted = []
game.voting = True game.voting = True
self._msg(channel, "Please Vote on your favorite. votecard <number> to vote, the entire channel can vote.") self._msg(
channel,
"Please Vote on your favorite. votecard <number> to vote, the entire channel can vote.",
)
schedule.addEvent(self.stopcardvote, time.time() + 60, "vote_%s" % channel) schedule.addEvent(self.stopcardvote, time.time() + 60, "vote_%s" % channel)
def stopcardvote(self): def stopcardvote(self):
#TODO: NOt quite done here # TODO: NOt quite done here
if self.voting: if self.voting:
game = self game = self
game.voting = False game.voting = False
@ -252,8 +266,10 @@ class CAH(callbacks.Plugin):
print(winner) print(winner)
game.game.end_round(winner[0][0], self.cardsPlayed) game.game.end_round(winner[0][0], self.cardsPlayed)
game.voted = [] game.voted = []
game._msg(self.channel, "%s wins the round!" % ircutils.bold(winner[0][0])) game._msg(
#game._msg(self.channel, "%s wins the round with %s" % (ircutils.bold(winner[0][0]), ircutils.bold(filledCard))) 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() game.nextround()
###### END VOTING LOGIC ###### ###### END VOTING LOGIC ######
@ -271,6 +287,7 @@ class CAH(callbacks.Plugin):
schedule.removeEvent("start_game_%s" % self.channel) schedule.removeEvent("start_game_%s" % self.channel)
except: except:
pass pass
Class = CAHGame Class = CAHGame
###### CHANNEL COMMANDS ###### ###### CHANNEL COMMANDS ######
@ -298,7 +315,14 @@ class CAH(callbacks.Plugin):
else: else:
if len(game.players) < game.maxPlayers: if len(game.players) < game.maxPlayers:
game.players.append(nick) 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: else:
irc.reply("Too many players") irc.reply("Too many players")
if len(game.players) > 1: if len(game.players) > 1:
@ -310,7 +334,7 @@ class CAH(callbacks.Plugin):
"""Starts a cards against humanity game, takes """Starts a cards against humanity game, takes
an optional arguement of number of rounds""" an optional arguement of number of rounds"""
channel = ircutils.toLower(msg.args[0]) channel = ircutils.toLower(msg.args[0])
#TODO: this is prob needs fixing. # TODO: this is prob needs fixing.
if len(args) < 1: if len(args) < 1:
numrounds = 5 numrounds = 5
else: else:
@ -319,7 +343,10 @@ class CAH(callbacks.Plugin):
if channel in self.games: if channel in self.games:
irc.reply("There is a game running currently.") irc.reply("There is a game running currently.")
else: 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] = self.CAHGame(irc, channel, numrounds)
self.games[channel].initGame() 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. For questions cards any number of continuous underscores will be treated as a fill-in-the-blank.
""" """
channel = ircutils.toLower(msg.args[0]) 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() text = args[1].capitalize().strip()
if args[0] == "question": if args[0] == "question":
card_file = "custom_question_cards" card_file = "custom_question_cards"
text = re.sub(r'_+', blank_format, text) text = re.sub(r"_+", blank_format, text)
elif args[0] == "answer": elif args[0] == "answer":
card_file = "custom_answer_cards" card_file = "custom_answer_cards"
else: else:
irc.reply("Specify type of card as either question or answer.") irc.reply("Specify type of card as either question or answer.")
return return
path = os.path.abspath(os.path.join(base_directory, card_folder, card_file)) 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]) file_handle.writelines([text])
def stopcah(self, irc, msg, args): def stopcah(self, irc, msg, args):
@ -364,16 +391,22 @@ class CAH(callbacks.Plugin):
elif nick in game.cardsPlayed: elif nick in game.cardsPlayed:
irc.reply("You already played, GET OUT.") irc.reply("You already played, GET OUT.")
elif len(args) < game.game.question.answers: 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: elif len(args) > game.game.question.answers:
if game.gane.question.answers == 1: if game.gane.question.answers == 1:
irc.reply("I only want one card you idiot.") 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: elif len(args) == game.game.question.answers:
game.playcard(nick, args) game.playcard(nick, args)
else: else:
irc.reply("Game not running.") irc.reply("Game not running.")
#TODO: Card decision logic # TODO: Card decision logic
def votecard(self, irc, msg, args): def votecard(self, irc, msg, args):
channel = ircutils.toLower(msg.args[0]) channel = ircutils.toLower(msg.args[0])
@ -398,6 +431,7 @@ class CAH(callbacks.Plugin):
else: else:
irc.reply("A Game is not running, or the time is not to vote.") irc.reply("A Game is not running, or the time is not to vote.")
Class = CAH Class = CAH