Merge branch 'master' supybot-cah

This commit is contained in:
oddluck 2019-12-07 09:15:49 +00:00
commit 137e8d80bf
12 changed files with 1546 additions and 0 deletions

41
.gitignore vendored Normal file
View File

@ -0,0 +1,41 @@
*.py[cod]
*.ini
*.swp
.dropbox
# C extensions
*.so
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
nosetests.xml
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
#PyCharm files
.idea/*

1
CAH/README.md Normal file
View File

@ -0,0 +1 @@
Cards Against Humanity

46
CAH/__init__.py Normal file
View File

@ -0,0 +1,46 @@
###
# Copyright (c) 2012, James Scott
# All rights reserved.
#
#
###
"""
Add a description of the plugin (to be presented to the user inside the wizard)
here. This should describe *what* the plugin does.
"""
import supybot
import supybot.world as world
import importlib
# Use this for the version of this plugin. You may wish to put a CVS keyword
# in here if you're keeping the plugin in CVS or some similar system.
__version__ = ""
# 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'))
# 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/'
from . import config
from . import plugin
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!
if world.testing:
from . import test
Class = plugin.Class
configure = config.configure
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

175
CAH/cah.py Normal file
View File

@ -0,0 +1,175 @@
from random import choice
import os
import json
from . import test
# Settings you change
card_folder = 'cards'
answer_cards_file_names = ['answer_cards', 'custom_answer_cards']
question_cards_file_name = ['question_cards', 'question_cards1', 'question_cards2', 'custom_question_cards']
blank_format = '__________'
# Settings that are used
#this is one level hire then 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')
def parse_card_file(self, card_type):
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 = []
for file_name in card_type_map[card_type]:
path = os.path.abspath(os.path.join(base_directory, card_folder, file_name))
if os.path.exists(path):
with open(path) as file_handle:
file_data = file_handle.readlines()
card_text_list.extend(file_data)
if len(card_text_list) is 0:
raise IOError
# Deduplicate the text from the cards
card_text_list = list(set(card_text_list))
# Turn the strings of text into a Card object
card_object_list = []
for index, card in enumerate(card_text_list):
# 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':
answers = self.count_answers(card)
card_object_list.append(Card(index, card_type, card, answers=answers))
else:
card_object_list.append(Card(index, card_type, card))
return card_object_list
def count_answers(self, text):
blanks = text.count(blank_format)
if blanks is 0:
return 1
else:
return blanks
def drawCard(self, typeOfCard):
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)})
class Card(object):
def __init__(self, id, type, text, **kwargs):
self.id = id
self.type = type
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):
self.round_limit = round_limit
self.deck = Deck()
self.players = self.build_player_list(players)
self.round = None
self.question = None
self.score = {}
def build_player_list(self, players):
player_list = {}
for player in players:
player_list[player] = PlayerHand(self.deck)
return player_list
def next_round(self):
if self.round is None:
self.round = 0
if self.round < self.round_limit:
self.round += 1
else:
raise IndexError
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)
for player in list(cards_played.keys()):
if isinstance(cards_played[player], Card):
cards_played[player] = [cards_played[player]]
for card in cards_played[player]:
self.players[player].card_list.remove(card)
self.players[player].deal_hand(self.deck)
def score_keeping(self, player_name):
if player_name not in self.players:
raise NameError
if player_name in self.score:
self.score[player_name] += 1
else:
self.score[player_name] = 1
def cardSubmit(self):
for player in self.players:
cardInput = None
cardRange = list(range(5))
while cardInput not in cardRange:
try:
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.players = players
class PlayerHand(object):
def __init__(self, deck):
self.card_list = []
self.deal_hand(deck)
def deal_hand(self, deck):
while len(self.card_list) < 5:
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)
return card_text
def showHand(self):
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()))
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()
print("\nJazz's hand in a weird way")
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))
print("\nEnd the round by picking a random cards amd winner: %s" % str(test.build_end_round_data(game)))

0
CAH/cards/__init__.py Normal file
View File

540
CAH/cards/answer_cards Normal file
View File

@ -0,0 +1,540 @@
A Gypsy curse.
A moment of silence.
A sausage festival.
An honest cop with nothing left to lose.
Famine.
Flesh-eating bacteria.
Flying sex snakes.
Not giving a shit about the Third World.
Sexting.
Shapeshifters.
Porn stars.
Raping and pillaging.
72 virgins.
A drive-by shooting.
A time travel paradox.
Authentic Mexican cuisine.
Bling.
Consultants.
Crippling debt.
Daddy issues.
The Donald Trump Seal of Approval.
Dropping a chandelier on your enemies and riding the rope up.
Former President George W. Bush.
Full frontal nudity.
Hormone injections.
Laying an egg.
Getting naked and watching Nickelodeon.
Pretending to care.
Public ridicule.
Sharing needles.
Boogers.
The inevitable heat death of the universe.
The miracle of childbirth.
The Rapture.
Whipping it out.
White privilege.
Wifely duties.
The Hamburglar.
AXE Body Spray.
The Blood of Christ.
Horrifying laser hair removal accidents.
BATMAN!!!
Agriculture.
A robust mongoloid.
Natural selection.
Coat hanger abortions.
Eating all of the cookies before the AIDS bake-sale.
Michelle Obama's arms.
The World of Warcraft.
Swooping.
Obesity.
A homoerotic volleyball montage.
Lockjaw.
A mating display.
Testicular torsion.
All-you-can-eat shrimp for $4.99.
Domino's Oreo Dessert Pizza.
Kanye West.
Hot cheese.
Raptor attacks.
Taking off your shirt.
Smegma.
Alcoholism.
A middle-aged man on roller skates.
The Care Bear Stare.
Bingeing and purging.
Oversized lollipops.
Self-loathing.
Children on leashes.
Half-assed foreplay.
The Holy Bible.
German dungeon porn.
Being on fire.
Teenage pregnancy.
Gandhi.
Leaving an awkward voicemail.
Uppercuts.
Customer service representatives.
An erection that lasts longer than four hours.
My genitals.
Picking up girls at the abortion clinic.
Science.
Not reciprocating oral sex.
Flightless birds.
A good sniff.
Waterboarding.
A balanced breakfast.
Historically black colleges.
Actually taking candy from a baby.
The Make-A-Wish Foundation.
A clandestine butt scratch.
Passive-aggressive Post-it notes.
The Chinese gymnastics team.
Switching to Geico.
Peeing a little bit.
Home video of Oprah sobbing into a Lean Cuisine.
Nocturnal emissions.
The Jews.
My humps.
Powerful thighs.
Winking at old people.
Mr. Clean, right behind you.
A gentle caress of the inner thigh.
Sexual tension.
The forbidden fruit.
Skeletor.
Fancy Feast.
Being rich.
Sweet, sweet vengeance.
Republicans.
A gassy antelope.
Natalie Portman.
Copping a feel.
Kamikaze pilots.
Sean Connery.
The homosexual agenda.
The hardworking Mexican.
A falcon with a cap on its head.
Altar boys.
The Kool-Aid Man.
Getting so angry that you pop a boner.
Free samples.
A big hoopla about nothing.
Doing the right thing.
The Three-Fifths compromise.
Lactation.
World peace.
RoboCop.
Chutzpah.
Justin Bieber.
Oompa-Loompas.
Inappropriate yodeling.
Puberty.
Ghosts.
An asymmetric boob job.
Vigorous jazz hands.
Fingering.
Glenn Beck catching his scrotum on a curtain hook.
GoGurt.
Police brutality.
John Wilkes Booth.
Preteens.
Scalping.
Stifling a giggle at the mention of Hutus and Tutsis.
"Tweeting."
Darth Vader.
A sad handjob.
Exactly what you'd expect.
Expecting a burp and vomiting on the floor.
Adderall.
Embryonic stem cells.
Tasteful sideboob.
Panda sex.
An icepick lobotomy.
Tom Cruise.
Mouth herpes.
Sperm whales.
Homeless people.
Third base.
Incest.
Pac-Man uncontrollably guzzling cum.
A mime having a stroke.
Hulk Hogan.
God.
Scrubbing under the folds.
Golden showers.
Emotions.
Licking things to claim them as your own.
Pabst Blue Ribbon.
The placenta.
Spontaneous human combustion.
Friends with benefits.
Finger painting.
Old-people smell.
Dying of dysentery.
My inner demons.
A Super Soaker full of cat pee.
Aaron Burr.
Cuddling.
The chronic.
Cockfights.
Friendly fire.
Ronald Reagan.
A disappointing birthday party.
A sassy black woman.
Mathletes.
A tiny horse.
William Shatner.
Riding off into the sunset.
An M. Night Shyamalan plot twist.
Jew-fros.
Mutually-assured destruction.
Pedophiles.
Yeast.
Grave robbing.
Eating the last known bison.
Catapults.
Poor people.
Forgetting the Alamo.
The Hustle.
The Force.
Wiping her butt.
Intelligent design.
Loose lips.
AIDS.
Pictures of boobs.
The Übermensch.
Sarah Palin.
American Gladiators.
Getting really high.
Scientology.
Penis envy.
Praying the gay away.
Frolicking.
Two midgets shitting into a bucket.
The KKK.
Genghis Khan.
Crystal meth.
Serfdom.
Stranger danger.
A Bop It.
Shaquille O'Neal's acting career.
Prancing.
Vigilante justice.
Overcompensation.
Pixelated bukkake.
A lifetime of sadness.
Racism.
Dwarf tossing.
Sunshine and rainbows.
A monkey smoking a cigar.
Flash flooding.
Lance Armstrong's missing testicle.
Dry heaving.
The terrorists.
Britney Spears at 55.
Attitude.
Breaking out into song and dance.
Leprosy.
Gloryholes.
Nipple blades.
The heart of a child.
Puppies!
Waking up half-naked in a Denny's parking lot.
Dental dams.
Toni Morrison's vagina.
The taint; the grundle; the fleshy fun-bridge.
Active listening.
Ethnic cleansing.
The Little Engine That Could.
The invisible hand.
Waiting ‘til marriage.
Unfathomable stupidity.
Euphoria by Calvin Klein.
Re-gifting.
Autocannibalism.
Erectile dysfunction.
My collection of high-tech sex toys.
The Pope.
White people.
Tentacle porn.
Glenn Beck convulsively vomiting as a brood of crab spiders hatches in his brain and erupts from his tear ducts.
Too much hair gel.
Seppuku.
Same-sex ice dancing.
Cheating in the Special Olympics.
Charisma.
Keanu Reeves.
Sean Penn.
Nickelback.
A look-see.
Pooping back and forth. Forever.
Menstruation.
Kids with ass cancer.
A salty surprise.
The South.
The violation of our most basic human rights.
YOU MUST CONSTRUCT ADDITIONAL PYLONS.
Date rape.
Being fabulous.
Necrophilia.
Centaurs.
Bill Nye the Science Guy.
Black people.
Chivalry.
Lunchables.
Bitches.
The profoundly handicapped.
Heartwarming orphans.
MechaHitler.
Fiery poops.
Another goddamn vampire movie.
Tangled Slinkys.
The true meaning of Christmas.
Estrogen.
A zesty breakfast burrito.
That thing that electrocutes your abs.
Passing a kidney stone.
A bleached asshole.
Michael Jackson.
Cybernetic enhancements.
Guys who don't call.
Smallpox blankets.
Masturbation.
Classist undertones.
Queefing.
Concealing a boner.
Edible underpants.
Viagra.
Soup that is too hot.
Muhammad (Praise Be Unto Him).
Surprise sex!
Five-Dollar Footlongs.
Drinking alone.
Dick fingers.
Multiple stab wounds.
Soiling oneself.
Child abuse.
Anal beads.
Civilian casualties.
Pulling out.
Robert Downey, Jr.
Horse meat.
A really cool hat.
Kim Jong-il.
A stray pube.
Jewish fraternities.
The token minority.
Doin' it in the butt.
Feeding Rosie O'Donnell.
Teaching a robot to love.
A can of whoop-ass.
A windmill full of corpses.
Count Chocula.
Wearing underwear inside-out to avoid doing laundry.
A death ray.
The glass ceiling.
A cooler full of organs.
The American Dream.
Keg stands.
When you fart and a little bit comes out.
Take-backsies.
Dead babies.
Foreskin.
Saxophone solos.
Italians.
A fetus.
Firing a rifle into the air while balls deep in a squealing hog.
Dick Cheney.
Amputees.
Eugenics.
My relationship status.
Christopher Walken.
Bees?
Harry Potter erotica.
College.
Getting drunk on mouthwash.
Nazis.
8 oz. of sweet Mexican black-tar heroin.
Stephen Hawking talking dirty.
Dead parents.
Object permanence.
Opposable thumbs.
Racially-biased SAT questions.
Jibber-jabber.
Chainsaws for hands.
Nicolas Cage.
Child beauty pageants.
Explosions.
Sniffing glue.
Glenn Beck being harried by a swarm of buzzards.
Repression.
Roofies.
My vagina.
Assless chaps.
A murder most foul.
Giving 110 percent.
Her Royal Highness, Queen Elizabeth II.
The Trail of Tears.
Being marginalized.
Goblins.
Hope.
The Rev. Dr. Martin Luther King, Jr.
A micropenis.
My soul.
A hot mess.
Vikings.
Hot people.
Seduction.
An Oedipus complex.
Geese.
Global warming.
New Age music.
Hot Pockets.
Making a pouty face.
Vehicular manslaughter.
Women's suffrage.
A defective condom.
Judge Judy.
African children.
The Virginia Tech Massacre.
Barack Obama.
Asians who aren't good at math.
Elderly Japanese men.
Exchanging pleasantries.
Heteronormativity.
Parting the Red Sea.
Arnold Schwarzenegger.
Road head.
Spectacular abs.
Figgy pudding.
A mopey zoo lion.
A bag of magic beans.
Poor life choices.
My sex life.
Auschwitz.
A snapping turtle biting the tip of your penis.
A thermonuclear detonation.
The clitoris.
The Big Bang.
Land mines.
Friends who eat all the snacks.
Goats eating cans.
The Dance of the Sugar Plum Fairy.
Jerking off into a pool of children's tears.
Man meat.
Me time.
The Underground Railroad.
Poorly-timed Holocaust jokes.
A sea of troubles.
Lumberjack fantasies.
Morgan Freeman's voice.
Women in yogurt commercials.
Natural male enhancement.
Being a motherfucking sorcerer.
Genital piercings.
Passable transvestites.
Sexy pillow fights.
Balls.
Grandma.
Friction.
Party poopers.
Farting and walking away.
Being a dick to children.
Booby-trapping the house to foil burglars.
The Tempur-Pedic Swedish Sleep System.
Dying.
Hurricane Katrina.
The gays.
The folly of man.
Men.
The Amish.
Pterodactyl eggs.
Team-building exercises.
A brain tumor.
Cards Against Humanity.
Fear itself.
Lady Gaga.
The milk man.
A foul mouth.
A big black dick.
A beached whale.
A bloody pacifier.
A crappy little hand.
A low standard of living.
A nuanced critique.
Panty raids.
A passionate Latino lover.
A rival dojo.
A web of lies.
A woman scorned.
Clams.
Apologizing.
Appreciative snapping.
Neil Patrick Harris.
Beating your wives.
Being a dinosaur.
Shaft.
Bosnian chicken farmers.
Nubile slave boys.
Carnies.
Coughing into a vagina.
Suicidal thoughts.
Dancing with a broom.
Deflowering the princess.
Dorito breath.
Eating an albino.
Enormous Scandinavian women.
Fabricating statistics.
Finding a skeleton.
Gandalf.
Genetically engineered super-soldiers.
George Clooney's musk.
Getting abducted by Peter Pan.
Getting in her pants, politely.
Gladiatorial combat.
Good grammar.
Hipsters.
Historical revisionism.
Insatiable bloodlust.
Jafar.
Jean-Claude Van Damme.
Just the tip.
Mad hacky-sack skills.
Leveling up.
Literally eating shit.
Making the penises kiss.
Media coverage.
Medieval Times Dinner and Tournament.
Moral ambiguity.
My machete.
One thousand Slim Jims.
Ominous background music.
Overpowering your father.
Pistol-whipping a hostage.
Quiche.
Quivering jowls.
Revenge fucking.
Ripping into a man's chest and pulling out his still-beating heart.
Ryan Gosling riding in on a white horse.
Santa Claus.
Scrotum tickling.
Sexual humiliation.
Sexy Siamese twins.
Slow motion.
Space muffins.
Statistically validated stereotypes.
Sudden Poop Explosion Disease.
The boners of the elderly.
The economy.
The Fanta girls.
The Gulags.
The harsh light of day.
The hiccups.
The shambling corpse of Larry King.
The four arms of Vishnu.
Being a busy adult with many important things to do.
Tripping balls.
Words, words, words.
Zeus's sexual appetites.

92
CAH/cards/question_cards Normal file
View File

@ -0,0 +1,92 @@
TSA guidelines now prohibit __________ on airplanes.
It's a pity that kids these days are all getting involved with __________.
In 1,000 years, when paper money is but a distant memory, __________ will be our currency.
Major League Baseball has banned __________ for giving players an unfair advantage.
What is Batman's guilty pleasure?
Next from J.K. Rowling: Harry Potter and the Chamber of __________.
I'm sorry, Professor, but I couldn't complete my homework because of __________.
What did I bring back from Mexico?
__________? There's an app for that.
__________. Betcha can't have just one!
What's my anti-drug?
While the United States raced the Soviet Union to the moon, the Mexican government funneled millions of pesos into research on __________.
In the new Disney Channel Original Movie, Hannah Montana struggles with __________ for the first time.
What's my secret power?
What's the new fad diet?
What did Vin Diesel eat for dinner?
When Pharaoh remained unmoved, Moses called down a Plague of __________.
How am I maintaining my relationship status?
What's the crustiest?
In L.A. County Jail, word is you can trade 200 cigarettes for __________.
After the earthquake, Sean Penn brought __________ to the people of Haiti.
Instead of coal, Santa now gives the bad children __________.
Life for American Indians was forever changed when the White Man introduced them to __________.
What's Teach for America using to inspire inner city students to succeed?
Maybe she's born with it. Maybe it's __________.
In Michael Jackson's final moments, he thought about __________.
White people like __________.
Why do I hurt all over?
A romantic, candlelit dinner would be incomplete without __________.
What will I bring back in time to convince people that I am a powerful wizard?
BILLY MAYS HERE FOR __________.
The class field trip was completely ruined by __________.
What's a girl's best friend?
Dear Abby, I'm having some trouble with __________ and would like your advice.
When I am President of the United States, I will create the Department of __________.
What are my parents hiding from me?
What never fails to liven up the party?
What gets better with age?
__________: Good to the last drop.
I got 99 problems but __________ ain't one.
__________. It's a trap!
MTV's new reality show features eight washed-up celebrities living with __________.
What would grandma find disturbing, yet oddly charming?
What's the most emo?
During sex, I like to think about __________.
What ended my last relationship?
What's that sound?
__________. That's how I want to die.
Why am I sticky?
What's the next Happy Meal toy?
What's there a ton of in heaven?
I do not know with what weapons World War III will be fought, but World War IV will be fought with __________.
What will always get you laid?
__________: Kid-tested, mother-approved.
Why can't I sleep at night?
What's that smell?
What helps Obama unwind?
This is the way the world ends / This is the way the world ends / Not with a bang but with __________.
Coming to Broadway this season, __________: The Musical.
Anthropologists have recently discovered a primitive tribe that worships __________.
But before I kill you, Mr. Bond, I must show you __________.
Studies show that lab rats navigate mazes 50% faster after being exposed to __________.
Next on ESPN2: The World Series of __________.
When I am a billionaire, I shall erect a 50-foot statue to commemorate __________.
In an attempt to reach a wider audience, the Smithsonian Museum of Natural History has opened an interactive exhibit on __________.
War! What is it good for?
What gives me uncontrollable gas?
What do old people smell like?
What am I giving up for Lent?
Alternative medicine is now embracing the curative powers of __________.
What did the US airdrop to the children of Afghanistan?
What does Dick Cheney prefer?
During Picasso's often-overlooked Brown Period, he produced hundreds of paintings of __________.
What don't you want to find in your Chinese food?
I drink to forget __________.
__________. High five, bro.
He who controls __________ controls the world.
The CIA now interrogates enemy agents by repeatedly subjecting them to __________.
In Rome, there are whisperings that the Vatican has a secret room devoted to __________.
Science will never explain the origin of __________.
When all else fails, I can always masturbate to __________.
I learned the hard way that you can't cheer up a grieving friend with __________.
In its new tourism campaign, Detroit proudly proclaims that it has finally eliminated __________.
The socialist governments of Scandinavia have declared that access to __________ is a basic human right.
In his new self-produced album, Kanye West raps over the sounds of __________.
What's the gift that keeps on giving?
This season on Man vs. Wild, Bear Grylls must survive in the depths of the Amazon with only __________ and his wits.
When I pooped, what came out of my butt?
In the distant future, historians will agree that __________ marked the beginning of America's decline.
What has been making life difficult at the nudist colony?
And I would have gotten away with it, too, if it hadn't been for __________.
What brought the orgy to a grinding halt?

76
CAH/cards/question_cards1 Normal file
View File

@ -0,0 +1,76 @@
__________. High five, bro.
TSA guidelines now prohibit __________ on airplanes.
It's a pity that kids these days are all getting involved with __________.
In 1,000 years, when paper money is but a distant memory, __________ will be our currency.
Major League Baseball has banned __________ for giving players an unfair advantage.
What is Batman's guilty pleasure?
Next from J.K. Rowling: Harry Potter and the Chamber of __________.
I'm sorry, Professor, but I couldn't complete my homework because of __________.
What did I bring back from Mexico?
__________? There's an app for that.
Betcha can't have just one!
What's my anti-drug?
While the United States raced the Soviet Union to the moon, the Mexican government funneled millions of pesos into research on __________.
In the new Disney Channel Original Movie, Hannah Montana struggles with __________ for the first time.
What's my secret power?
What's the new fad diet?
What did Vin Diesel eat for dinner?
When Pharaoh remained unmoved, Moses called down a Plague of __________.
How am I maintaining my relationship status?
What's the crustiest?
When I'm in prison, I'll have __________ smuggled in.
After Hurricane Katrina, Sean Penn brought __________ to the people of New Orleans.
Instead of coal, Santa now gives the bad children __________.
Life was difficult for cavemen before __________.
What's Teach for America using to inspire inner city students to succeed?
Who stole the cookies from the cookie jar?
In Michael Jackson's final moments, he thought about __________.
White people like __________.
Why do I hurt all over?
A romantic candlelit dinner would be incomplete without __________.
What will I bring back in time to convince people that I am a powerful wizard?
BILLY MAYS HERE FOR __________.
The class field trip was completely ruined by __________.
What's a girl's best friend?
I wish I hadn't lost the instruction manual for __________.
When I am President of the United States, I will create the Department of __________.
What are my parents hiding from me?
What never fails to liven up the party?
What gets better with age?
__________: good to the last drop.
I got 99 problems but __________ ain't one.
It's a trap!
MTV's new reality show features eight washed-up celebrities living with __________.
What would grandma find disturbing, yet oddly charming?
What's the most emo?
During sex, I like to think about __________.
What ended my last relationship?
What's that sound?
__________. That's how I want to die.
Why am I sticky?
What's the next Happy Meal® toy?
What's there a ton of in heaven?
I do not know with what weapons World War III will be fought, but World War IV will be fought with __________.
What will always get you laid?
__________: kid tested, mother approved.
Why can't I sleep at night?
What's that smell?
What helps Obama unwind?
This is the way the world ends \ This is the way the world ends \ Not with a bang but with __________.
Coming to Broadway this season, __________: The Musical.
Anthropologists have recently discovered a primitive tribe that worships __________.
But before I kill you, Mr. Bond, I must show you __________.
Studies show that lab rats navigate mazes 50% faster after being exposed to __________.
Due to a PR fiasco, Walmart no longer offers __________.
When I am a billionaire, I shall erect a 50-foot statue to commemorate __________.
In an attempt to reach a wider audience, the Smithsonian Museum of Natural History has opened an interactive exhibit on __________.
War! What is it good for?
What gives me uncontrollable gas?
What do old people smell like?
Sorry everyone, I just __________.
Alternative medicine is now embracing the curative powers of __________.
The U.S. has begun airdropping __________ to the children of Afghanistan.
What does Dick Cheney prefer?
During Picasso's often-overlooked Brown Period, he produced hundreds of paintings of __________.
What don't you want to find in your Chinese food?
I drink to forget __________.

12
CAH/cards/question_cards2 Normal file
View File

@ -0,0 +1,12 @@
That's right, I killed __________. How, you ask? __________.
And the Academy Award for __________ goes to __________.
For my next trick, I will pull __________ out of __________.
In his new summer comedy, Rob Schneider is __________ trapped in the body of __________.
When I was tripping on acid, __________ turned into __________.
__________ is a slippery slope that leads to __________.
In a world ravaged by __________, our only solace is __________.
In M. Night Shyamalan's new movie, Bruce Willis discovers that __________ had really been __________ all along.
I never truly understood __________ until I encountered __________.
Rumor has it that Vladimir Putin's favorite dish is __________ stuffed with __________.
Lifetime® presents __________, the story of __________.
What's the next superhero/sidekick duo? __________ / __________

49
CAH/config.py Normal file
View File

@ -0,0 +1,49 @@
###
# Copyright (c) 2012, James Scott
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions, and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions, and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the author of this software nor the name of
# contributors to this software may be used to endorse or promote products
# derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###
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)
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."""))
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

421
CAH/plugin.py Normal file
View File

@ -0,0 +1,421 @@
###
# Copyright (c) 2012, James Scott
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions, and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions, and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the author of this software nor the name of
# contributors to this software may be used to endorse or promote products
# derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###
import supybot.utils as utils
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.ircmsgs as ircmsgs
import supybot.schedule as schedule
import supybot.callbacks as callbacks
from random import randint
import operator
from .cah import Game, base_directory, card_folder, blank_format
import time
import os
import re
class CAH(callbacks.Plugin):
"""Add the help for "@plugin help CAH" here
This should describe *how* to use this plugin."""
threaded = True
def __init__(self, irc):
self.__parent = super(CAH, self)
self.__parent.__init__(irc)
self.games = {}
class CAHGame(object):
"""docstring for Game"""
def __init__(self, irc, channel, numrounds = 5):
self.irc = irc
self.channel = channel
self.game = None
self.canStart = False
self.voting = False
self.canStart = False
self.roundRunning = False
self.running = False
self.rounds = numrounds
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)
###### UTIL METHODS ##########
def _msg(self, recip, msg):
self.irc.queueMsg(ircmsgs.privmsg(recip,msg))
def _printBlackCard(self, recip):
response = "Question: %s"
cah = self.game
self._msg(recip, ircutils.mircColor(response % cah.question.text, bg="black", fg="white"))
def _msgHandToPlayer(self, nick):
response = "Your cards: %s Please respond with @playcard [channel if in pm] <number> [number]"
enumeratedHand = []
cah = self.game
for position, card in enumerate(cah.players[nick].card_list):
enumeratedHand.append("%s: %s " % (position + 1, ircutils.bold(card.text)))
self._printBlackCard(nick)
self._msg(nick, ircutils.mircColor(response % ', '.join(enumeratedHand), bg="white", fg="black"))
def _displayPlayedCards(self):
channel = self.channel
responseTemplate = "%s: (%s)"
responses = []
response = "%s"
for count, nick in enumerate(self.cardsPlayed.keys()):
cardText = []
cards = ", ".join([ircutils.bold(card.text) for card in self.cardsPlayed[nick]])
responses.append(responseTemplate % (count + 1, cards))
response = "; ".join(responses)
self._msg(channel, "Played White cards: %s" % response)
def _findHighScore(self, scores):
highscore = []
for nick, score in scores.items():
if len(highscore) == 0:
highscore.append([nick, score])
elif highscore[0][1] < score:
highscore = []
highscore.append([nick, score])
elif highscore[0][1] == score:
highscore.append([nick, score])
if len(highscore) > 0:
return (highscore[randint(0, len(highscore) -1)], True)
else:
return (highscore[0], False)
def _tallyVotes(self, votes):
ties = []
winningCanidate = []
canidatesById = []
for nick in list(self.cardsPlayed.keys()):
canidatesById.append(nick)
for canidateNumber, count in votes.items():
canidate = canidatesById[int(canidateNumber)]
count = int(count)
if len(winningCanidate) == 0:
winningCanidate.append((canidate, count))
elif winningCanidate[0][1] < count:
winningCanidate = []
winningCanidate.append((canidate, count))
elif winningCanidate[0][1] == count:
winningCanidate.append((canidate, count))
if len(winningCanidate) > 1:
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
if game.canStart:
if len(game.players) < 2:
self._msg(channel, "I need more players.")
else:
game.canStart = False
game.running = True
game.game = Game(game.players, game.rounds)
#start game logic
self.nextround()
###### END PRE GAME LOGIC ######
###### START GAME LOGIC ########
def playcard(self, nick, cardNumbers):
game = self
cah = game.game
cardlist = []
cards = cah.players[nick].card_list
for cardNum in cardNumbers:
cardlist.append(cards[int(cardNum) - 1])
self.cardsPlayed[nick] = cardlist
if len(self.cardsPlayed) == len(self.players):
try:
schedule.removeEvent("round_%s" % self.channel)
except:
pass
self.endround()
def nextround(self):
channel = self.channel
game = self
cah = game.game
try:
self.cardsPlayed = {}
cah.next_round()
#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 PMed to the players, you have 60 seconds to choose.")
self.acceptingWhiteCards = True
#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 = []
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)))
def endround(self):
channel = self.channel
try:
game = self
if game.acceptingWhiteCards:
game.acceptingWhiteCards = False
self._msg(channel, "Card Submittion Completed.")
self._printBlackCard(channel)
self._displayPlayedCards()
self.startcardvote()
else:
self_msg(channel, "No round active.")
except KeyError:
self_msg(channel, "A Game is not running.")
###### END GAME LOGIC #########
###### VOTING ##############
def startcardvote(self):
channel = self.channel
game = self
game.votes = {}
game.voted = []
game.voting = True
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)
def stopcardvote(self):
#TODO: NOt quite done here
if self.voting:
game = self
game.voting = False
winner = self._tallyVotes(game.votes)
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.nextround()
###### END VOTING LOGIC ######
def close(self):
try:
schedule.removeEvent("round_%s" % self.channel)
except:
pass
try:
schedule.removeEvent("vote_%s" % self.channel)
except:
pass
try:
schedule.removeEvent("start_game_%s" % self.channel)
except:
pass
Class = CAHGame
###### CHANNEL COMMANDS ######
def forcestart(self, irc, msg, args):
channel = ircutils.toLower(msg.args[0])
if channel in self.games:
try:
schedule.removeEvent("start_game_%s" % self.channel)
except:
pass
self.games[channel].startgame()
else:
irc.reply("Game not running.")
def playing(self, irc, msg, args):
channel = ircutils.toLower(msg.args[0])
nick = msg.nick
if channel in self.games:
game = self.games[channel]
if game.running == False:
if nick in game.players:
irc.reply("You already are playing.")
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)))
else:
irc.reply("Too many players")
if len(game.players) > 1:
game.canStart = True
else:
irc.reply("Game not running.")
def cah(self, irc, msg, args):
"""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.
if len(args) < 1:
numrounds = 5
else:
numrounds = int(args[0])
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)
self.games[channel] = self.CAHGame(irc, channel, numrounds)
self.games[channel].initGame()
def addcard(self, irc, msg, args):
"""Add a question or answer card to the deck,
take required argument of [question, answer], and the string.
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
text = args[1].capitalize().strip()
if args[0] == "question":
card_file = "custom_question_cards"
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:
file_handle.writelines([text])
def stopcah(self, irc, msg, args):
channel = ircutils.toLower(msg.args[0])
if channel in self.games:
self.games[channel].close()
self.games.pop(channel)
irc.reply("Game stopped.")
else:
irc.reply("Game not running.")
def playcard(self, irc, msg, args):
channel = ircutils.toLower(msg.args[0])
nick = msg.nick
if channel in self.games:
game = self.games[channel]
if not nick in game.players:
irc.reply("You are not playing, GET OUT.")
elif not game.acceptingWhiteCards:
irc.reply("Not accepting white cards.")
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)
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)
elif len(args) == game.game.question.answers:
game.playcard(nick, args)
else:
irc.reply("Game not running.")
#TODO: Card decision logic
def votecard(self, irc, msg, args):
channel = ircutils.toLower(msg.args[0])
if channel in self.games:
game = self.games[channel]
try:
vote = int(args[0])
if game.voting:
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
else:
game.voted.append(msg.nick)
try:
game.votes[vote - 1] += 1
except KeyError:
game.votes[vote - 1] = 1
irc.reply("vote cast")
except ValueError:
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.")
####DEBUG VOTING REMOVE LATER#####
# TODO: REMOVE THIS DEBUG CODE #
def endvote(self, irc, msg, args):
channel = ircutils.toLower(msg.args[0])
if channel in self.games:
try:
schedule.removeEvent("vote_%s" % self.channel)
except:
pass
self.games[channel].endvote()
else:
irc.reply("Game not running.")
###### END CHANNEL COMMANDS ######
Class = CAH
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

93
CAH/test.py Normal file
View File

@ -0,0 +1,93 @@
__author__ = 'Bear'
from .cah import *
def test_cards_will_be_unique(deck=None, player_list = None):
"""
Ensure that when a hand is created the proper cards are removed from the deck.
"""
if deck is None:
deck=Deck()
if player_list is None:
player_list = {'one': PlayerHand(deck),'two': PlayerHand(deck) }
for value in list(player_list.values()):
for card in value.card_list:
assert card.text not in deck.answerDb
def test_card_parsing(deck=None):
"""
This test checks that the cards in a deck are correctly built Card objects
"""
if deck is None:
deck = Deck()
for deck_type in [deck.answerDb, deck.questionDb]:
for card in deck_type:
test_card(card)
def test_game():
game = Game(['Bear','Swim', 'Jazz'])
test_cards_will_be_unique(deck=game.deck, player_list= game.players)
for player in list(game.players.keys()):
hand = game.players[player]
test_player_hand(hand)
test_round_advancement(game)
def test_round_advancement(game=None):
if game is None:
game = Game(['Bear','Swim', 'Jazz'])
assert game.round is None
assert game.question is None
while round < game.round_limit:
bot_gets = game.next_round()
assert isinstance(bot_gets, dict)
assert 'question' in bot_gets
assert 'question' in game
assert 'hands' in bot_gets
test_end_round(game)
def build_end_round_data(game):
winner = choice(list(game.players.keys()))
cards_played = {}
#Get random cards from player's hand to satisfy the question card
for player in list(game.players.keys()):
player_cards = game.players[player].card_list[:game.question.answers]
cards_played[player] = player_cards #player_cards is a deque object -> tuple(list,maxlen)
return {'winner': winner, 'cards_played': cards_played}
def test_end_round(game=None):
if game is None:
game = Game(['Bear','Swim', 'Jazz'])
game.next_round()
game.question.answers = 2
fake_end_round = build_end_round_data(game)
game.end_round(fake_end_round['winner'],fake_end_round['cards_played'])
for player in list(game.players.keys()):
assert len(game.players[player].card_list) == 5
if isinstance(fake_end_round['cards_played'][player], Card):
fake_end_round['cards_played'][player] = list(fake_end_round['cards_played'][player])
for card in fake_end_round['cards_played'][player]:
assert card not in game.players[player].card_list
assert fake_end_round['winner'] in game.score
def test_player_hand(hand=None):
if hand is None:
hand = PlayerHand(Deck())
assert type(hand) is PlayerHand
for count, card in enumerate(hand.card_list):
assert count < 5
assert type(card) is Card
def test_card(card=None):
if card is None:
card = Deck().drawCard('question')
assert type(card) is Card
assert type(card.id) is int
assert type(card.type) is str
assert card.type in ['answer', 'question']
assert type(card.text) is str
assert card.text.find('\n') is -1
if card.type is 'question':
assert type(card.answers) is int