Example #1
0
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)
Example #3
0
    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)
Example #4
0
    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
Example #6
0
 def test_deck_length1(self):
     x = Deck()
     card = Card("a", "b")
     x[:] = [card]
     actual = x.draw()
     self.assertEqual(actual, card)
     self.assertListEqual(x, [])
Example #7
0
 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])
Example #8
0
 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)
Example #9
0
    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)
Example #10
0
    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
Example #11
0
    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
Example #12
0
	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
Example #13
0
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
Example #14
0
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)
Example #15
0
#    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)
Example #16
0
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()
Example #17
0
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()
Example #18
0
 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)
Example #19
0
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
Example #20
0
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
Example #21
0
 def test_empty_deck(self):
     x = Deck()
     x[:] = []
     with self.assertRaises(IndexError):
         x.draw()
     self.assertListEqual(x, [])