class Cribbage: HUMAN = "human" COMPUTER = "computer" def __init__(self): self.deck = None self.starter = None self.board = None self.players = {Cribbage.HUMAN: HumanPlayer(), Cribbage.COMPUTER: ComputerPlayer()} self.crib = [] self.game_state = GAME_STATE_DONE def play(self): self.deck = Deck() self.board = {Cribbage.HUMAN: 0, Cribbage.COMPUTER: 0} self.players[Cribbage.COMPUTER].deal([self.deck.draw() for c in range(6)], False) self.players[Cribbage.HUMAN].deal([self.deck.draw() for c in range(6)], False) def get_computer_cards(self): return self.players[Cribbage.COMPUTER].get_cards() def get_human_cards(self): return self.players[Cribbage.HUMAN].get_cards() def update(self): pass
class TestDeck(unittest.TestCase): def setUp(self): self.deck = Deck() def test52(self): self.assertEqual(len(self.deck), 52) def test_no_dupes(self): seen = set() for card in self.deck: self.assertNotIn(card, seen) seen.add(card) def test_repr_string(self): self.assertIsInstance(repr(self.deck), str) def test_shuffle(self): deck2 = Deck() random.shuffle(deck2) self.assertNotEqual(self.deck.cards, deck2.cards) def test_deal_5(self): hand = self.deck.deal(5) self.assertEqual(len(hand), 5) def test_draw(self): hand = self.deck.deal(5) self.deck.draw(hand) self.assertEqual(len(hand), 6)
def test_draw(self): """ Test draw function draws one card and reloads when no cards are left """ deck = Deck() deck.reload() draw_pile = [] for _ in range(0, 52): draw_pile.append(deck.draw()) self.assertEqual(len(draw_pile), 52) deck.draw() self.assertEqual(len(deck.cards), 51)
def playAIGame(): """ Plays a game of Cribbage using two AI players """ players = [AI.Player("player 2"), AI.Player("player 1")] try: round = 1 while (True): """ players[1] is the dealer, the array order is swapped every round The while loop will break when one player passes 121 points (This is done by throwing an exeption) """ deck = Deck() deck.shuffle() print("\n") print(colored("Round " + str(round), 'grey', 'on_yellow')) print("") print(colored("The Deal", 'grey', 'on_magenta')) print(players[1].name + " is the dealer") players[0].deal(deck.draw(6), isDealer=False) players[1].deal(deck.draw(6), isDealer=True) face = deck.draw() print("The face card is: ", end="") print(face.coloredString()) if Card.rankName(face.cards[0].rank) == "J": players[1].addPoints(2, colored(" for the face being a Jack")) print("") print(colored("The Play", 'grey', 'on_magenta')) Cribbage.pegging(players) kitty = players[0].kitty + players[1].kitty print("") print(colored("The Count", 'grey', 'on_magenta')) players[0].score(face) players[1].score(face, kitty) players.reverse() round += 1 except ValueError as e: print() print(e)
class PasyansGameState(CardGameState): """Represents the history of a Pasyans game, allowing turns to be reversed or a game to be resumed.""" ranks = [ Rank.SIX, Rank.SEVEN, Rank.EIGHT, Rank.NINE, Rank.TEN, Rank.JACK, Rank.QUEEN, Rank.KING, Rank.ACE ] command_aliases = { 'move': ['move', 'mv'], 'exit': ['exit', 'end', 'quit'], 'win': ['win'] } cell_names = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'F', 'f'] def __init__(self, debug_mode=False): super().__init__(self.ranks, debug_mode) self.deck.shuffle() self.cells = [[self.deck.draw() for i in range(4)] for j in range(9)] self.free_cell = None def reset_game(self): self.deck = Deck(self.ranks) self.deck.shuffle() self.cells = [[self.deck.draw() for i in range(4)] for j in range(9)] self.free_cell = None self.turn_history = [] self.is_won = False
def test_deck_length1(self): x = Deck() card = Card("a", "b") x[:] = [card] actual = x.draw() self.assertEqual(actual, card) self.assertListEqual(x, [])
def test_deck_length2(self): x = Deck() card1 = Card("a", "b") card2 = Card("c", "d") x[:] = [card1, card2] actual = x.draw() self.assertEqual(actual, card2) self.assertListEqual(x, [card1])
def test_deck_full(self): x = Deck() x.reset() expected_state_after = x[:-1] expected_card = x[-1] actual_card = x.draw() self.assertEqual(actual_card, expected_card) self.assertListEqual(x, expected_state_after)
def cah_madlib(self, server, event, bot): '''Entertaining function for dev, delete later.''' d = Deck() b = d.draw("black") madlib = b.body blanks = b.num_answers if blanks == 0: madlib += ' ' + d.draw("white").body.rstrip('.') elif madlib.count('_') == 0: madlib += ' ' + ', '.join([d.draw("white").body.rstrip('.') for x in range(blanks)]) else: replacements = [] madlib = madlib.replace("%","%%").replace("_", "%s") for i in range(blanks): replacements.append("\x02\x1F%s\x0F" % d.draw("white").body.rstrip('.')) madlib = madlib % tuple(replacements) server.privmsg(event.target, madlib)
def create_random(self): """create a random character based on card draw and random assignment""" #Get list of traits and aptitudes traits, aptitudes = self.__get_stats() #Draw cards and get aptitudes deck = Deck() hand = [deck.draw() for i in range(0, 12)] #Convert jokers to dice size and check for Mysterious Past for c in hand: if c.suit == "Joker": self.mysterious_past = True card = deck.draw() c.suit = card.suit #Remove two lowest value cards hand.remove(min(hand, key=lambda x: x.value)) hand.remove(min(hand, key=lambda x: x.value)) #Apply num and size randomly to aptitudes for t in traits: c = hand.pop() t.set_num(c.die_num) t.set_size(c.die_size) #Math out secondary attributes self.pace = self.quickness.size self.wind = self.vigor.size + self.spirit.size #Get aptitude points aptitude_points = self.knowledge.size + self.smarts.size + self.cognition.size #Randomly assign points to aptitudes while (aptitude_points > 0): if aptitude_points > 5: num = int((randint(0, 5) + randint(0, 5)) / 2) else: num = aptitude_points aptitudes[randint(0, len(aptitudes) - 1)].set_num(num) aptitude_points -= num
def create_random(self): """create a random character based on card draw and random assignment""" #Get list of traits and aptitudes traits, aptitudes = self.__get_stats() #Draw cards and get aptitudes deck = Deck() hand = [deck.draw() for i in range(0,12)] #Convert jokers to dice size and check for Mysterious Past for c in hand: if c.suit == "Joker": self.mysterious_past = True card = deck.draw() c.suit = card.suit #Remove two lowest value cards hand.remove(min(hand, key=lambda x: x.value)) hand.remove(min(hand, key=lambda x: x.value)) #Apply num and size randomly to aptitudes for t in traits: c = hand.pop() t.set_num(c.die_num) t.set_size(c.die_size) #Math out secondary attributes self.pace = self.quickness.size self.wind = self.vigor.size + self.spirit.size #Get aptitude points aptitude_points = self.knowledge.size + self.smarts.size + self.cognition.size #Randomly assign points to aptitudes while (aptitude_points > 0): if aptitude_points > 5: num = int((randint(0,5) + randint(0,5)) / 2) else: num = aptitude_points aptitudes[randint(0, len(aptitudes)-1)].set_num(num) aptitude_points -= num
def play(): deck = Deck() playerCard = deck.draw() dealerCard = deck.draw() result = Result() result.playerCard = playerCard result.dealerCard = dealerCard if playerCard < dealerCard: result.message = "Sorry, you lose." elif playerCard > dealerCard: result.message = "You win!" else: result.message = "It's a tie." return result
class CAHGame(object): def __init__(self, server, channel): self.status = "Waiting for players to join" # Keep track of the current channel/server self.channel = channel self.server = server #flag to keep track of whether or not game is running self.running = True #list of active players in a game self.players = [] #dummy with a small deck for testing. #replace with actual card loading from DB later self.deck = Deck() # Who is the current czar in self.players? # Starting at -1 so the first iteration has the czar be the first person to join self.current_czar = -1 # What is the current black card? self.current_card = None # Cards submitted self.submissions = {} #add a new player to the game def add_player(self, name): #check to see if player already in game if name in [p.name for p in self.players]: return False else: player = Player(name) self.players.append(player) self.deal(player) return player def get_player(self, name): players = [p for p in self.players if p.name == name] if len(players) == 1: return players[0] else: return None #start the game def start(self): # Reset back to the start self.status = "Waiting for player selection" # Remove previous submissions from players' hands for player, submissions in self.submissions.iteritems(): for card in submissions: if card in player.hand: player.hand.remove(card) self.submissions = {} # Refresh player hands for player in self.players: self.deal(player) # Deal the new black card new_card = self.deal_black() if new_card is None: self.message("Out of black cards! You played a long game!") self.end() # TODO: make this end the game when out of black cards return czar = self.choose_czar() self.message("The new czar is %s" % czar.name) self.message("%s has drawn: %s" % (czar.name, self.current_card.body)) # Show players their current hand for player in [player for player in self.players if player.name != czar.name]: self.message("You will need to choose \x02%d\x0F cards with the 'select X' command, where X is the card's position in your hand." % self.cards_needed, player) if self.cards_needed > 1: self.message("NOTE: To submit multiple cards, use the cah command 'select X Y ...', where the card numbers are separated by a space.", player) # Display hand self.message("Ok, here's your hand:", player) for num, card in enumerate(player.hand): self.message("%d. %s" % (num+1, card.body), player) def end(self): #check if game is already running if self.running: self.message("The game has ended.") for place, player in enumerate(sorted(self.players, key=lambda x: x.score, reverse=True)): self.message("%d. %s with %d points" % (place+1, player.name, player.score)) self.running = False self.deck.reset() else: self.message("There's no game running! Use '@cah new' to start a new game.") # Choose cards to play def select(self, player, cards): # Fail if the player is the Czar OR it's not time for players to select cards if self.status != "Waiting for player selection" or self.players[self.current_czar].name == player.name: self.message("This isn't your turn!", player) return # Fail if player didn't select the right amount of cards if len(cards) != self.cards_needed: self.message("You need to play %d cards _only_" % self.cards_needed, player) return # Fail if cards are invalid (they should have been sanitized to ints in cah.py) for card in cards: if card > len(player.hand) or card <= 0: self.message("You don't have a card %d in your hand!" % card, player) return # Insert cards into the submissions dictionary self.submissions[player] = [player.hand[card-1] for card in cards] # Continue on in the game loop if all but the czar have voted if len(self.submissions) == len(self.players)-1: self.display_selections() self.status = "Waiting for Czar vote" # Present the funnies def display_selections(self): self.message("Results are in!") # Question cards are only displayed once, then the replies are presented as choices if "_" not in self.current_card.body: self.message(self.current_card.body) for num, submission in enumerate(self.submissions.values()): self.message("%d. %s" % (num+1, ', '.join([x.body for x in submission]))) # Other cards have the white card answeres filled in the blanks (with bold and underline) else: for num, submission in enumerate(self.submissions.values()): replacements = [] filled_in = self.current_card.body.replace("%","%%").replace("_", "%s") for i in range(self.cards_needed): replacements.append("\x02\x1F%s\x0F" % submission[i].body) filled_in = filled_in % tuple(replacements) self.message("%d. %s" % (num+1, filled_in)) # Prompt the czar to not be lazy... self.message("Now for %s to vote..." % self.players[self.current_czar].name) # Czar vote def vote(self, player, vote): # Fail if the player isn't the current Czar if player.name != self.players[self.current_czar].name: self.message("You are not the Czar!", player) return # Fail if it's not time for the Czar to vote if self.status != "Waiting for Czar vote": self.message("We're not ready for you to vote.", player) return # Fail if the czar vote for a choice that isn't present if vote <= 0 or vote > len(self.players)-1: self.message("%d isn't a valid vote selection." % vote, player) return # Display and increase score for the Czar's choice winning_player = self.submissions.keys()[vote-1] self.message("%s won this round! The winning combination was..." % winning_player.name) winning_player.score += 1 # TODO: refactor this and the bit in display_selections # see display_selections, this is the same, except it only displays a single submission if "_" not in self.current_card.body: self.message(self.current_card.body) self.message(', '.join([x.body for x in self.submissions.values()[vote-1]])) else: replacements = [] filled_in = self.current_card.body.replace("%","%%").replace("_", "%s") for i in range(self.cards_needed): replacements.append("\x02\x1F%s\x0F" % self.submissions.values()[vote-1][i].body) filled_in = filled_in % tuple(replacements) self.message(filled_in) # And start the game loop over self.start() #deal cards to player until hand size is 10 def deal(self, player): handSize = len(player.hand) while handSize < 10: player.hand.append(self.deck.draw("white")) handSize += 1 return player.hand def choose_czar(self): self.current_czar = (self.current_czar + 1) % len(self.players) return self.players[self.current_czar] def deal_black(self): try: self.current_card = self.deck.draw("black") return self.current_card except NoMoreCards: return None def message(self, body, player=None): if player is not None: self.server.notice(player.name, body) else: self.server.privmsg(self.channel, body) @property def cards_needed(self): return self.current_card.num_answers
class Game(object): def __init__(self, num_player=1, player_tokens=1000, min_bet=10, max_bet=500, ndecks=6, shuffle_lim=10, sleep_time=0.7): # self.players = [Player.Player(ntokens=player_tokens) for _ in range(num_player)] self.player = Player(ntokens=player_tokens) self.dealer = Dealer() self.draw_count = 0 # keeps track of number of draws - first two counts as one self.min_bet = min_bet self.max_bet = max_bet self.current_bet = 0 self.sleep_time = sleep_time self.deck = Deck(ndecks, shuffle_lim) def initialize_round(self): # for p in self.players: # p.initialize() self.player.initialize() # clear dealer hand self.dealer.initialize() self.draw_count = 0 def players_bet(self): self.current_bet = self.player.place_bet(min_bet=self.min_bet, max_bet=self.max_bet) def draw_cards(self, side, face_down=True): new_card = self.deck.draw() if not face_down: new_card.reveal() if side == 'p': self.player.hands[0].append(new_card) elif side == 'd': self.dealer.hand.append(new_card) def players_actions(self): """ Get player action from player :return: """ # compile list of valid actions for player # hit and stand are always valid valid_actions = [Action.Hit, Action.Stand] # split and double only occurs in draw one if self.draw_count == 1: valid_actions.append(Action.Double) if len(self.player.hands[0]) == 2 and self.player.hands[0][0].value == self.player.hands[0][1].value: valid_actions.append(Action.Split) action = self.player.choose_action(valid_actions) return action def result(self, code): # player blackjack, pays 3 to 2 if code == Condition.BLACKJACK: print("Congratulations, you got a blackjack!") update_tokens = int(self.current_bet * (1 + 1.5)) # player wins elif code == Condition.WIN: print("You won!") update_tokens = self.current_bet * 2 # player loses elif code == Condition.LOSE: print("You lost!") # player token already deducted, do nothing update_tokens = 0 # push elif code == Condition.PUSH: print("Push!") update_tokens = self.current_bet # compare hand values else: raise NotImplementedError self.player.tokens += update_tokens def condition(self): """ Check the current condition and returns a condition code :return: condition code """ # check blackjack if get_hand_best_value(self.player.hands[0]) == 21: # player blackjack, pays 3 to 2 if self.draw_count == 1: # check if dealer also blackjack return Condition.PUSH if get_hand_best_value(self.dealer.hand) == 21 else Condition.BLACKJACK # check dealer blackjack elif get_hand_best_value(self.dealer.hand) == 21 and self.draw_count == 1: print("Dealer got a blackjack!") return Condition.LOSE # check player bust elif get_hand_best_value(self.player.hands[0]) > 21: print("You busted!") return Condition.LOSE # check dealer bust elif get_hand_best_value(self.dealer.hand) > 21: print("Dealer busted!") return Condition.WIN # continue else: return Condition.CONTINUE def compare_hands(self): """ Compares the hands between dealer and player to decide result :return: a result code """ # take max <= 21 player_best = get_hand_best_value(self.player.hands[0]) dealer_best = get_hand_best_value(self.dealer.hand) # check blackjack if player_best == 21 and dealer_best != 21 and self.draw_count == 1: return Condition.BLACKJACK # check dealer bust if dealer_best > 21: return Condition.WIN if player_best > dealer_best: return Condition.WIN elif player_best < dealer_best: return Condition.LOSE elif player_best == dealer_best: return Condition.PUSH else: raise NotImplementedError def display_hands(self): # only print values <= 21, print minimum if no values <= 21 dealer_values = get_hand_value(self.dealer.hand) dealer_print = sorted([val for val in dealer_values if val <= 21]) if len(dealer_print) == 0: dealer_print = [min(dealer_values)] player_values = get_hand_value(self.player.hands[0]) player_print = sorted([val for val in player_values if val <= 21]) if len(player_print) == 0: player_print = [min(player_values)] print("Dealer hand:") print("%s, %s" % (self.dealer.hand, dealer_print)) print() print("Player hand:") print("%s, %s" % (self.player.hands[0], player_print)) print() sleep(self.sleep_time) def split(self): pass def round(self): self.initialize_round() self.players_bet() # draw two initial cards print("Drawing first two cards...") self.draw_cards('d', face_down=False) self.draw_cards('p', face_down=False) self.draw_cards('d', face_down=True) self.draw_cards('p', face_down=False) self.draw_count += 1 self.display_hands() code = Condition.CONTINUE # player draws until 21 or stand or double or busted while True: # drew to 21 if get_hand_best_value(self.player.hands[0]) == 21: code = Condition.BLACKJACK break # busted, reveal dealer card and end round if get_hand_best_value(self.player.hands[0]) > 21: code = Condition.LOSE # reveal dealer's cards for card in self.dealer.hand: card.reveal() self.display_hands() self.result(code) return player_action = self.players_actions() # player stand, end player drawing phase if player_action == Action.Stand: break if player_action == Action.Split: # TODO: split logic pass self.draw_cards('p', face_down=False) self.draw_count += 1 self.display_hands() # if player doubled if player_action == Action.Double: # checked if player had enough tokens # deducted from player balance # add to current bet self.current_bet *= 2 # end player draw (only one draw on doubles) break # reveal dealer's cards for card in self.dealer.hand: card.reveal() self.display_hands() # if player blackjack, skip dealer drawing if code != Condition.BLACKJACK: # dealer draws until >= 17 while True: dealer_action = self.dealer.choose_action() if dealer_action == Action.Stand: break self.draw_cards('d', face_down=False) self.display_hands() # dealer done drawing but still no result, so compare hands code = self.compare_hands() # game ended self.result(code)
# for k in range(aces): # if value > 21: # value -= 10 return value if __name__ == '__main__': deck = Deck() shuffle(deck) new_game = 'y' player_value = 0 while new_game == 'y': player = [] dealer = [] player.append(deck.draw()) dealer.append(deck.draw()) player.append(deck.draw()) dealer.append(deck.draw()) print('Your cards is: ', player) print('Dealers card is: ', dealer[1:]) player_value = get_hand_value(player) while player_value < 21: decision = str(input('Card? (yes/no) ')) if decision in ('n', 'no'): break elif decision in ('y', 'yes'): player.append(deck.draw()) player_value = get_hand_value(player)
class Game(object): def __init__(self, mode=None, print_games=True): self.deck = Deck() self.mode = mode self.dealer_hand = [] self.player_hand = [] # deal out initial cards dealer_card = self.deck.draw() dealer_card.facing = "down" self.dealer_hand.append(dealer_card) self.player_hand.append(self.deck.draw()) self.dealer_hand.append(self.deck.draw()) self.player_hand.append(self.deck.draw()) if print_games: logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format="%(message)s") else: logging.basicConfig(level=logging.CRITICAL) logging.info("--------- A GAME OF BLACKJACK ---------") logging.info(self) if self.mode == "stdin": while True: command = raw_input( "What would you like to do? [s]tay, [h]it...") self.dealer_command(command) def __repr__(self): stdout = "========================================\n" if any([card.facing == "down" for card in self.dealer_hand]): stdout += " Dealer showing ({}):\n".format( self.sum_hand(self.dealer_hand)) else: stdout += " Dealer has ({}):\n".format( self.sum_hand(self.dealer_hand)) for card in self.dealer_hand: stdout += " {}\n".format(card) stdout += " ~ ~ ~ ~ ~ ~ ~ ~ \n" stdout += " Player has ({}):\n".format(self.sum_hand( self.player_hand)) for card in self.player_hand: stdout += " {}\n".format(card) stdout += "========================================" return stdout @staticmethod def sum_hand(hand): total = 0 ace_count = 0 for card in hand: if card.facing == "down": continue try: total += int(card.rank) except: if card.rank in ["jack", "queen", "king"]: total += 10 elif card.rank == "ace": ace_count += 1 # assume aces are 11 unless you'd bust, then 1 for x in range(ace_count): if total <= 10: total += 11 else: total += 1 return total def dealer_command(self, command): if command in ["hit", "h"]: logging.info(" => player has chosen to hit") self.player_hand.append(self.deck.draw()) logging.info(self) if self.sum_hand(self.player_hand) > 21: raise PlayerBusts() if command in ["stay", "s"]: logging.info(" => player has chosen to stay") [card.show() for card in self.dealer_hand] while self.sum_hand(self.dealer_hand) < 17: self.dealer_hand.append(self.deck.draw()) logging.info(self) if self.sum_hand(self.dealer_hand) > 21: raise DealerBusts() if self.sum_hand(self.player_hand) > self.sum_hand( self.dealer_hand): raise PlayerWins() if self.sum_hand(self.player_hand) < self.sum_hand( self.dealer_hand): raise DealerWins() if self.sum_hand(self.player_hand) == self.sum_hand( self.dealer_hand): raise Push()
def main(): """ Main. """ print('Welcome to Cribbage.') print() dealer = Player('Player A') pone = HumanPlayer('Player B') print(dealer.name + ' is the dealer.') print(pone.name + ' is the pone.') def other_player(player): if player is dealer: return pone return dealer while True: # reset crib_cards = [] # shuffle print('Shuffling deck.') deck = Deck() deck.shuffle() # deal print('Dealing cards.') deal(deck, dealer, pone, 6) # throw to crib print('Waiting for ' + dealer.name + ' to throw 2 cards to the crib...') dealer_threw = dealer.throw_to_crib(True) print(dealer.name + ' threw ' + str(dealer_threw) + ' into the crib.') crib_cards += dealer_threw print('Waiting for ' + pone.name + ' to throw 2 cards to the crib...') pone_threw = pone.throw_to_crib(False) print(pone.name + ' threw ' + str(pone_threw) + ' into the crib.') crib_cards += pone_threw # cut cut_card = deck.draw() print('The cut card is ' + str(cut_card) + '.') if cut_card.rank == 11: print(dealer.name + " receives 2 points for the Jack's heels.") add_points(dealer, 2, other_player(dealer)) check_win(dealer, pone) # keep track of count points dealer_points = Hand(dealer.hand_cards, cut_card).count() pone_points = Hand(pone.hand_cards, cut_card).count() crib_points = Hand(crib_cards, cut_card, True).count() # peg played_cards = [] player_to_play = pone passed = None while True: print('Waiting for ' + player_to_play.name + ' to play a card...') played_card = player_to_play.play_card(played_cards) if played_card: print(player_to_play.name + ' plays ' + str(played_card) + '.') played_cards.append(played_card) print('Cards in play: ' + str(played_cards) + ' (' + str(sum(map(lambda card: card.value, played_cards))) + ').') peg_points = count_peg_points(played_cards) if peg_points != 0: print(player_to_play.name + ' pegs ' + str(peg_points) + ' points.') add_points(player_to_play, peg_points, other_player(player_to_play)) check_win(dealer, pone) if len(dealer.hand_cards) == 0 and len(pone.hand_cards) == 0: print(player_to_play.name + ' receives a go.') add_points(player_to_play, 1, other_player(player_to_play)) check_win(dealer, pone) break if not passed: player_to_play = other_player(player_to_play) else: if not passed: print(player_to_play.name + ' cannot play a card.') passed = player_to_play player_to_play = other_player(player_to_play) else: passed = None print(player_to_play.name + ' receives a go.') add_points(player_to_play, 1, other_player(player_to_play)) check_win(dealer, pone) player_to_play = other_player(player_to_play) played_cards = [] print() # count print(pone.name + ' counts ' + str(pone_points) + ' points.') add_points(pone, pone_points, dealer, False) check_win(dealer, pone) print(dealer.name + ' counts ' + str(dealer_points) + ' points.') add_points(dealer, dealer_points, pone, False) check_win(dealer, pone) print(dealer.name + ' scores ' + str(crib_points) + ' points from the crib.') add_points(dealer, crib_points, pone) check_win(dealer, pone) # new dealer dealer, pone = pone, dealer print()
def cah_draw(self, server, event, bot, color): '''For testing only, delete later.''' d = Deck() c = d.draw(color) server.privmsg(event.target, c.body)
class Table(object): players = [] dealerUp = [] __dealerDownCard = None deck = Deck() verbose = False washed_up = [] def __init__(self, loud=False): print("Welcome to BlackJack") self.verbose = loud def add_player(self, newPlayer): self.players.append(newPlayer) def setup_game(self): # Configure Deck for number of players self.deck = Deck(len(self.players) // 2) def game(self): # Remove all broke players broke = [] for you in self.players: if you.bank <= 0: broke.append(you) for them in broke: self.washed_up.append(self.players.pop(self.players.index(them))) # Deal all cards to players if self.verbose: print("Dealing Cards...") for x in self.players: x.deal_hand([self.deck.draw(), self.deck.draw()]) # Dealer cards self.dealerUp.append(self.deck.draw()) self.__dealerDownCard = self.deck.draw() if self.verbose: print("Dealer's upcard:\n\t" + str(self.dealerUp[0])) # Betting round self.betting_round() # Check who won and award money self.wrap_up(self.declare_winner()) def declare_winner(self): winners = [(sum(self.dealerUp) + self.__dealerDownCard, 'Dealer', None) ] if self.verbose: s = str(sum(self.dealerUp) + self.__dealerDownCard) + ' Dealer' print('Completed round scores:\n\t', s) for you in self.players: winners.append((sum(you.get_hand()), you.name, you)) if self.verbose: s = str(sum(you.get_hand())) + ' ' + you.name print('\t', s) winners.sort() return winners def betting_round(self): in_round = [] for you in self.players: in_round.append(you) # For all of the people in the game, get betting for you in self.players: bt = you.initial_bet() if self.verbose: print(you.name, "makes an initial bet of $" + str(bt)) print("\tRemaining Balance: $", you.bank) # While there are people still wanting to play, while len(in_round) > 0: # Check all players for status for you in self.players: # Make sure they're still in if you not in in_round: pass # If they are playing, check if hit elif you.hit(): # Deal card on hit bust = you.deal_card(self.deck.draw()) if bust: in_round.remove(you) else: in_round.remove(you) # Dealers Turn once everyone has played while sum(self.dealerUp) + self.__dealerDownCard < 15: newCard = self.deck.draw() if self.verbose: print("Dealer draws a card.", newCard) self.dealerUp.append(newCard) if self.verbose: print("Dealer flips his card. It's a", self.__dealerDownCard) print("Dealers Hand:\n\t" + str(self.__dealerDownCard)) for thing in self.dealerUp: print("\t" + str(thing)) # Let all the players know what was played allhands = [self.__dealerDownCard] allhands.extend(self.dealerUp) for you in self.players: allhands.extend(you.get_hand()) for you in self.players: you.end_round(allhands) def wrap_up(self, scores): # Complete the game an print all of the money won by player names. losers = [] winners = [] dealerScore = sum(self.dealerUp) + self.__dealerDownCard for you in scores: if you[2] is None: # Dealer, ignore his payday continue elif you[0] == 21: # Blackjack! Give them their money back and more you[2].won_money(1.5) winners.append(you) elif you[0] < 21 and you[0] >= dealerScore: # You still won, just less money you[2].won_money(1) winners.append(you) elif dealerScore > 21 and you[0] < 21: # Won you[2].won_money(1) winners.append(you) else: losers.append(you) # Print stuff if self.verbose: print("Winners!") print([you[:2] for you in winners]) print("Losers") print([you[:2] for you in losers]) # Remove cards from the Dealer self.dealerUp = [] self.__dealerDownCard = None
class CAHGame(object): def __init__(self, server, channel): self.status = "Waiting for players to join" # Keep track of the current channel/server self.channel = channel self.server = server #flag to keep track of whether or not game is running self.running = True #list of active players in a game self.players = [] #dummy with a small deck for testing. #replace with actual card loading from DB later self.deck = Deck() # Who is the current czar in self.players? # Starting at -1 so the first iteration has the czar be the first person to join self.current_czar = -1 # What is the current black card? self.current_card = None # Cards submitted self.submissions = {} #add a new player to the game def add_player(self, name): #check to see if player already in game if name in [p.name for p in self.players]: return False else: player = Player(name) self.players.append(player) self.deal(player) return player def get_player(self, name): players = [p for p in self.players if p.name == name] if len(players) == 1: return players[0] else: return None #start the game def start(self): # Reset back to the start self.status = "Waiting for player selection" # Remove previous submissions from players' hands for player, submissions in self.submissions.iteritems(): for card in submissions: if card in player.hand: player.hand.remove(card) self.submissions = {} # Refresh player hands for player in self.players: self.deal(player) # Deal the new black card new_card = self.deal_black() if new_card is None: self.message("Out of black cards! You played a long game!") self.end() # TODO: make this end the game when out of black cards return czar = self.choose_czar() self.message("The new czar is %s" % czar.name) self.message("%s has drawn: %s" % (czar.name, self.current_card.body)) # Show players their current hand for player in [ player for player in self.players if player.name != czar.name ]: self.message( "You will need to choose \x02%d\x0F cards with the 'select X' command, where X is the card's position in your hand." % self.cards_needed, player) if self.cards_needed > 1: self.message( "NOTE: To submit multiple cards, use the cah command 'select X Y ...', where the card numbers are separated by a space.", player) # Display hand self.message("Ok, here's your hand:", player) for num, card in enumerate(player.hand): self.message("%d. %s" % (num + 1, card.body), player) def end(self): #check if game is already running if self.running: self.message("The game has ended.") for place, player in enumerate( sorted(self.players, key=lambda x: x.score, reverse=True)): self.message("%d. %s with %d points" % (place + 1, player.name, player.score)) self.running = False self.deck.reset() else: self.message( "There's no game running! Use '@cah new' to start a new game." ) # Choose cards to play def select(self, player, cards): # Fail if the player is the Czar OR it's not time for players to select cards if self.status != "Waiting for player selection" or self.players[ self.current_czar].name == player.name: self.message("This isn't your turn!", player) return # Fail if player didn't select the right amount of cards if len(cards) != self.cards_needed: self.message( "You need to play %d cards _only_" % self.cards_needed, player) return # Fail if cards are invalid (they should have been sanitized to ints in cah.py) for card in cards: if card > len(player.hand) or card <= 0: self.message("You don't have a card %d in your hand!" % card, player) return # Insert cards into the submissions dictionary self.submissions[player] = [player.hand[card - 1] for card in cards] # Continue on in the game loop if all but the czar have voted if len(self.submissions) == len(self.players) - 1: self.display_selections() self.status = "Waiting for Czar vote" # Present the funnies def display_selections(self): self.message("Results are in!") # Question cards are only displayed once, then the replies are presented as choices if "_" not in self.current_card.body: self.message(self.current_card.body) for num, submission in enumerate(self.submissions.values()): self.message("%d. %s" % (num + 1, ', '.join([x.body for x in submission]))) # Other cards have the white card answeres filled in the blanks (with bold and underline) else: for num, submission in enumerate(self.submissions.values()): replacements = [] filled_in = self.current_card.body.replace("%", "%%").replace( "_", "%s") for i in range(self.cards_needed): replacements.append("\x02\x1F%s\x0F" % submission[i].body) filled_in = filled_in % tuple(replacements) self.message("%d. %s" % (num + 1, filled_in)) # Prompt the czar to not be lazy... self.message("Now for %s to vote..." % self.players[self.current_czar].name) # Czar vote def vote(self, player, vote): # Fail if the player isn't the current Czar if player.name != self.players[self.current_czar].name: self.message("You are not the Czar!", player) return # Fail if it's not time for the Czar to vote if self.status != "Waiting for Czar vote": self.message("We're not ready for you to vote.", player) return # Fail if the czar vote for a choice that isn't present if vote <= 0 or vote > len(self.players) - 1: self.message("%d isn't a valid vote selection." % vote, player) return # Display and increase score for the Czar's choice winning_player = self.submissions.keys()[vote - 1] self.message("%s won this round! The winning combination was..." % winning_player.name) winning_player.score += 1 # TODO: refactor this and the bit in display_selections # see display_selections, this is the same, except it only displays a single submission if "_" not in self.current_card.body: self.message(self.current_card.body) self.message(', '.join( [x.body for x in self.submissions.values()[vote - 1]])) else: replacements = [] filled_in = self.current_card.body.replace("%", "%%").replace( "_", "%s") for i in range(self.cards_needed): replacements.append( "\x02\x1F%s\x0F" % self.submissions.values()[vote - 1][i].body) filled_in = filled_in % tuple(replacements) self.message(filled_in) # And start the game loop over self.start() #deal cards to player until hand size is 10 def deal(self, player): handSize = len(player.hand) while handSize < 10: player.hand.append(self.deck.draw("white")) handSize += 1 return player.hand def choose_czar(self): self.current_czar = (self.current_czar + 1) % len(self.players) return self.players[self.current_czar] def deal_black(self): try: self.current_card = self.deck.draw("black") return self.current_card except NoMoreCards: return None def message(self, body, player=None): if player is not None: self.server.notice(player.name, body) else: self.server.privmsg(self.channel, body) @property def cards_needed(self): return self.current_card.num_answers
def test_empty_deck(self): x = Deck() x[:] = [] with self.assertRaises(IndexError): x.draw() self.assertListEqual(x, [])