Ejemplo n.º 1
0
def initGame(mastersound):
    '''
        Initialize a new model of the game:

        Starts the intro song

        returns a tuple 
            a deck
            a list of minidecks
            a pile
            a new playscreen
    '''


    deck = Deck()
    pile = Pile()
    minidecks = []

    mastersound.stop()
    mastersound.intro()

    #Initialize a list of slots
    
    for i in range(NUMBEROFMINID):
        minidecks.append(Minideck(deck.draw_cards(CARDSINMINIDECK)))



    pile.put(deck.draw_card())

    return deck, minidecks, pile, PlayScreen()
Ejemplo n.º 2
0
	def dealCards(self):
		theDeck = Deck()

		# DEALING CARDS
		counter = 0
		for player in self.players:
			player.cardsInHand = []
			player.playersHand = []
			for i in xrange(player.cardsLeft):
				player.recieveCard(theDeck.dealCard())
				counter += 1

		# INITING TABLE VARIABLES
		cardsOnTable = []
		self.numCardsOnTable = 0
		for player in self.players:
			for cardFromPlayer in player.playersHand:
				self.numCardsOnTable += cardFromPlayer[1]
				existOnTable = False
				for cardOnTable in cardsOnTable:
					if cardFromPlayer[0] == cardOnTable[0]:
						cardOnTable[1] += cardFromPlayer[1]
						existOnTable = True

				if not existOnTable:
					cardsOnTable.append(cardFromPlayer)

		self.cardsOnTable = cardsOnTable
Ejemplo n.º 3
0
def computeHS2( data ) :
    [pocket_assignment, board, EV_or_HS] = data
    if len(board) != 5 :
        print "HS2 only works on board lengths of 5"
        assert False
    results = {}
    d = Deck()
    d.remove( board )
    valid = all([d.remove(pa) for pa in pocket_assignment])
    if valid :
        r = pe.poker_eval( game=globles.GAME, \
                           pockets=pocket_assignment, \
                           board=board )
        if EV_or_HS == 'EV' :
            for pocket,evl in zip( pocket_assignment, r["eval"] ) :
                results[canonicalize(pocket)] = evl["ev"] / float(globles.EV_RANGE)
        else :
            for i, pocket in enumerate(pocket_assignment) :
                wins   = r["eval"][i]["winhi"]
                ties   = r["eval"][i]["tiehi"]
                losses = r["eval"][i]["losehi"]
                hs = (wins + float(ties)/2) / (wins + ties + losses)
                hs2 = hs*hs;
                #if canonicalize(pocket) == '8d8c' :
                    #print data, hs2
                results[canonicalize(pocket)] = hs2
    else :
        pass
        #raise Exception("Invalid Assignment")

    return results
Ejemplo n.º 4
0
def computeEHS2( data ) :
    [pocket_assignment, board, EV_or_HS] = data
    d = Deck()
    d.remove( board )
    valid = all([d.remove(pa) for pa in pocket_assignment])
    results = {}
    if valid :
        canonical_pockets = [canonicalize(p) for p in pocket_assignment]
        num_unknown_board = 5-len(board)
        HS2sums = {}
        counts = {}
        for pocket in canonical_pockets :
            HS2sums[pocket] = 0
            counts[pocket] = 0
        for board_suffix in combinations( d.cards, num_unknown_board ) :
            full_board = board + makeHuman(board_suffix)
            #print makeHuman(pocket), full_board
            data = [ pocket_assignment, full_board, EV_or_HS]
            HS2s = computeHS2(data)
            for pocket in canonical_pockets :
                HS2sums[pocket] += HS2s[pocket]
                counts[pocket] += 1

        for pocket in canonical_pockets :
            results[pocket] = HS2sums[pocket] / float(counts[pocket])
    return results
Ejemplo n.º 5
0
def mapReduceComputeEHS2( pool, \
                          board, \
                          num_opponents = 1 ) :

    known_pockets = [['__','__']]
    dek = Deck()
    dek.shuffle()
    dek.remove( board )
    remaining_cards = dek.cards
    possible_pockets = combinations( remaining_cards, globles.POCKET_SIZE )
    possible_pocket_assignments = combinations( possible_pockets, \
                                                num_opponents )
   
    #map
    a = time()
    all_pockets_plus_globals = wrapWithGlobals( possible_pocket_assignments, \
                                                known_pockets, \
                                                remaining_cards, \
                                                board, \
                                                'HS')
    mapped = pool.map( computeEHS2, all_pockets_plus_globals )
    #mapped: [{pocket1: HS2, __: HS2},{pocket2: HS2, __:HS2},...]
    
    d_pocket_HS2 = {}
    for pocket_hs in mapped :
        for pocket in pocket_hs :
            if pocket != canonicalize(['__','__']) :
                d_pocket_HS2[pocket] = pocket_hs[pocket]

    #print d_pocket_HS2
    return d_pocket_HS2 
    def getReward(self, state, action, transitionState):
        isDone, isFirst, isDoubleDown, hasAce, hardCount, dealerSoftCount = transitionState
        multiplier = 2 if isDoubleDown else 1
        if hardCount > 21:
            return -2 * multiplier

        softCount = hardCount + 10 if hasAce and hardCount <= 11 else hardCount
        if isDone:
            if isFirst and softCount == 21:
                return multiplier
            # Simulate the dealer's actions
            dealerAgent = DealerAgent()
            dealerCardValue = dealerSoftCount - 1 if dealerSoftCount != 11 else 0
            card = Card(0, dealerCardValue)
            dealerHand = Hand(1)
            dealerHand.addCard(card)
            deck = Deck(1, 4, 13)
            dealerHand.addCard(deck.take())
            while dealerAgent.getNextAction(None, dealerHand) == Actions.HIT:
                dealerHand.addCard(deck.take())
            return (
                multiplier
                if softCount > dealerHand.getSoftCount()
                else (0 if softCount == dealerHand.getSoftCount() else -multiplier)
            )
        else:
            return 0
Ejemplo n.º 7
0
    def launch(self, proc_number):
        """Runs a simulation
        :return: double: the ratio of successful hands over total hands
        """

        logging.info(process.current_process().name + ': Plot data will be collected every {} runs'.
                     format(self.collect_frequency))

        success_count = 0
        deck = Deck()

        for sim_nb in range(self.number_simulations):
            deck.initialise()
            card_rules=CardRules(deck)
            card_rules.set_target(self.target_rank)

            cards_in_hand = self.get_starting_hand(deck, self.starting_cards)

            for v in range(self.number_of_draws):
                retained_cards = card_rules.apply_rules(cards_in_hand)
                #draw additional cards from deck to make a full hand
                dealer_cards = [deck.get_card() for c in
                                range(self.MAX_CARDS_IN_HAND - len(retained_cards))]
                cards_in_hand=retained_cards+dealer_cards

            # at the end of the last draw we check the final hand to see if we hit the target
            is_success=card_rules.check_success(cards_in_hand)
            if is_success:
                success_count += 1
            if self.is_plot and sim_nb % self.collect_frequency == 0 and sim_nb > 0:
                self._intermediate_results.append((success_count) / sim_nb)

        self._simulation_result = (success_count)/self.number_simulations
        return self
 def test_remove_top_card_object(self):
     test_deck_path = os.path.join("..", "decks", "testdeckold.json")
     deck = Deck("Some Dude", test_deck_path)
     deck_size = len(deck.deck)
     card = deck.deck[0]
     deck.remove_card(card)
     self.assertEqual(deck_size, len(deck.deck) + 1)
Ejemplo n.º 9
0
class Game(object):
	def __init__(self):
		self.player = Player()
		self.deck = Deck()
		self.dealer = Dealer()
		self.isFirstDeal = True


	def dealToPlayer(self):
		if self.isFirstDeal:
			card1 = self.deck.randomDraw()
			card2 = self.deck.randomDraw()
			self.player.hand.extend([card1, card2])
			self.isFirstDeal = False
		else:
			card = self.deck.randomDraw()
			self.player.hand.append(card)
		pass
		
		print "Your Hand: ", self.player.hand
	
	def play_round(self):
		while self.player.play_action().low() == "h": #returns Hit or Stand"
			if self.player.choice.low() == "h":
				self.player.dealToPlayer()
			else: # end of the game
				self.player.hand
				self.dealer.play_action()
		
			
	def play_game(self):
Ejemplo n.º 10
0
class Player():
    def __init__(self, name, cash):
        """
        name:  name of the player
        cash:  used for gambling
        hand:  your current hand of cards
        total: blackjack total
        """

        self.name  = name
        self.cash  = cash
        self.hand  = Deck()
        self.total = 0

    def __str__(self):
        """ pretty printing """
        return "{} (${:>5}): <{:>3}> | {}".format(self.name, self.cash, self.total, self.hand)

    def __add__(self, card):
        """ add card to the hand """
        self.hand.return_card(card)
        self._find_total()
        return self

    def _find_total(self):
        """ Total is blackjack specific """
        total = 0
        for card in self.hand:
            if card.rank.isdigit():
                total += int(card.rank)
            elif card.rank in ["K", "Q", "J"]:
                total += 10

        for card in self.hand:
            if card.rank == "A":
                if total + 11 < 21:
                    total += 11
                else:
                    total += 1
        self.total = total

    def discard(self):
        """ remove all cards from hand, to put back into the deck """
        tmp = self.hand
        self.hand  = Deck()
        self.total = 0
        return tmp

    def wager(self, cash):
        """ subtract cash, return the pot amount """
        # You can't wager more than you have
        if cash > self.cash:
            # cash goes to 0, bet all you have
            tmp = self.cash
            self.cash = 0
            return tmp

        else:
            self.cash -= cash
            return cash
Ejemplo n.º 11
0
 def test_middle_to_stack(self):
     deck = Deck()
     current_deck = deck.deck
     current_middle = deck.get_current_middle()
     current_deck.append(current_middle)
     deck.middle_to_stack()
     self.assertEqual(current_deck, deck.deck)
Ejemplo n.º 12
0
def game():
    # Instantiate game deck, player and dealer
    deck = Deck()
    player = Hand()
    dealer = Hand()

    # Initial Deal
    player.hand = [deck.hit() for _ in range(2)]
    dealer.hand = [deck.hit() for _ in range(2)]

    print("\n\nWelcome to Blackjack.\n")
    playing = True
    player_stays = False

    while playing is True:
        player.get_value()
        dealer.get_value()
        print("Your Hand: {}".format(list(player.hand[0:])))
        print("Your Hand's Value: {}".format(player.value))

        print("\nDealer's Hand: [xxx Hidden Card xxx], {}".format(dealer.hand[1:]))
        print("Dealer's Hand Value Showing: {}".format(dealer.shown_value))
        print("_" * 60)
        if player_stays is False:
            if player.value < 21:
                player_hit = input("\nWould you like to hit? Y/n").lower()
                if player_hit != 'n':
                    player.hand.append(deck.hit())
                else:
                    print("You Have Decided To Stay.")
                    player_stays = True
            else:
                player_stays = True
        else:
            if player.value > 21:
                print("You Lose! Bust!")
                playing = False
            else:
                if dealer.value < 17:
                    dealer.hand.append(deck.hit())
                    print("Dealer Hits.")
                else:
                    if dealer.value > 21:
                        print("You Win! Dealer Busts.")
                        playing = False
                    elif dealer.value > player.value:
                        print("Dealer's Hand Beats Yours. You lost.")
                        playing = False
                    elif dealer.value == player.value:
                        print("Push. Nobody won.")
                        playing = False
                    else:
                        print("Your Hand Beats Dealer's Hand! You Win!")
                        playing = False

    print("\n\nDealer's Hand Was: {}  Total Value {}".format(dealer.hand, dealer.value))
    if input("\nGame over. Play again? Y/n").lower() != 'n':
        game()
    else:
        print("Goodbye!")
Ejemplo n.º 13
0
class DeckTest(unittest.TestCase):


	def setUp(self):
		"""Set up testing environment for deck"""
		self.deck = Deck()

	def tearDown(self):
		"""Tear down testing environment for deck"""
		self.deck = None

	def test_check_bust_true(self):
		"""Test that if someone busts, it returns True"""
		hand = ['Ts', '9c', 'Qs']
		self.assertEqual(self.deck.check_bust(hand), True)

	def test_check_bust_false(self):
		"""Test that if someone does not bust, it returns False"""
		hand = ['2d', '3s', '5d', '6h']
		self.assertEqual(self.deck.check_bust(hand), False)

	def test_check_bust_21(self):
		"""Test that if someone has exactly 21 they do not bust and return False"""
		hand = ['Js', 'Ac']
		self.assertEqual(self.deck.check_bust(hand), False)

	def test_grab_numbers(self):
		"""Test that the numbers or face cards are selected from their suits for adding"""
		hand = ['Js', '2d']
		self.assertEqual(self.deck.grab_numbers(hand), [10, 2])

	def test_calculate_hand(self):
		"""Test that the numbers from the cards add up"""
		hand = ['Ad', '5h', '2h']
		self.assertEqual(self.deck.calculate_hand(hand), 18)
Ejemplo n.º 14
0
Archivo: game.py Proyecto: jkloo/Golf
class Game:
    ''' '''
    def __init__(self, nplayers, ndecks=1):
        ''' '''
        self.deck = Deck()
        self.players = [deepcopy(NO_PLAYER) for i in range(nplayers)]
        self.curr_plr = self.players[0]

    def begin(self, ncards):
        ''' '''
        self.curr_plr = self.players[0]
        self.deck.shuffle()
        self.deal(ncards)

    def deal(self, n):
        ''' '''
        for p in self.players:
            p.hand.cards = self.deck.draw(n)

    def new_player(self, name, seat):
        ''' '''
        if NO_PLAYER in self.players:
            if (seat >= len(self.players)) or not (self.players[seat] == NO_PLAYER):
                # if the seat preference is taken, seat in the minimum available seat
                seat = min([x for x in range(len(self.players)) if self.players[x] == NO_PLAYER])
            self.players[seat] = Player(name, seat)

    def next_player(self):
        ''' '''
        id_ = self.players.index(self.curr_plr)
        id_ += 1
        if id_ >= len(self.players):
            id_ = 0
        self.curr_plr = self.players[id_]
Ejemplo n.º 15
0
    def next_card(self, turn_deck=None):
        if not turn_deck:
            turn_deck = Deck()
        if self.is_game_over():
            return
        self.turn += 1
        print("Turn {}".format(self.turn))
        print("Decks:\n------\nPlayer 1: {}\nPlayer 2: {}"
               .format(self.deck1, self.deck2))
        c1 = self.deck1.deal()
        c2 = self.deck2.deal()
        turn_deck.add(c1)
        turn_deck.add(c2)

        print("{}   {}\n".format(c1, c2))
        higher_card = self.determine_higher_card(c1, c2)
        if higher_card == 1:
            for card in turn_deck.cards:
                self.deck1.add(card)    # TODO more pythonic if just in turn_deck
        elif higher_card == 2:
            for card in turn_deck.cards:
                self.deck2.add(card)    # TODO more pythonic if just in turn_deck
        else:
            self.go_to_war(turn_deck)
        return
Ejemplo n.º 16
0
class Game(object):
    '''
    classdocs
    '''
    

    def __init__(self, lang, startPoint, nteams):
        '''
        Constructor
        '''
        # Initialize all the game related stuff 
        # TODO: error check on deckPath
        # Initialize the Deck 
        self.deckEmpty = True
        deckPath = DECKS_FOLDER + "/"+lang[0:2]+"/cards"
        self.deck = Deck(deckPath, startPoint)
        if self.deck.getLength() > 0: 
            self.deckEmpty = False
       
        # Initialize the teams object 
        self.teams = []
        for i in range(0, nteams):
            self.teams.append(Team(self, i))
        
        # Initialize the game board TODO 
        self.board = 0
    
    def newTurn(self, timeout):
        '''
        Create turn and select not last playing team.
        return back the turn object pointer.
        '''
        for t in self.teams:
            if t.wasLastPlaying() == False:
                break
        
        if t.wasLastPlaying():
            raise Exception('Error in teams switching')
        #TODO: start team play
        
        turn = Turn(self, t, timeout)
        self.currentTurn = turn
        return self.currentTurn
    
    def getCurrentTurn(self):
        return self.currentTurn
    
    def isDeckEmpty(self):
        return self.deckEmpty
    
    def getRandomCard(self):
        '''
        Pick a card randomly. The picked card will be removed from the deck.
        '''
        if self.deck.getLength() > 0:
            return self.deck.getRandomCard()
        else:
            self.deckEmpty = True
            return False
Ejemplo n.º 17
0
  def testDrawCards(self):
     '''
       Tests drawing multiple cards
     '''

     deck = Deck()
     self.assertEqual(len(deck.draw_cards(5)), 5)
     self.assertEqual(len(deck._deck), 52-5)
Ejemplo n.º 18
0
 def test_pop_four_from_deck_of_two_returns_two(self):
     deck = Deck(0)
     deck.cards.extend([self.two, self.ace])
     result = deck.pop_card(4)
     result_contains_cards = self.two in result and self.ace in result
     self.assertTrue(result_contains_cards)
     self.assertEqual(len(deck.cards), 0)
     self.assertEqual(len(result), 2)
Ejemplo n.º 19
0
 def initialize_deck(self):
     cards = []
     for value in range(1, 14):
         cards.extend(BlackJackCard(value, Suit(st))
                      for st in Suit.get_all_suit_types())
     deck = Deck()
     deck.set_cards(cards)
     deck.reset()
     self._deck = deck
Ejemplo n.º 20
0
def test_deck52Cards():
	"""
	Checks if returned deck is a normal 52 card deck.
	"""
	myDeck = Deck()
	myDeck.shuffle()
	
	cards = myDeck.getCards()
	assert len(cards) == 52
Ejemplo n.º 21
0
	def testNumbCardsLeft():
		#Testing method numbCardsLeft
		
		deck = Deck()

		assert deck.numbCardsLeft() == 52

		del deck.deck["two"]

		assert deck.numbCardsLeft() == 48
Ejemplo n.º 22
0
def start_new_deal(game_state, dealer_index):
    deck = Deck()
    game_state.cards_remaining = set(deck.cards)
    hands = deck.deal()
    game_state.trump = hands[dealer_index][-1].suit
    for i in xrange(NUM_PLAYERS):
        game_state.players[i].cards = hands[i]
        game_state.players[i].round_start(game_state)
    reset_player_possible_suits(game_state)
    reset_unlikelies(game_state)
Ejemplo n.º 23
0
    def test_calc_total_vp(self):
        """Test calculating the total vp in a player's deck."""
        deck = Deck()

        # Test that a default deck has 3 VP
        assert_equal(deck.calc_total_vp(), 3)

        # Test that adding a province gives 9 VP
        deck.discard_pile.append(cards.Province)
        assert_equal(deck.calc_total_vp(), 9)
 def test_deck_shuffles(self):
     test_deck_path = os.path.join("..", "decks", "smalltestdeck.json")
     df = Deck("Some Dude", test_deck_path)
     df.shuffle(3)
     test_shuffle_output = os.path.join("..", "decks", "smalltestdeckshuffletest.txt")
     with open(test_shuffle_output, "r") as fp:
         expected_output = fp.readlines()
         for i in range(0,len(df.deck)):
             self.assertIn(str(df.deck[i].power), expected_output[i])
             self.assertIn(str(df.deck[i].denomination), expected_output[i])
    def test_card_from_string_function(self):

        df = Deck("TestName")
        card_example = "9 1 Tribble - Go"
        count = 0
        for each_card in df.convert_string_to_cards(card_example):
            count += 1
            self.assertEqual(each_card.denomination, 1)
            self.assertEqual(each_card.power, Power.Go)
        self.assertEqual(count, 9)
Ejemplo n.º 26
0
class DeckTest (unittest.TestCase):
	def setUp(self):
		self.deck = Deck()

	def test_reset(self):
		# reset deck to contain all cards
		self.deck.reset()

		self.assertEquals(len(self.deck.cards), self.deck.size, "Deck should be "+ str(self.deck.size) +" cards.")
		self.assertTrue((3, 's') in self.deck.cards, " Three of Spades should be included.")
		self.assertFalse((12, 'd') in self.deck.cards, " Twelve of Diamonds should not be included.")

		spades = [ card for card in self.deck.cards if card[1] == 's' ]
		self.assertEquals(len(spades), self.deck.size / 4, "Spades are 1/4 of the deck")

	def test_shuffle(self):
		self.deck.reset()
		self.deck.shuffle()

		self.assertEquals(len(self.deck.cards), self.deck.size, "Deck must stay the same size.")

	def test_deal_card(self):
		self.deck.reset()
		initial_size = self.deck.size
		last_card_in_deck = self.deck.cards[-1]

		card = self.deck.deal_card()
		new_size = self.deck.size

		self.assertEquals(initial_size, new_size + 1, "New Deck is correct size")
		self.assertEquals(last_card_in_deck, card, "Dealt card was at end of deck")
Ejemplo n.º 27
0
def couple_check():
    card_to_check = 1;
    myDeck = Deck("French", 13)
    myDeck.shuffle_deck()
    success = False
    card_1 = myDeck.pop_card()
    card_2 = myDeck.pop_card()
	
    if (card_1['number'] == card_to_check and card_2['number'] == card_to_check):
	success = True	
    return success
Ejemplo n.º 28
0
class Table:

    def __init__(self):
        self.__read_config__()
        self.__init__seats()
        self.button = self.conf["button"]
        self.big_blind_amount = self.conf["big_blind_amount"]
        self.small_blind_amount = self.conf["small_blind_amount"]
        self.rake = self.conf["rake"]
        self.deck = Deck()
        self.pot = 0


    def __init__seats(self):
        self.seats = []
        for player in range(1, 11):
            try:
                conf = self.conf["seats"][str(player)]
                if not conf:
                    self.seats.append(None)
                else:
                    self.seats.append(Player(conf, table=self))
            except:
                self.seats.append(None)


    def __read_config__(self):
        self.conf = json.loads(open("table_config.json").read())        

    def take_blinds(self):
        button = int(self.button)
        current_seat = button
        small_blind_taken = False
        big_blind_taken = False
        while not big_blind_taken:
            current_seat = current_seat + 1 
            if current_seat == 11:
                current_seat = 1
            if self.seats[current_seat]:
                if small_blind_taken:
                    self.pot = self.pot + self.seats[current_seat].take_money(self.big_blind_amount)
                    big_blind_taken = True
                else:
                    self.pot = self.pot + self.seats[current_seat].take_money(self.small_blind_amount)
                    small_blind_taken = True
            

    def deal(self):
        self.take_blinds()
        self.deck.new_deck()
        for card in range(0, 2):
            for player in self.seats:
                if player:
                    player.accept_card(self.deck.get_card())
Ejemplo n.º 29
0
class CoupGame(object):
    def __init__(self):
        self.deck = Deck()
        self.destroyedCards = []
        self.players = PlayerQueue()

        #coins dispersed
        self.treasury = 50 - 2 * self.players.numPlayers() #50 is starting amt

        #deck shuffled
        self.deck.shuffle()
Ejemplo n.º 30
0
class CardGame:
    def __init__(self):
        self.deck = Deck()
        self.deck.shuffle()

    def getDeck(self):
        return self.deck

    def printHands(self):
        for hand in self.hands:
            print hand
Ejemplo n.º 31
0
    def __init__(self, num_players=2):

        self.num_players = num_players

        self.hands = [Hand for _ in range(num_players)]
        self.deck = Deck()
Ejemplo n.º 32
0
 def __init__(self, deck: Deck = Deck(), number_of_players=DEFAULT_NUM_OF_PLAYERS):
     self._players = []
     self._hand_to_player = {}
     self._deck = deck
     self.number_of_players = number_of_players
     self._game_setup()
Ejemplo n.º 33
0
	def __init__(self):
		super(Game, self).__init__()
		self.deck = Deck()
		self.score = dict.fromkeys(['p1', 'p2'], 0) # Should this be a view?
		self.history = OrderedDict()
		self.winner = True in [self.score[p] >= 121 for p in self.score.keys()]
Ejemplo n.º 34
0
    def test_missing_cards_from_sideboard(self):
        test_collection = Collection(TEST_COLLECTION_NAME)
        self.assertEqual(test_collection.size(), 0)
        empty_main_deck = []
        test_sideboard = []
        CARDS_IN_SIDEBOARD = 25
        ARBITRARY_NUMBER = 5  #must be less than CARDS_IN_SIDEBOARD

        for x in range(0, CARDS_IN_SIDEBOARD):
            quantity = random.randint(1, 4)
            card = Card("card" + str(x), quantity)
            test_sideboard.append(card)

        test_deck = Deck(empty_main_deck, test_sideboard)

        #an empty collection should be missing every card
        cards_missing_from_sideboard = test_collection.missing_cards_from_sideboard(
            test_deck)

        #assert that return list is of equal length to deck
        self.assertEqual(len(cards_missing_from_sideboard), CARDS_IN_SIDEBOARD)
        index = 0
        for card in cards_missing_from_sideboard:
            #assert that return list has a list of cards equivalent to sideboard
            self.assertEqual(card.name, test_deck.sideboard[index].name)
            self.assertEqual(card.quantity,
                             test_deck.sideboard[index].quantity)
            index += 1

        #a "full" collection should be missing no cards
        for x in range(0, CARDS_IN_SIDEBOARD + CARDS_IN_SIDEBOARD):
            quantity = random.randint(4, 10)
            card = Card("card" + str(x), quantity)
            test_collection.add_card(card)

        cards_missing_from_sideboard = test_collection.missing_cards_from_main_deck(
            test_deck)
        self.assertEqual(len(cards_missing_from_sideboard), 0)

        #a "partially full" collection should be missing some cards
        test_collection = Collection(TEST_COLLECTION_NAME)
        self.assertEqual(test_collection.size(), 0)

        for x in range(0, CARDS_IN_SIDEBOARD - ARBITRARY_NUMBER):
            quantity = random.randint(0, 2)
            card = Card("card" + str(x), quantity)
            test_collection.add_card(card)

        cards_missing_from_sideboard = test_collection.missing_cards_from_sideboard(
            test_deck)

        index = 0
        for card in test_deck.sideboard:
            if not test_collection.cards.get(card.name):
                self.assertEqual(cards_missing_from_sideboard[index].name,
                                 card.name)
                self.assertEqual(cards_missing_from_sideboard[index].quantity,
                                 card.quantity)
                index += 1
            elif test_collection.cards.get(card.name) < card.quantity:
                self.assertEqual(cards_missing_from_sideboard[index].name,
                                 card.name)
                self.assertEqual(
                    cards_missing_from_sideboard[index].quantity,
                    card.quantity - test_collection.cards.get(card.name))
                index += 1

        #test when cards are overlapping from sideboard and maindeck
        test_collection = Collection(TEST_COLLECTION_NAME)
        self.assertEqual(test_collection.size(), 0)
        test_sideboard = []
        test_main_deck = []

        #populate collection
        for x in range(0, 1000):
            quantity = random.randint(1, 20)
            card = Card("card" + str(x), quantity)
            test_collection.add_card(card)

        #populate sideboard
        for x in range(0, 1000):
            quantity = random.randint(1, 10)
            card = Card("card" + str(x), quantity)
            test_sideboard.append(card)

        #populate maindeck
        for x in range(0, 1000):
            quantity = random.randint(1, 10)
            card = Card("card" + str(x), quantity)
            test_main_deck.append(card)
        self.assertEqual(len(test_sideboard), 1000)
        self.assertEqual(len(test_main_deck), 1000)
        test_deck = Deck(test_main_deck, test_sideboard)
        cards_missing_from_sideboard = test_collection.missing_cards_from_sideboard(
            test_deck)
        cards_missing_from_main_deck = test_collection.missing_cards_from_main_deck(
            test_deck)
        sideboard_index = 0
        main_deck_index = 0

        #quantity in collection + cards_missing_from_main_deck + cards_missing_from_sideboard (cmm)
        # = main_deck + sideboard
        #if quanitity in collection < quantity main + quantity board
        md_bounds = len(cards_missing_from_main_deck)
        sb_bounds = len(cards_missing_from_sideboard)
        for x in range(0, 1000):
            current_card = "card" + str(x)
            cmm_quantity = 0
            tmp_side = 0
            tmp_main = 0
            if sideboard_index < sb_bounds:
                if cards_missing_from_sideboard[
                        sideboard_index].name == current_card:
                    tmp_side = cards_missing_from_sideboard[
                        sideboard_index].quantity
                    cmm_quantity += cards_missing_from_sideboard[
                        sideboard_index].quantity
                    sideboard_index += 1

            if main_deck_index < md_bounds:
                if cards_missing_from_main_deck[
                        main_deck_index].name == current_card:
                    tmp_main = cards_missing_from_main_deck[
                        main_deck_index].quantity
                    cmm_quantity += cards_missing_from_main_deck[
                        main_deck_index].quantity
                    main_deck_index += 1
            if test_collection.cards.get(current_card) >= (
                    test_deck.main_deck[x].quantity +
                    test_deck.sideboard[x].quantity):
                pass
            else:
                self.assertEqual(
                    test_collection.cards.get(current_card) + cmm_quantity,
                    test_deck.main_deck[x].quantity +
                    test_deck.sideboard[x].quantity)
Ejemplo n.º 35
0
class Game(object):
    """ This class represents a game of UNO """
    current_player = None
    reversed = False
    choosing_color = False
    started = False
    draw_counter = 0
    players_won = 0
    starter = None
    mode = DEFAULT_GAMEMODE
    job = None
    owner = ADMIN_LIST
    open = OPEN_LOBBY
    translate = ENABLE_TRANSLATIONS
    scores = dict()
    last_round_score = list()
    win_score = SCORE_WIN

    def __init__(self, chat):
        self.chat = chat
        self.last_card = None

        self.deck = Deck()

        self.logger = logging.getLogger(__name__)

    @property
    def players(self):
        """Returns a list of all players in this game"""
        players = list()
        if not self.current_player:
            return players

        current_player = self.current_player
        itplayer = current_player.next
        players.append(current_player)
        while itplayer and itplayer is not current_player:
            players.append(itplayer)
            itplayer = itplayer.next
        return players

    def start(self):
        if self.mode == None or self.mode != "wild":
            self.deck._fill_classic_()
        else:
            self.deck._fill_wild_()

        self._first_card_()
        self.started = True

    def set_mode(self, mode):
        self.mode = mode

    def reverse(self):
        """Reverses the direction of game"""
        self.reversed = not self.reversed

    def turn(self):
        """Marks the turn as over and change the current player"""
        self.logger.debug("Next Player")
        self.current_player = self.current_player.next
        self.current_player.drew = False
        self.current_player.turn_started = datetime.now()
        self.choosing_color = False

    def _first_card_(self):
        # In case that the player did not select a game mode
        if not self.deck.cards:
            self.set_mode(DEFAULT_GAMEMODE)

        # The first card should not be a special card
        while not self.last_card or self.last_card.special:
            self.last_card = self.deck.draw()
            # If the card drawn was special, return it to the deck and loop again
            if self.last_card.special:
                self.deck.dismiss(self.last_card)

        self.play_card(self.last_card)

    def play_card(self, card):
        """
        Plays a card and triggers its effects.
        Should be called only from Player.play or on game start to play the
        first card
        """
        self.deck.dismiss(self.last_card)
        self.last_card = card

        self.logger.info("Playing card " + repr(card))
        if card.value == c.SKIP:
            self.turn()
        elif card.special == c.DRAW_FOUR:
            self.draw_counter += 4
            self.logger.debug("Draw counter increased by 4")
        elif card.value == c.DRAW_TWO:
            self.draw_counter += 2
            self.logger.debug("Draw counter increased by 2")
        elif card.value == c.REVERSE:
            # Special rule for two players
            if self.current_player is self.current_player.next.next:
                self.turn()
            else:
                self.reverse()

        # Don't turn if the current player has to choose a color
        if card.special not in (c.CHOOSE, c.DRAW_FOUR):
            self.turn()
        else:
            self.logger.debug("Choosing Color...")
            self.choosing_color = True

    def choose_color(self, color):
        """Carries out the color choosing and turns the game"""
        self.last_card.color = color
        self.turn()

    def add_score(self, player):
        """Add total value of all card in every players hand
        to the winner's score."""
        scores = 0
        self.last_round_score.clear()
        for p in self.players:
            for card in p.cards:
                sc = c.CARD_SCORES[card.value or card.special]
                self.last_round_score.append((sc, card))
                scores += sc
        try:
            self.scores[player.user.id] += scores
        except KeyError:
            self.scores[player.user.id] = scores

    def reset_cards(self):
        """Reset game deck and player's hand"""
        players_cache = self.players
        # clear player's card, might as well use player.cards.clear()
        for player in players_cache:
            for card in player.cards:
                self.deck.dismiss(card)
            player.cards = list()
        # fill deck with normal cards set
        self.deck._fill_classic_()
        # draw player's hand
        for player in players_cache:
            player.draw_first_hand()

    def new_round(self):
        lc = self.last_card
        while self.last_card == lc or not self.last_card or self.last_card.special:
            self.last_card = self.deck.draw()
            # If the card drawn was special, return it to the deck and loop again
            if self.last_card.special:
                self.deck.dismiss(self.last_card)
        self.play_card(self.last_card)

    def get_score(self, player):
        try:
            return self.scores[player.user.id]
        except KeyError:
            self.scores[player.user.id] = 0
            return 0

    def get_scores(self):
        return [(player, self.get_score(player)) for player in self.players]
Ejemplo n.º 36
0
    def __init__(self):
        self.draw_pile = Main_Deck()
        self.discard_pile = Deck()
        self.foundation_1 = Deck()
        self.foundation_2 = Deck()
        self.foundation_3 = Deck()
        self.foundation_4 = Deck()

        self.deck_1 = Deck()
        self.deck_2 = Deck()
        self.deck_3 = Deck()
        self.deck_4 = Deck()
        self.deck_5 = Deck()
        self.deck_6 = Deck()
        self.deck_7 = Deck()

        self.distribute_cards()
Ejemplo n.º 37
0
def build_num_deck():
    return Deck(reduce(lambda x,y: x + y, list(map(lambda x: [x] * nums_dist[x],
                                                   [i for i in range(1,10)]))))
Ejemplo n.º 38
0
        print('Choose:')
        print('1. Hit, or 2. Stand')
        hit = player.input()
        if hit:
            player.pick(deck.get_one())
        else:
            break
    player.clear()

    print(player.name + '\'s total sum was:', 'BUST!' if bust else card_sum)

    return -1 if bust else card_sum


if __name__ == "__main__":
    deck = Deck()

    player = Player()
    comp = Computer()
    _round = 1

    while player.balance > 0:
        print('ROUND', _round)
        print('The player\'s balance is', player.balance)

        while True:
            try:
                print('Enter the bidding amount.')
                bid_amount = int(input('> '))
                player.bid(bid_amount)
                break
Ejemplo n.º 39
0
class Hanabi:

    players = []
    deck = None
    discard_pile = []
    clock = 8
    fuse = 3
    fireworks = {'green': 0, 'white': 0, 'red': 0, 'yellow': 0, 'blue': 0}
    last_round_counter = 0

    def __init__(self, n_players):
        self.turn_number = 0
        self.discard_pile = []
        self.clock = 8
        self.fuse = 3
        self.last_round_counter = 0
        self.last_round = False
        self.hints = {}
        self.available_hints = []
        self.last_action_taken = None

        self.deck = Deck()
        self.deck.shuffle()

        self.n_players = n_players
        self.player_hands = {}

        for i in range(n_players):
            self.players.append(Player(i))
            self.hints[i] = []

        if n_players <= 3:
            n_cards = 5
        else:
            n_cards = 4

        for p in self.players:
            #p.hand = [None]*n_cards
            self.player_hands[p.player_number] = [None] * n_cards
            for card_num in range(n_cards):
                #self.draw_card(p, card_num)
                #p.draw(self.deck)

                self.draw_card(p.player_number, card_num)

        self.current_player = random.randint(0, n_players - 1)

        for p in self.players:
            p.log_observed_state(self.observed_state(p.player_number))

        # log = Log()
        # log.log_state(self.game_state())

    def game_state(self):
        state = {
            'fireworks': self.fireworks,
            'clock': self.clock,
            'fuse': self.fuse,
            'last_round': self.last_round,
            'last_round_counter': self.last_round_counter,
            'current_player': self.current_player,
            'turn_number': self.turn_number,
            'cards_left': self.deck.cards_left(),
            'player_hands': self.player_hands,
            'discard_pile': self.discard_pile,
            'last_action_taken': self.last_action_taken
        }
        return state

    def observed_state(self, player_number):
        observed_hands = deepcopy(self.player_hands)
        masked_hand = list(
            map(lambda x: x != None, self.player_hands[player_number]))
        observed_hands[player_number] = masked_hand
        state = {
            'fireworks': self.fireworks,
            'clock': self.clock,
            'fuse': self.fuse,
            'last_round': self.last_round,
            'last_round_counter': self.last_round_counter,
            'current_player': self.current_player,
            'turn_number': self.turn_number,
            'cards_left': self.deck.cards_left(),
            'player_hands': observed_hands,
            'discard_pile': self.discard_pile,
            'hints': self.hints,
            'last_action_taken': self.last_action_taken
        }
        return deepcopy(state)

    def next_turn(self):

        if self.last_round:
            print("LAST ROUND")
            self.last_round_counter += 1

        # Print game state info
        print("\n")
        print("-" * 20)
        print("Player #{}'s turn.\n".format(self.current_player))

        print("Time left: {}".format(self.clock))
        print("Fuse length: {}\n".format(self.fuse))
        print("Discarded/played cards: {}\n".format(self.discard_pile))
        print("{} cards left in deck. \n".format(self.deck.cards_left()))

        #print("\nFireworks: {}\n".format(self.fireworks))
        self.print_fireworks()

        # print("\nOther players' hands:")
        # for p in self.players:
        #     if p.player_number == self.current_player:
        #         pass
        #     else:
        #         print("Player #{}: {}".format(p.player_number, self.player_hands[p.player_number]))

        print("")
        self.print_observed_hands(self.current_player)
        print("")

        #print("\nHints given:")
        #pprint(self.hints)
        self.print_hints()

        # update hint options
        #self.hint_options = self.generate_hints(self.current_player)

        player_action = self.players[self.current_player].take_turn()
        self.take_action(self.current_player, player_action)

        self.current_player = (self.current_player + 1) % self.n_players
        self.turn_number += 1

        for p in self.players:
            p.log_observed_state(self.observed_state(p.player_number))

    def take_action(self, player_number, action):
        if action['action'] == 'discard_card':
            card_num = action['action_data']
            self.discard_card(player_number, card_num)
        elif action['action'] == 'play_card':
            card_num = action['action_data']
            self.play_card(player_number, card_num)
        elif action['action'] == 'give_hint':
            # hint_num = action['num']
            # hint = self.hint_options[hint_num]
            # self.hints[hint['player']].append({'cards': hint['cards'], 'card_type': hint['card_type']})

            hint = action['action_data']
            if hint not in self.hint_options(player_number):
                print("Invalid Hint.")
                return -1
            else:
                self.hints[hint['player']].append({
                    'cards':
                    hint['cards'],
                    'card_type':
                    hint['card_type']
                })
                self.clock -= 1
                print("Hint: {} given. 1 hour lost.".format(hint))

        else:
            print("Error. Invalid Action")
        self.last_action_taken = {
            'player': player_number,
            'action': action['action'],
            'action_data': action['action_data']
        }

    def hint_options(self, player_number):
        hint_options = []

        for p_num, hand in self.player_hands.items():
            if p_num == player_number:
                continue

            card_types = set([i[0] for i in hand] + [i[1] for i in hand])
            for t in card_types:
                card_nums = []
                if type(t) == str:
                    for card_num, card in enumerate(hand):
                        if card[0] == t:
                            card_nums.append(card_num)
                else:
                    for card_num, card in enumerate(hand):
                        if card[1] == t:
                            card_nums.append(card_num)
                hint = {'player': p_num, 'cards': card_nums, 'card_type': t}
                hint_options.append(hint)

        return hint_options

    # def give_hint(self, player_number, hint):
    #     self.hints[player_number].append(hint)
    #     self.clock -= 1

    # def discard_card(self, player, card_num):
    #     card = player.hand[card_num]
    #     self.discard_pile.append(card)
    #     print("Card {} discarded.".format(card))
    #     self.clock = min(self.clock + 1, 8)

    #     self.draw_card(player, card_num)

    def discard_card(self, player_number, card_num):
        card = self.player_hands[player_number][card_num]
        self.discard_pile.append(card)
        print("Card {} discarded.".format(card))
        self.clock = min(self.clock + 1, 8)

        self.draw_card(player_number, card_num)

    # def draw_card(self, player, card_num):
    #     # draw new card and put it in the place of the old one
    #     if self.deck.cards_left() > 0:
    #         player.hand[card_num] = self.deck.pop()
    #     else:
    #         player.hand[card_num] = None
    #         print("No more cards in deck. No card drawn")
    #         pass

    #     # remove hints relating to the old card
    #     player_hints = self.hints[player.player_number]
    #     new_hints = []
    #     for h in player_hints:
    #         try:
    #             h[0].remove(card_num)
    #         except:
    #             pass
    #         if len(h[0]) == 0:
    #             continue
    #         else:
    #             new_hints.append(h)
    #     self.hints[player.player_number] = new_hints

    #     #print(self.hints[player.player_number])

    def draw_card(self, player_number, card_num):
        # draw new card and put it in the place of the old one
        if self.deck.cards_left() > 0:
            self.player_hands[player_number][card_num] = self.deck.pop()
        else:
            self.player_hands[player_number][card_num] = None
            print("No more cards in deck. No card drawn")
            return 0

        # print("hints for player {}".format(player.player_number))
        #
        # print(player_hints)

        # remove hints relating to the old card
        print("removing hints")
        print("card_num: {}".format(card_num))
        player_hints = self.hints[player_number]

        print("player_hints: {}".format(player_hints))
        new_hints = []
        for h in player_hints:
            try:
                h['cards'].remove(card_num)
                #h[0].remove(card_num)
            except:
                continue
            if len(h['cards']) == 0:
                continue
            else:
                new_hints.append(h)
        self.hints[player_number] = new_hints

        print(self.hints[player.player_number])

    # def play_card(self, player, card_num):
    #     # play the card
    #     card = player.hand[card_num]
    #     self.discard_pile.append(card)

    #     stack_count = self.fireworks[card[0]]
    #     if card[1] == stack_count + 1:
    #         self.fireworks[card[0]] += 1
    #         print("Card {} successfully added".format(card))
    #         print("Fireworks: {}".format(self.fireworks))
    #         # 5 - firework complete
    #         if self.fireworks[card[0]] == 5:
    #             print("{} firework complete! 1 hour has been added to the clock.".format(card[0]))
    #             self.clock = min(self.clock + 1, 8)
    #     else:
    #         print("Card {} does not match any fireworks.".format(card))
    #         print("Card discarded and fuse has been shortened. Fuse: {}".format(self.fuse))
    #         self.fuse -= 1

    #     self.draw_card(player, card_num)

    def play_card(self, player_number, card_num):
        # play the card
        card = self.player_hands[player_number][card_num]
        self.discard_pile.append(card)

        stack_count = self.fireworks[card[0]]
        if card[1] == stack_count + 1:
            self.fireworks[card[0]] += 1
            print("Card {} successfully added".format(card))
            print("Fireworks: {}".format(self.fireworks))
            # 5 - firework complete
            if self.fireworks[card[0]] == 5:
                print(
                    "{} firework complete! 1 hour has been added to the clock."
                    .format(card[0]))
                self.clock = min(self.clock + 1, 8)
        else:
            print("Card {} does not match any fireworks.".format(card))
            self.fuse -= 1
            print(
                "Card discarded and fuse has been shortened. Fuse: {}".format(
                    self.fuse))

        self.draw_card(player_number, card_num)

    def end_game(self):
        print("*" * 20)
        final_score = reduce(lambda x, y: x + y, self.fireworks.values())
        print("Game Over. Final Score: {}".format(final_score))
        if final_score <= 5:
            print("Horrible.")
        elif final_score <= 10:
            print("Mediocre.")
        elif final_score <= 15:
            print("Honorable Attempt")
        elif final_score <= 20:
            print("Excellent, crowd pleasing.")
        elif final_score <= 24:
            print("Amazing, they will be talking about it for weeks!")
        elif final_score >= 25:
            print("Legendary, everyone left speechless, stars in their eyes!")
        return final_score

    def get_color_tag(self, color):
        if color == 'white':
            return Style.BRIGHT + Fore.WHITE
        elif color == 'yellow':
            return Style.BRIGHT + Fore.YELLOW
        elif color == 'red':
            return Style.BRIGHT + Fore.RED
        elif color == 'green':
            return Style.BRIGHT + Fore.GREEN
        elif color == 'blue':
            return Style.BRIGHT + Fore.BLUE

    def print_fireworks(self):
        print("Fireworks: ", end=' ')
        print(Style.BRIGHT + Fore.YELLOW +
              'yellow:{}'.format(self.fireworks['yellow']) + Style.RESET_ALL,
              end='  ')
        print(Style.BRIGHT + Fore.RED +
              'red:{}'.format(self.fireworks['red']) + Style.RESET_ALL,
              end='  ')
        print(Style.BRIGHT + Fore.WHITE +
              'white:{}'.format(self.fireworks['white']) + Style.RESET_ALL,
              end='  ')
        print(Style.BRIGHT + Fore.GREEN +
              'green:{}'.format(self.fireworks['green']) + Style.RESET_ALL,
              end='  ')
        print(Style.BRIGHT + Fore.BLUE +
              'blue:{}'.format(self.fireworks['blue']) + Style.RESET_ALL)

    def print_observed_hands(self, player_number):
        print("Hands:")
        for p in self.players:
            print("  Player #{}: ".format(p.player_number), end='')
            if p.player_number == self.current_player:
                print(list(
                    map(lambda x: x != None,
                        self.player_hands[player_number])),
                      end='')
            else:
                for c in self.player_hands[p.player_number]:
                    if c != None:
                        color_tag = self.get_color_tag(c[0])
                        print(color_tag + c[0] + " " + str(c[1]) +
                              Style.RESET_ALL,
                              end='  ')
                    else:
                        print("None", end='  ')
            print("")

    def print_hints(self):
        def hint_str(hint):
            if len(hint['cards']) == 1:
                return ("Card {} is {}.".format(hint['cards'],
                                                hint['card_type']))
            else:
                return ("Cards {} are {}.".format(hint['cards'],
                                                  hint['card_type']))

        print("Hints Given:")
        for p, hints in self.hints.items():
            print("  Player #{}: ".format(p), end=' ')
            for h in hints:
                print(hint_str(h), end=' ')
            print("")
Ejemplo n.º 40
0
class Game:
    """
    contains logic for blackjack game
    """
    def __init__(self, cut_index=0, num_players=1):
        self.deck = Deck()
        self.deck.shuffle()
        self.deck.cut(cut_index)
        self.players = [
            Hand(self.deck.draw(), self.deck.draw())
            for i in range(num_players)
        ]
        self.dealer = Dealer(self.deck.draw(), self.deck.draw())

    def play(self):
        """
        play a single blackjack game
        """

        player_finished = [False for i in range(len(self.players))]

        print(self.dealer)

        while not all(player_finished):

            for i, player in enumerate(self.players):
                if player.game_over() or player_finished[i]:
                    print(f'Player {i+1} is finished')
                    player_finished[i] = True
                    continue

                print('-' * 60)
                print(f"Player {i+1}'s turn")
                print('-' * 60)
                print(player)
                print('-' * 60)

                invalid = True
                while invalid:
                    move = input(
                        'Do you want to hit or stay? \n>').strip().lower()
                    if move in ['h', 'hit', 's', 'stay']:
                        invalid = False

                if move.startswith('h'):
                    player.add(self.deck.draw()
                               )  # draw a card and add it to a player's hand
                    print(player)

                if move.startswith('s'):
                    player_finished[i] = True

        print('-' * 60)
        print("Dealer's Turn")
        print('-' * 60)
        while self.dealer.should_hit():
            print('Dealer hits')
            print('-' * 60)
            self.dealer.add(self.deck.draw())
            print(self.dealer)
            print('-' * 60)

            # reveal final hands and results
        print('-' * 60)
        print(f"Dealer's Hand")
        print('-' * 60)
        self.dealer.reveal()

        for i, player in enumerate(self.players):
            print('-' * 60)
            print(f"Player {i+1}'s hand")
            print('-' * 60)
            print(player)

            points = player.points()
            dealer_points = self.dealer.points()
            if points == 21:
                print('Blackjack!')
            elif (points > 21) or points <= dealer_points <= 21:
                print('You lose!')
            else:
                print('You win!')
Ejemplo n.º 41
0
class Game:
    """A game of Texas Hold'em."""
    def __init__(self):
        self.players_size = 0
        self.players_list = []
        self.dealer = 0
        self.last_raise = 0
        self.current_player = 0

        self.pot = 0

        self.current_cycle = 0
        self.end_of_first = 0  # To prevent skipping big blind player

        self.min_bet = 0
        self.small_blind_points = 5
        self.big_blind_points = 10
        self.initial_points = 200

        self.deck = None
        self.common_cards = []
        self.evaluator = Evaluator()

        self.done = False  # To be removed after command line testing

    #The game's API consists entirely of the next 4 (possibly 5) methods:
    #add_player, MAYBE remove_player, initialize_game, update_game, and
    #poll_game.
    #add_player is called to put players into the game before starting it.
    #remove_player allows a player to be dropped from the game.
    #initialize_game is called after all players have been added and takes
    #care of everything related to starting the game.
    #update_game is called every time a player ends their turn to update
    #the internal state of the game to reflect that player's actions.
    #poll_game is called by the server's HTML templater for the game room
    #in order to get out the information it needs to deliver each player
    #a version of the room tailored to them.

    def add_player(self, name):
        """Create a new Player object and add it to the game. Return the
        index in self.players_list of the player just created.
        """
        self.players_size += 1
        self.players_list.append(Player(name))
        return self.players_size - 1

    def remove_player(self, index):
        self.players_size -= 1

    def initialize_game(self):
        """When called, we allocate to each player a beginning number of
        points and initialize the first round. The first betting cycle
        then begins implicitly.
        """
        for player in self.players_list:
            player.points = self.initial_points

        #For now the first player to join the lobby is made the dealer.
        self._initialize_round(dealer=0)

    def update_game(self, bet=0, fold=False):
        """Function that updates the internal state of the game whenever
        a player concludes their turn. Takes as an argument the amount of
        the bet (if any) placed by that player and whether or not that
        player folded.
        """

        #EVENTUALLY this function will need to validate the actions just
        #made by the player & prompt them to redo if their actions were
        #invalid.

        #If only one active player remains.
        if self._poll_active_players() == 1:
            self._end_round(
                self._get_next_active_player(self.current_player))

        if self.end_of_first:
            self.end_of_first = False
            if bet == 0:
                self._end_cycle()
                return

        #Otherwise, the player just checked or placed a bet.
        #Need to check for when the player is able to check (as opposed
        #to when they're required to place a bet).
        if not fold:
            if self.players_list[self.current_player].all_in:
                pass
            elif (
                    self.players_list[self.current_player].bet <
                    self.players_list[self._get_previous_active_player(
                    self.current_player)].bet):
                raise ValueError(
                    "Your bet must at least equal the previous player's.")

            self.pot += bet

            if self.players_list[self.current_player].bet > self.players_list[
                    self._get_previous_active_player(self.current_player)].bet:
                self.last_raise = self.current_player
                self.min_bet = self.players_list[self.current_player].bet

        self.current_player = \
            self._get_next_active_player(self.current_player)

        #If we have made it around the table to the last player who
        #raised, and no additional raises have been made, end this
        #betting cycle. An exception is made for the first round of
        #betting, in which case the player who bet the big blind gets
        #an opportunity to raise or check.
        if self.last_raise == self.current_player:
            if (
                self.current_player == self._get_next_player(self.dealer, 2)
                    and self.current_cycle == 0):
                self.end_of_first = True
            else:
                self._end_cycle()

    def poll_game(self, player=None):
        """Return a dictionary containing useful information about the
        state of the game. If a player index is passed in, the dictionary
        includes information about that specific player, which makes this
        function a one-stop shop for users to get information specific to
        the game from their perspective.
        """
        info = {
            'dealer': self.dealer,
            'small_blind': self._get_next_player(self.dealer),
            'big_blind': self._get_next_player(self.dealer, 2),
            'pot': self.pot,
        }

        community = []

        for card in self.common_cards:
            community.append([card.value, card.suit, card.string])

        info.update({'community': community})

        players = []

        if player is not None:
            #Loop beginning with the player on this player's left up
            #through the player on their right. Gather information about
            #the other players that this player needs to be able to see
            #on their game screen.
            for other_player in self.players_list[player + 1:] + \
                    self.players_list[:player]:
                players.append([
                    other_player.name,
                    other_player.bet,
                    other_player.points,
                    other_player.active,
                ])

            info.update({
                'turn': True if player == self.current_player else False,
                'dealer': True if player == info['dealer'] else False,
                'small_blind': True if player == info['small_blind'] else False,
                'big_blind': True if player == info['big_blind'] else False,
                'points': self.players_list[player].points,
                'bet': self.players_list[player].bet,
                'active': self.players_list[player].active,
                'name': self.players_list[player].name,
                'players': players,
            })

            hand = []
            for card in self.players_list[player].hand:
                hand.append([card.value, card.suit, card.string])

            info.update({'hand': hand})

        else:
            #If a spectator is making this request, return a minimal amount
            #of information on all players.
            for other_player in self.players_list:
                players.append({
                    'name': other_player.name,
                    'bet': other_player.bet,
                    'points': other_player.points,
                    'active': other_player.active,
                })

            info.update({'players': players})

        return info

    def _initialize_round(self, dealer=None):
        """Assign one player the role of dealer and the next two players
        the roles of small blind and big blind. If the "dealer" argument
        is passed in, the game forces that player to be the dealer.
        Otherwise, it looks at its internal self.dealer and assigns to the
        NEXT player the role of dealer. The small blind and big blind are
        made to place their bets.
        """

        # Initialize a new deck object for each round
        self.deck = Deck()

        #  Remove players without enough $ to play
        for index, player in enumerate(self.players_list):
            if player.points < self.big_blind_points:
                self.remove_player(index)

        #Determine who the dealer, small blind, big blind, and first turn
        #will be for the next round.
        if dealer is not None:
            self.dealer = dealer
        else:
            self.dealer = self._get_next_player(self.dealer)

        small_blind = self._get_next_player(self.dealer)

        big_blind = self._get_next_player(small_blind)
        self.last_raise = big_blind

        self.current_player = self._get_next_player(big_blind)

        #Deal two cards to each player and reset their bets and active
        #status from the last round.
        for player in self.players_list:
            player.bet = 0
            player.active = True
            player.hand = [self.deck.get_card(), self.deck.get_card()]

        #Reset the pot and force the small blind and big blind to place
        #their bets.
        self.pot = 0
        self.pot += self.players_list[small_blind].call(
            self.small_blind_points)
        self.pot += self.players_list[big_blind].call(
            self.big_blind_points)

        self.min_bet = self.big_blind_points
        #Will eventually need to check that these players have enough
        #points to place the bet.

        self.current_cycle = 0
        self.common_cards = []

    def _end_cycle(self):
        """Called when the current betting cycle has concluded. This
        happens when the player whose turn it would currently be was the
        last player to raise. Initializes the next betting cycle or ends
        the round.
        """
        if self.current_cycle >= 3:
            #If this was the last betting cycle.
            self._end_round()

        else:
            if self.current_cycle == 0:
                self.common_cards = [
                    self.deck.get_card(),
                    self.deck.get_card(),
                    self.deck.get_card()
                    ]
            else:
                self.common_cards.append(self.deck.get_card())

            self.current_cycle += 1

            # Sets current player to first active player left of the big blind.
            self.current_player = \
                self._get_next_active_player(
                    self._get_next_player(self.dealer, 2))
            self.last_raise = self.current_player

    def _end_round(self, winner=None):
        """Called when the current round ends - either when all players
        but one fold, or when the last betting cycle is completed. When
        an argument is passed, the round is assumed to have ended because
        all players but the one with the index passed have folded.
        Determines a winner in the showdown (if applicable) and gives the
        pot to the winner.
        """
        # Find and save best hand for active each player, while keeping
        # track of the overall best hand

        best_rank = 7463  # Worst possible actual rank is 7462
        best_string = ''  # i.e. 'Full House' or 'Pair of Eights', etc.
        best_cards = []  # Cards comprising the winning hand.
        Tie = False

        if winner is None:
            for index, player in enumerate(self.players_list):
                if player.active or player.all_in:
                    seven_cards = []
                    seven_cards.extend(self.common_cards)
                    seven_cards.extend(player.hand)
                    rank, string, cards = self.evaluator.get_best(seven_cards)
                    if rank < best_rank:
                        if Tie:
                            Tie = False
                        winner = index
                        winners_tie = [winner]
                        best_rank = rank
                        best_string = string
                        best_cards = cards
                    elif rank == best_rank:
                        Tie = True
                        winners_tie.append(index)

        if Tie:
            split_pot = self.pot // len(winners_tie)
            for player_index in winners_tie:
                self.players_list[player_index].points += split_pot

        # If the winner was all in, they cannot win more than the pot amount
        # at the time of going all in.
        elif self.players_list[winner].all_in:
            subpot = self._calculate_subpot(self.players_list[winner].bet)
            self.players_list[winner].points += subpot
            self.pot -= subpot
            self.players_list[winner].all_in = False
            if self.pot > 0:
                self._end_round()  # Find winner of remaining pot

        else:
            self.players_list[winner].points += self.pot

        #  For testing by running from command line.
        self.done = True
        self.best_string = best_string
        self.pot_won = self.pot
        self.winner = self.players_list[winner].name

        self._initialize_round()

    def _poll_active_players(self):
        """Find out how many players are active (haven't folded)."""
        active_players = 0
        for player in self.players_list:
            if player.active:
                active_players += 1

        return active_players

    def _get_next_active_player(self, index):
        """Get the next active player clockwise around the table from
        the player at the index passed in. The index passed in must be a
        valid index.
        """
        count = 0
        index = self._get_next_player(index)
        while not self.players_list[index].active:
            index = self._get_next_player(index)
            count += 1
            if count > self.players_size:
                raise BaseException(
                    "_get_next_active_player is looping infinitely.")

        return index

    def _get_previous_active_player(self, index):
        """Get the next active player counterclockwise around the table
        from the player at the index passed in. The index passed in must
        be a valid index.
        """
        count = 0
        index = self._get_previous_player(index)
        while not self.players_list[index].active:
            index = self._get_previous_player(index)
            count += 1
            if count > self.players_size:
                raise BaseException(
                    "_get_previous_active_player is looping infinitely.")

        return index

    def _get_next_player(self, index, step=1):
        """Get the player step positions to the left of the player at
        the index passed in. The index passed in must be a valid index.
        """
        if index not in range(self.players_size):
            raise IndexError(
                "Index %s passed to _get_next_player is out of range." %
                index)

        return (index + step) % self.players_size

    def _get_previous_player(self, index, step=1):
        """Get the player step positions to the right of the player at
        the index passed in. The index passed in must be a valid index.
        """
        if index not in range(self.players_size):
            raise IndexError(
                "Index %s passed to _get_previous_player is out of range."
                % index)

        index -= step
        while index < 0:
            index += self.players_size
        return index

    def _get_subpot(self, bet):
        subpot = 0
        for player in self.players_list:
            if bet >= player.bet:
                subpot += player.bet
            else:
                subpot += bet
Ejemplo n.º 42
0
from deck import Deck
from sequence_of_functions.player_class import Player
from table import Table

if __name__ == '__main__':
    deck = Deck()
    deck.shuffle()
    players = []
    player_count = int(input('Please enter player count:\n'))
    for i in range(player_count):
        players.append(
            Player(
                input('Please enter the name for player no. ' + str(i + 1) +
                      '\n')))

    table = Table(players=players, deck=deck)
    table.initialize_game()

    while len(table.cards) <= 5:
        table.play_a_round()
Ejemplo n.º 43
0
    class Hand:
        def __init__(self, BlackjackGame):
            self.deck = Deck()
            self.playerHands = [BlackjackHand([self.deck.draw()])]
            self.dealerHand = BlackjackHand([self.deck.draw()])
            self.BlackjackGame = BlackjackGame
            self.amtBet = USA('0.10')
            self.playerHands[0].add(self.deck.draw())
            self.dealerHand.add(self.deck.draw())
            self.playerTurn = True

        def __str__(self):
            temp = ""
            temp += "Dealer's hand:\n"

            if self.playerTurn and self.dealerHand != 21:
                temp += str(self.dealerHand.cards[0]) + '\n'
            else:
                temp += str(self.dealerHand)

            temp += '\n'

            for i in range(len(self.playerHands)):
                if len(self.playerHands) > 1:
                    temp += "Player " + str(i + 1) + '\n'
                temp += "Your hand:\n" + str(self.playerHands[i]) + '\n'
                temp += "Current Value: " + str(self.playerHands[i].getValue())
                temp += " Your bet: " + str(
                    self.amtBet) + "  You have: " + str(
                        self.BlackjackGame.playerMoney)

            return temp

        #returns None if no further moves by player possible. Otherwise, returns the number option
        #of their choice.
        def getPlayerMove(self, playerNum):
            if self.dealerHand.getValue() == 21:
                self.BlackjackGame.playerMoney -= self.amtBet
                print("Dealer blackjack! Hand lost.  Your balance:",
                      self.BlackjackGame.playerMoney)

            elif self.playerHands[playerNum].getValue() == 21:
                self.BlackjackGame.playerMoney += self.amtBet
                print("You got a blackjack! Hand won.  Your balance:",
                      self.BlackjackGame.playerMoney)

            elif self.playerHands[0].getValue() > 21:
                self.BlackjackGame.playerMoney -= self.amtBet
                print("You busted! Hand lost.  Your balance:",
                      self.BlackjackGame.playerMoney)

            else:
                print("What would you like to do?  Your balance: ",
                      self.BlackjackGame.playerMoney)

                hitLocked = self.playerHands[playerNum].getValue() == 20
                splitAvailable = False

                #checking for split availability
                if self.playerHands[playerNum].getValue() % 2 == 0:
                    if self.playerHands[playerNum].cards[0].value < 10:
                        splitAvailable = self.playerHands[playerNum].cards[
                            1].value == self.playerHands[playerNum].cards[
                                0].value
                    else:
                        splitAvailable = self.playerHands[playerNum].cards[
                            1].value >= 10

                #outputting player options
                option = 0
                while option == 0:
                    if hitLocked:
                        print("[-] Hit locked due to hand value")
                    else:
                        print("[1] Hit")
                    print("[2] Stand")
                    if hitLocked:
                        print("[-] Double Down locked due to hand value")
                    else:
                        print("[3] Double Down")
                    if splitAvailable:
                        print("[4] Split")
                    else:
                        print("[-] Split not available")
                    print("[5] Surrender")

                    answer = input()
                    answer = answer.lower()

                    if (answer == '1' or answer == 'h'
                            or answer == 'hit') and not hitLocked:
                        option = 1
                    elif answer == '2' or answer == 'stand':
                        option = 2
                    elif (answer == '3' or answer == 'd' or answer == 'double'
                          or answer == 'double down') and not hitLocked:
                        option = 3
                    elif (answer == '4'
                          or answer == 'split') and splitAvailable:
                        option = 4
                    elif answer == '5' or answer == 'surrender':
                        option = 5

                    if option == 0:
                        print(
                            "Unable to determine answer. Please choose a valid option."
                        )

                return option

        def playerHit(self, playerNum):
            self.playerHands[playerNum].add(self.deck.draw())

        def playerDoubleDown(self, playerNum):
            self.amtBet *= 2
            self.playerHit(playerNum)
Ejemplo n.º 44
0
def build_op_deck():
    return Deck(reduce(lambda x, y: x + y, list(map(lambda x : [x] * ops_dist[x], 
                                                    list(ops_dist.keys())
                                                    ))))
Ejemplo n.º 45
0
class Game:
    def __init__(self):
        self.draw_pile = Main_Deck()
        self.discard_pile = Deck()
        self.foundation_1 = Deck()
        self.foundation_2 = Deck()
        self.foundation_3 = Deck()
        self.foundation_4 = Deck()

        self.deck_1 = Deck()
        self.deck_2 = Deck()
        self.deck_3 = Deck()
        self.deck_4 = Deck()
        self.deck_5 = Deck()
        self.deck_6 = Deck()
        self.deck_7 = Deck()

        self.distribute_cards()

    def distribute_cards(self):
        self.deck_1.add(self.draw_pile.getremove(0).flip())

        self.deck_2.add(self.draw_pile.getremove(0))
        self.deck_2.add(self.draw_pile.getremove(0).flip())

        for i in range(2):
            self.deck_3.add(self.draw_pile.getremove(0))
        self.deck_3.add(self.draw_pile.getremove(0).flip())

        for i in range(3):
            self.deck_4.add(self.draw_pile.getremove(0))
        self.deck_4.add(self.draw_pile.getremove(0).flip())

        for i in range(4):
            self.deck_5.add(self.draw_pile.getremove(0))
        self.deck_5.add(self.draw_pile.getremove(0).flip())

        for i in range(5):
            self.deck_6.add(self.draw_pile.getremove(0))
        self.deck_6.add(self.draw_pile.getremove(0).flip())

        for i in range(6):
            self.deck_7.add(self.draw_pile.getremove(0))
        self.deck_7.add(self.draw_pile.getremove(0).flip())

    def __repr__(self):
        max_len = 0
        for deck in [
                self.deck_1, self.deck_2, self.deck_3, self.deck_4,
                self.deck_5, self.deck_6, self.deck_7
        ]:
            if len(deck) > max_len:
                max_len = len(deck)
        if len(self.discard_pile) == 0:
            discard_1 = '[ Empty ]'
            discard_2 = '[ Empty ]'
            discard_3 = '[ Empty ]'
        elif len(self.discard_pile) == 1:
            discard_1 = f'{str(self.discard_pile.get(-1))}'
            discard_2 = '[ Empty ]'
            discard_3 = '[ Empty ]'
        elif len(self.discard_pile) == 2:
            discard_1 = f'{str(self.discard_pile.get(-1))}'
            discard_2 = f'{str(self.discard_pile.get(-2))}'
            discard_3 = '[ Empty ]'
        else:
            discard_1 = f'{str(self.discard_pile.get(-1))}'
            discard_2 = f'{str(self.discard_pile.get(-2))}'
            discard_3 = f'{str(self.discard_pile.get(-3))}'
        if len(self.foundation_1) == 0:
            found_1 = '[ Empty ]'
        else:
            found_1 = f'{str(self.foundation_1.get(-1))}'
        if len(self.foundation_2) == 0:
            found_2 = '[ Empty ]'
        else:
            found_2 = f'{str(self.foundation_2.get(-1))}'
        if len(self.foundation_3) == 0:
            found_3 = '[ Empty ]'
        else:
            found_3 = f'{str(self.foundation_3.get(-1))}'
        if len(self.foundation_4) == 0:
            found_4 = '[ Empty ]'
        else:
            found_4 = f'{str(self.foundation_4.get(-1))}'
        if len(self.deck_1) == 0:
            d_1 = '[ Empty ]'
        else:
            d_1 = f'{str(self.deck_1.get(0))}'
        if len(self.deck_2) == 0:
            d_2 = '[ Empty ]'
        else:
            d_2 = f'{str(self.deck_2.get(0))}'
        if len(self.deck_3) == 0:
            d_3 = '[ Empty ]'
        else:
            d_3 = f'{str(self.deck_3.get(0))}'
        if len(self.deck_4) == 0:
            d_4 = '[ Empty ]'
        else:
            d_4 = f'{str(self.deck_4.get(0))}'
        if len(self.deck_5) == 0:
            d_5 = '[ Empty ]'
        else:
            d_5 = f'{str(self.deck_5.get(0))}'
        if len(self.deck_6) == 0:
            d_6 = '[ Empty ]'
        else:
            d_6 = f'{str(self.deck_6.get(0))}'
        if len(self.deck_1) == 7:
            d_7 = '[ Empty ]'
        else:
            d_7 = f'{str(self.deck_7.get(1))}'
        line_1 = f'[ Draw  ] {discard_1}           {found_1} {found_2} {found_3} {found_4}'
        line_2 = f'          {discard_2}'
        line_3 = f'          {discard_3}'
        line_4 = f'{d_1} {d_2} {d_3} {d_4} {d_5} {d_6} {d_7}'
        lines_end = []
        for i in range(max_len - 1):
            line = ''
            for j in [
                    self.deck_1, self.deck_2, self.deck_3, self.deck_4,
                    self.deck_5, self.deck_6, self.deck_7
            ]:
                if len(j) >= i + 2:
                    line += f'{str(j.get(i+1))} '
                else:
                    line += '          '
            lines_end.append(line)
        lines = [line_1, line_2, line_3, line_4, *lines_end]
        return '\n'.join(lines)
Ejemplo n.º 46
0
class PicturesApp(App):
    conn = client_connection()
    card_database = card_database_creation()
    card_reader = cv_card_reader()
    table = None
    deck = None

    def check_resize(self, instance, x, y):
        print("resize", x, y)
        self.table.bounding_boxes['hand'].set_box(
            [int(x * 0.5), int(50)],
            [int(x), int(y * 0.2)],
        )
        self.table.bounding_boxes['mana_cards'].set_box(
            [int(0), int(50)], [int(x * 0.5), int(y * 0.2)])
        self.table.bounding_boxes['monsters_cards'].set_box(
            [int(0), int(y * 0.2)], [int(x), int(y * 0.4)])
        self.table.bounding_boxes['attacking_cards'].set_box(
            [int(0), int(y * 0.4)], [int(x), int(y * 0.6)])
        self.current_width = x
        self.current_height = y
        self.table.update_opponent_bounding_boxes()
        self.table.animate_all_cards()
        # self.root.canvas.ask_update()
        self.event_loop = []

    def wrapper_create_card(self, name):
        if not isinstance(name, str): name = name.text
        card_id = self.create_card(name)
        self.table.move_card(card_id, 'hand', [Window.width, Window.height])

    def wrapper_send_message(self, name):
        self.conn.writer_tcp(name.text)

    def wrapper_create_card_from_camera(self, event):
        name = self.card_reader.grab_text()
        card_id = self.create_card(name)
        self.table.move_card(card_id, 'hand', [Window.width, Window.height])

    def create_onepone(self, event=None):
        opo = Picture(source='opo.png')
        self.root.add_widget(opo)

    def create_card(self, name, summon_position=None, assigned_id=None):
        # card = card_creation(self.card_database, name)
        return self.table.create_card(name=name,
                                      summon_position=None,
                                      assigned_id=None)

    def app_func(self):
        async def run_wrapper():
            await self.async_run()
            print('App done')
            self.card_reader.close()
            self.other_task.cancel()

        return asyncio.gather(run_wrapper(), self.client_connection())

    def deck_next_card(self, event):
        if self.deck is None:
            self.deck = Deck()
            for i in self.deck.load_hand():
                self.wrapper_create_card(i)
        else:
            self.wrapper_create_card(self.deck.load_card())

    def build(self):
        self.table = Table(self)
        self.check_resize(None, Window.width, Window.height)
        textinput = TextInput(text='Card Name', multiline=False)
        textinput.bind(on_text_validate=self.wrapper_create_card)
        chatclient = TextInput(text='Chat', multiline=False)
        chatclient.bind(on_text_validate=self.wrapper_send_message)
        button = Button(text='grab card from camera', font_size=14)
        button.bind(on_press=self.wrapper_create_card_from_camera)
        deck = Button(text='grab card from virtual decks', font_size=14)
        deck.bind(on_press=self.deck_next_card)

        layout = BoxLayout(size_hint=(1, None), height=50)
        layout.add_widget(textinput)
        layout.add_widget(chatclient)
        layout.add_widget(button)
        layout.add_widget(deck)
        self.root.add_widget(layout)

        buttonlayout = FloatLayout(size_hint=(None, None), height=50)
        button_1p1 = Button(text="+1/+1",
                            pos_hint={
                                'center_x': 10,
                                'center_y': 10
                            },
                            size_hint=(None, None))
        button_1p1.bind(on_press=self.create_onepone)
        buttonlayout.add_widget(button_1p1)

        Window.bind(on_resize=self.check_resize)

    async def client_connection(self):
        try:
            await self.conn.establish_connection()
            await asyncio.sleep(1)

            async def connection():
                await asyncio.sleep(1)
                self.conn.writer_tcp('create_a_room mtg mtg')
                await asyncio.sleep(1)
                self.conn.writer_tcp('join_a_room mtg mtg')
                await asyncio.sleep(1)
                self.conn.writer_tcp('username mtg{}'.format(
                    random.getrandbits(10)))
                await asyncio.sleep(1)
                while True:
                    await asyncio.sleep(5)
                    self.table.broadcast_cards()

            async def card_watcher():
                while True:
                    if len(self.event_loop
                           ) > 0 and self.event_loop[0][0] + 0.2 < time.time():
                        # [time.time(), 2, self.parent_object.current_width//2, self.parent_object.current_height//2, self]
                        animation = Animation(pos=(self.event_loop[0][2],
                                                   self.event_loop[0][3]),
                                              t='out_back',
                                              duration=0.25)
                        animation &= Animation(scale=self.event_loop[0][1],
                                               t='in_out_cubic',
                                               duration=0.25)
                        animation.start(self.event_loop[0][-1])
                        self.event_loop.pop(0)
                    await asyncio.sleep(0.1)

            await asyncio.gather(connection(), card_watcher(),
                                 self.conn.reader_tcp(self.incoming_message))

        except asyncio.CancelledError as e:
            pass

    def incoming_message(self, message):
        print(message)
        text = " ".join(message.split(' ')[1:])
        if text.startswith('create_a_card'):
            self.create_card(" ".join(text.split(' ')[1:]))
        if text.startswith('current_cards'):
            self.table.opponent_update(
                message.split(' ')[0][:-1], " ".join(text.split(' ')[1:]))
Ejemplo n.º 47
0
    def test_missing_cards_from_main_deck(self):

        test_collection = Collection(TEST_COLLECTION_NAME)
        self.assertEqual(test_collection.size(), 0)
        test_main_deck = []
        empty_sideboard = []
        CARDS_IN_MAIN_DECK = 25
        ARBITRARY_NUMBER = 5  #must be less than CARDS_IN_MAIN_DECK

        for x in range(0, CARDS_IN_MAIN_DECK):
            quantity = random.randint(1, 4)
            card = Card("card" + str(x), quantity)
            test_main_deck.append(card)

        test_deck = Deck(test_main_deck, empty_sideboard)

        #an empty collection should be missing every card from a maindeck
        cards_missing_from_main_deck = test_collection.missing_cards_from_main_deck(
            test_deck)

        #assert that return list is of equal length to deck
        self.assertEqual(len(cards_missing_from_main_deck), CARDS_IN_MAIN_DECK)
        index = 0
        for card in cards_missing_from_main_deck:
            #assert that return list has a list of cards equivalent to main deck
            self.assertEqual(card.name, test_deck.main_deck[index].name)
            self.assertEqual(card.quantity,
                             test_deck.main_deck[index].quantity)
            index += 1

        #a "full" collection should be missing no card from a maindeck
        for x in range(0, CARDS_IN_MAIN_DECK + CARDS_IN_MAIN_DECK):
            quantity = random.randint(4, 10)
            card = Card("card" + str(x), quantity)
            test_collection.add_card(card)

        cards_missing_from_main_deck = test_collection.missing_cards_from_main_deck(
            test_deck)
        self.assertEqual(len(cards_missing_from_main_deck), 0)

        #a "partially full" collection should be missing some cards from a maindeck
        test_collection = Collection(TEST_COLLECTION_NAME)
        self.assertEqual(test_collection.size(), 0)

        for x in range(0, CARDS_IN_MAIN_DECK - ARBITRARY_NUMBER):
            quantity = random.randint(0, 2)
            name = "card" + str(x)
            card = Card.query.filter_by(name=name).first()
            user.add_card_to_collection(card, quantity)
        cards_missing_from_main_deck = test_collection.missing_cards_from_main_deck(
            test_deck)

        index = 0
        for card in test_deck.main_deck:
            if not test_collection.cards.get(card.name):
                self.assertEqual(cards_missing_from_main_deck[index].name,
                                 card.name)
                self.assertEqual(cards_missing_from_main_deck[index].quantity,
                                 card.quantity)
                index += 1
            elif test_collection.cards.get(card.name) < card.quantity:
                self.assertEqual(cards_missing_from_main_deck[index].name,
                                 card.name)
                self.assertEqual(
                    cards_missing_from_main_deck[index].quantity,
                    card.quantity - test_collection.cards.get(card.name))
                index += 1
Ejemplo n.º 48
0
class GameServer(object):
    '''  
    The ERS game server holds the state of a single game at a time. 
    Clients (players) can interact with the server but the server can 
    not interact with the clients. 
    '''

    def __init__(self):
        '''
        Initializes the primary Egyptian Rat Screw objects which 
        hold the state of the game.
        '''
        self.players = defaultdict(lambda:defaultdict(deque))
        self.locked = False
        self.started = False
        self.deck = Deck()
        self.deck.generate_fresh_deck()
        self.deck.shuffle_deck()
        self.total_cards = self.deck.size()
        self.pile = deque()
        self.round = 0
        self.round_history = []
        self.player_list = []
        self.slaps = []
        self.round_result = ""
        self.current_card = ""
        self.winner = ""
        self.current_flipper = ""

    def get_locked_status(self):
        ''' Gets the status of the server and whether it is locked from additional players '''
        return self.locked

    def get_start_status(self):
        ''' Gets the start status of the game '''
        return self.started

    def get_players(self):
        ''' Gets the current players registered with the game server '''
        return self.players.keys()

    def get_round_number(self):
        ''' Gets the current round of the game '''
        return self.round

    def get_round_results(self):
        ''' Gets the results from the last round '''
        return self.round_result

    def get_winner(self):
        ''' Gets the winner of the game, if there is not one it returns an empty string '''
        return self.winner

    def get_round(self):
        ''' Gets the round number, the card flipped in that round, and the player who flipped it '''
        return self.round, self.current_card, self.current_flipper

    def reset_players_status(self):
        ''' Reset ready status of all players to not ready '''
        for player in self.players.keys():
            self.players[player]["ready"] = False   

    def slap_attempt(self, name, timestamp):
        ''' 
        Takes: itself, the name of the player making the slap attempt, the time stamp of said slap attempt
        Returns: None, adds the slap attempt details to list of slap attempts for the current round
        '''
        self.slaps.append((name, timestamp))

    def get_num_cards(self, name):
        ''' 
        Takes: itself, the name of a player in the game 
        Returns: the number of cards the input player currently has 
        '''
        return len(self.players[name]["pile"])

    @Pyro4.expose
    def register_player(self, name):
        ''' 
        Takes: itself, name of player to register in the game
        Returns: None, registers a player for the game 
        '''
        if not self.locked: self.players[name]["ready"] = False

    @Pyro4.expose
    def quit_game(self, name):
        ''' 
        Takes: itself, name of player to be removed from the game
        Returns: None, removes input player from game state
        '''
        self.players.pop(name, None)

    def get_lobby_status(self):
        '''
        Takes: itself 
        Returns: ready status of players in the game lobby 
        '''
        s = "\n\nLobby Status: \n"

        # construct a string of those in the game lobby and their ready status
        for player in self.players.keys():
            if self.players[player]["ready"]: s += player + " is ready \n"
            else: s += player + " is not ready \n"
        return s

    def players_ready(self):
        '''
        Takes: itself
        Returns: boolean True if all players in the game are ready, False otherwise
        '''
        all_ready = True
        for player in self.players.keys():
            if not self.players[player]["ready"]: all_ready = False        
        return True if all_ready else False  

          

    @Pyro4.expose
    def signal_ready(self, name):
        ''' 
        Takes: itself and the unique name of the player who is signaling readiness
        Returns: None, signals that a player is ready for the game state
        '''
        self.players[name]["ready"] = True

        # if everyone in the game agrees to move on to the next round and there are 
        # enough people to play go ahead and move to the next round
        if len(self.players.keys()) > 1 and self.players_ready(): 

            # if we haven't started the game yet we need to lock it, mark it as started,
            # distribute the deck amongst the players, and get a copy of those playing
            if not self.started: 
                self.started, self.locked = True, True
                self.distribute_cards() 
                self.player_list = list(self.players.keys())
            self.next_round()

    def distribute_cards(self):
        '''
        Takes: itself
        Returns: None, distributes the deck of cards among the players in the game state 
        '''
        num_players = len(self.players.keys())

        # distribute cards n at a time where n is the number of players and where |deck| - n > -1
        while not self.deck.will_be_empty(num_players):
            for player in self.players.keys():
                self.players[player]["pile"].append(self.deck.take_top())

    def next_round(self):
        '''
        Takes: itself
        Returns: None, move on to the next round 
        '''
        if self.players_ready():
            # if we are just starting the round, we can move directly to it 
            if self.round == 0: self.new_round()
            else:
                # if all players are ready for a new round, we go ahead and employ their decisions by order of 
                # timestamp and move the game state to the next round 
                self.apply_round_results()
                self.new_round()

    def new_round(self):
        '''
        Takes: itself
        Returns: None, moves the game state to a new round
        '''
        self.reset_players_status()
        self.slaps = []
        self.round += 1
        turn = self.round % len(self.player_list)

        # Since the official game rules state players without anymore cards can still play, remaining players
        # must then accomodate by flipping their cards instead
        if self.players[self.player_list[turn]]["pile"]: card = self.players[self.player_list[turn]]["pile"].pop()
        else:
            next_person = self.round
            while True:
                next_person += 1
                turn = next_person % len(self.player_list)

                # the first player to have a pile will need to flip
                if self.players[self.player_list[turn]]["pile"]: 
                    card = self.players[self.player_list[turn]]["pile"].pop()
                    break

        # add to the pile, round histroy, and basic markers of the current round
        self.round_history.append((self.player_list[turn], card))
        self.current_card = str(card.get_value()) + " of " + str(card.get_suit())
        self.current_flipper = self.player_list[turn]
        self.pile.append(card)

    def is_valid_slap(self):
        '''
        Takes: itself
        Returns: boolean True or False of whether a slap in this round is valid
        '''
        r = self.round
        if not self.pile: return False

        # check if it is a slap on doubles
        if r > 1 and self.round_history[r - 1][1].get_value() == self.round_history[r- 2][1].get_value(): return True

        # check if it is a slap on sandwich
        elif r > 2 and self.round_history[r - 1][1].get_value() == self.round_history[r - 3][1].get_value(): return True

        # check if it is a slap on top bottom
        elif r > 1 and self.round_history[0][1].get_value() == self.round_history[r - 1][1].get_value(): return True

        # check if it is a slap on ascending or descending
        elif r > 3 and self.is_ascending_or_descending(): return True

        # otherwise we have a false slap
        return False
        
    def is_ascending_or_descending(self):
        '''
        Takes: itself
        Returns: boolean True or False for whether the top 4 cards in the main pile are ascending or descending
        '''
        cards = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"]

        # get the top 4 elements in the pile from the round history
        top_card = self.round_history[self.round - 1][1].get_value()
        second_card = self.round_history[self.round - 2][1].get_value()
        third_card = self.round_history[self.round - 3][1].get_value()
        fourth_card = self.round_history[self.round - 4][1].get_value()
        card_list = [fourth_card, third_card, second_card, top_card]
        ascending = True
        descending = True

        # now we simply iterate up the card list and see whether there is an increasing or decreasing pattern 
        for i in range(3):
            if cards.index(card_list[i]) + 1 != cards.index(card_list[i+1]): ascending = False
            if cards.index(card_list[i]) != cards.index(card_list[i+1]) - 1: descending = False
        return ascending or descending

    def apply_round_results(self):
        '''
        Takes: itself
        Returns: None, applies the decisions made by players to the current round 
        '''
        winner = ""
        winning_reason = ""
        losers = []
        result = "\n\n"

        # we first consider and prioritize whether there was a valid slap 
        if self.slaps and self.is_valid_slap(): 
            # if there is a valid slap, we get the player who slapped early to resolution of millisecond
            winner = min(self.slaps, key=lambda x:x[1])[0]
            winning_reason = " for slapping first and correctly!!!"

        # we also want to consider if someone has won the round by simply playing a face or ace card
        elif self.round > 1 and (self.round_history[self.round - 2][1].is_face_or_ace() 
            and not self.round_history[self.round - 1][1].is_face_or_ace()): 
            winner = self.round_history[self.round - 2][0]
            winning_reason = " for being the last to put down a face or ace!!!"

        # otherwise punish anyone that slapped since they slapped incorrectly
        else:
            for slap in self.slaps:
                losers.append(slap[0])
                # remove 0-2 cards from each player, as much as is possible
                if self.players[slap[0]]["pile"]: self.pile.appendleft(self.players[slap[0]]["pile"].pop())
                if self.players[slap[0]]["pile"]: self.pile.appendleft(self.players[slap[0]]["pile"].pop())

        # if there is a winner we give that winner all the cards in the main pile and shuffle the newly merged pile
        if winner:
            self.players[winner]["pile"].extend(self.pile)
            random.shuffle(self.players[winner]["pile"])
            self.pile = deque()
            result += "The winner of this round is " + winner + winning_reason + "\n"

        # otherwise we can see if there were any losers in that round who slapped incorrectly
        else:
            for loser in losers:
                result += loser + " slapped incorrectly and lost 2 cards or whatever was remaining\n"
        self.round_result = result

        # if there is a winner because of this round make note of it in the game state so when the client 
        # next polls the game can end with a winner
        self.check_winner()

    def check_winner(self):
        '''
        Takes: itself
        Returns: None, sets a winner in the game state if there exists a winner
        '''
        for player in self.players.keys():
            if len(self.players[player]["pile"]) == self.total_cards: 
                self.winner = player
Ejemplo n.º 49
0
class Table:
    TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
    # will remove player if he or she hasn't played in time limit
    PLAYER_TURN_LIMIT = 30

    def __init__(self,
                 players=None,
                 deck=None,
                 pot=0,
                 cards=None,
                 tableId=None,
                 blind=2,
                 currentBet=0,
                 statusId=None,
                 winners=None,
                 updateTs=None):
        self.players = players if players is not None else []
        if deck is not None:
            self.deck = deck
        else:
            self.deck = Deck()
            self.deck.shuffle()
        self.pot = pot
        self.cards = cards if cards is not None else []
        self.tableId = tableId if tableId is not None else str(uuid.uuid4())
        self.blind = blind
        self.currentBet = currentBet
        ## Any table change should update the status id this can then be used to determine if there has been a change on the table

        self.statusId = statusId if statusId is not None else 0
        self.winners = winners if winners is not None else []
        self.updateTs = updateTs

    def resetTable(self):
        self.players = []
        self.deck = None
        self.pot = 0
        self.cards = None
        self.blind = 2
        self.currentBet = 0
        self.statusId = 0
        self.winners = None
        self.updateTs = None
        logger.warn(" Table successfully reset values")

    def setDealerAtRandom(self):
        playerIndex = randint(0, len(self.players) - 1)
        logger.debug("Dealer Selected")
        self.setDealerPosition(playerIndex)
        self.statusId = self.statusId + 1

    def setDealerPosition(self, playerIndxForDealer):
        '''
        Set the position of the dealer. Player that is dealer will be in index 0 of the array of players.
        '''
        self.players[playerIndxForDealer].dealer = True
        logger.info(' {0} is dealer.'.format(
            self.players[playerIndxForDealer].name))

        resetPlayers = []
        ### set dealer to index 0
        for index in range(len(self.players)):
            nextPlayer = playerIndxForDealer + index
            if nextPlayer >= len(self.players):
                nextPlayer = nextPlayer - len(self.players)
            player = self.players[nextPlayer]
            player.dealer = playerIndxForDealer == nextPlayer
            resetPlayers.append(player)
            logger.info('player ' + self.players[nextPlayer].name +
                        ' is position ' + str(index))
        self.players = resetPlayers
        self.setBlinds()
        self.statusId = self.statusId + 1

    def dealPlayer(self, playerIndex):
        player = self.players[playerIndex]
        if len(player.hand.cards) >= 2:
            logger.warn(
                ' dealPlayer called for player {0}, id {1}, the request was ignored because player has 2 or more cards'
                .format(player.name, player.playerId))
            return
        card = self.deck.deal()
        logger.info(' {0} received a {1}'.format(player.name, card))
        player.hand.cards.append(card)
        self.statusId = self.statusId + 1

    def dealToTable(self, cardCount):
        for _ in range(cardCount):
            card = self.deck.deal()
            self.cards.append(card)
            logger.info(' Table received a {0}'.format(card))
            logger.info(' Table cards: {0}'.format(self.showHand()))
        self.statusId = self.statusId + 1

    def playerBetOrCall(self, player, chips):
        logger.info('in bet or call recalling...' + str(player) + " " +
                    str(chips) + " ")
        self.playerBetOrCallByIndex(self.players.index(player), chips)

    def playerBetOrCallByIndex(self, playerIndex, chips):
        logger.info('in bet or call')
        player = self.players[playerIndex]
        player.currentBet = player.currentBet + chips
        logger.info(
            ' {0} bets {1} chip(s), for a total of {2} this round'.format(
                player.name, chips, player.currentBet))
        if player.folded:
            logger.warn(
                "Player asked to bet or call, but is folded, bet will not be made"
            )
            return
        logger.info('in bet or call 2')
        player.chips = player.chips - chips
        player.currentAction = PlayerAction.CALL_CHECK_RAISE
        self.pot = self.pot + chips
        self.currentBet = player.currentBet
        logger.info(
            ' Sets table pot to {0} and current call amount for this round to {1}'
            .format(self.pot, self.currentBet))
        self.setNextPlayerTurn(player)
        logger.info('in bet or call done')
        self.statusId = self.statusId + 1

    def playerCheck(self, player):
        self.playerCheckByIndex(self.players.index(player))

    def playerCheckByIndex(self, playerIndex):
        player = self.players[playerIndex]
        logger.info(' {0} checks'.format(player.name))
        if player.currentBet < self.currentBet:
            raise ValueError('Cannot check without meeting the current bet')
        if player.folded:
            logger.warn(player.name +
                        " asked to check, but is folded, bet will not be made")
            return
        player.currentAction = PlayerAction.CALL_CHECK_RAISE
        self.setNextPlayerTurn(player)
        self.statusId = self.statusId + 1

    def setNextPlayerTurn(self, player):
        logger.info("Setting turn for player after {0}".format(player.name))
        for p in self.players:
            p.turn = False
            p.turnStartTime = None

        if self.isRoundComplete():
            pass
        else:
            playerIndex = self.players.index(player)
            nextPlayerIndex = self.getNextPlayerIndex(playerIndex)
            while self.players[nextPlayerIndex].folded:
                nextPlayerIndex = self.getNextPlayerIndex(nextPlayerIndex)
            self.players[nextPlayerIndex].turn = True
            self.players[nextPlayerIndex].turnStartTime = datetime.now(
            ).strftime(self.TIME_FORMAT)
            logger.info("Setting {0}'s turn".format(
                self.players[nextPlayerIndex].name))

    def getNextPlayerIndex(self, playerIndex):
        playerIndex = playerIndex + 1
        if (playerIndex == len(self.players)):
            playerIndex = 0
        return playerIndex

    def playerFold(self, player):
        self.playerFoldByIndex(self.players.index(player))

    def playerFoldByIndex(self, playerIndex):
        player = self.players[playerIndex]
        player.folded = True
        logger.info(
            ' {0} folds, player has a total of {1} chips bet this round'.
            format(player.name, player.currentBet))
        self.setNextPlayerTurn(player)
        self.statusId = self.statusId + 1

    def prepareForNextHand(self):
        '''
        Next dealer, reset pot, shuffle a new deck reset players
        '''
        logger.info("Table is preparing for next hand")
        self.prepareForNextRound()
        self.deck = Deck()
        self.deck.shuffle()
        self.pot = 0
        self.cards = []
        self.winners = []

        indexOfDealer = 0
        for playerIndex, player in enumerate(self.players):
            player.hand.cards = []
            player.folded = False
            player.isInformedHandComplete = False
            if player.dealer:
                indexOfDealer = self.getNextPlayerIndex(playerIndex)

        self.setDealerPosition(indexOfDealer)
        self.statusId = self.statusId + 1

    def prepareForNextRound(self):
        '''
        Reset players for the next round of betting
        '''
        logger.info("Table is preparing for next round")
        for player in (self.players):
            player.currentBet = 0
            player.currentAction = PlayerAction.NONE
        self.currentBet = 0
        self.statusId = self.statusId + 1
        self.setNextPlayerTurn(self.players[0])  # dealer is index 0

    def addPlayer(self, player):
        for existingPlayer in self.players:
            if existingPlayer.playerId == player.playerId:
                #raise ValueError(" Cannot add player to table as player is already at table.")
                return
        if self.isPlayActive():
            player.folded = True
        self.players.append(player)
        self.statusId = self.statusId + 1

    def isRoundComplete(self):
        '''
        Check to see that all bets are completed for the round of betting and players notified of winners
        '''
        for player in self.players:
            if player.currentAction == PlayerAction.NONE and not player.folded:
                return False
            if player.currentAction == PlayerAction.CALL_CHECK_RAISE and player.currentBet < self.currentBet and not player.folded:
                return False
        return True

    def isHandComplete(self):
        if self.isRoundComplete():
            if len(self.cards) == 5:
                return True
            if self.haveAllButOnePlayerFolded():
                return True
            if len(self.players()) <= 1:
                return True
        return False

    def addPlayers(self, players):
        for player in players:
            self.addPlayer(player)

    def removePlayer(self, player):
        if player in self.players:
            if player.dealer:
                indexOfDealer = self.getNextPlayerIndex(
                    self.players.index(player))
                self.setDealerPosition(self.getNextPlayerIndex(indexOfDealer))
            elif player.turn:
                self.setNextPlayerTurn(player)
            self.players.remove(player)
        self.statusId = self.statusId + 1

    def removePlayerById(self, playerId):
        for player in self.players:
            if player.playerId == playerId:
                self.removePlayer(player)

    def setBlinds(self):
        '''
        Set blinds or bets before table cards or betting. 
        Must have dealer set before this is called. Dealer will be index [0]
        '''
        firstBlindIndex = 1
        secondBlindIndex = self.getNextPlayerIndex(1)
        self.playerBetOrCallByIndex(firstBlindIndex, int(self.blind / 2))
        self.playerBetOrCallByIndex(secondBlindIndex, self.blind)
        # since this is blind, give the player a chance to call
        self.players[firstBlindIndex].currentAction = PlayerAction.NONE
        self.players[secondBlindIndex].currentAction = PlayerAction.NONE
        self.setNextPlayerTurn(self.players[secondBlindIndex])
        logger.info(
            ' Blinds set, {0} is low at {1} chip(s) and {2} high with {3} chips '
            .format(self.players[firstBlindIndex].name, int(self.blind / 2),
                    self.players[secondBlindIndex].name, self.blind))

    def dealRound(self):
        numberOfPlayers = len(self.players)
        for playerIndex in range(1, numberOfPlayers + 1):
            if playerIndex >= numberOfPlayers:
                playerIndex = 0
            self.dealPlayer(playerIndex)
        self.statusId = self.statusId + 1

    def doAllPlayersHaveTwoCards(self):
        for player in self.players:
            if len(player.hand.cards) < 2:
                return False
        return True

    def showHand(self):
        myCards = "Table : "
        if len(self.cards) == 0:
            myCards += " No cards"
        else:
            for card in self.cards[:-1]:
                myCards += str(card)
                myCards += ", "
            myCards += str(self.cards[-1])
        return myCards

    def hasDealer(self):
        for player in self.players:
            if player.dealer:
                return True
        return False

    def findPlayerById(self, playerId):
        for player in self.players:
            if playerId == player.playerId:
                return player
        return None

    def isPlayActive(self):
        for player in self.players:
            if len(player.hand.cards) < 0:
                return True
        if self.pot != 0:
            return True
        if len(self.cards) > 0:
            return True
        return False

    def allPlayersKnowHandIsComplete(self):
        for player in self.players:
            if not player.folded and not player.isInformedHandComplete:
                return False

        return True

    def haveAllButOnePlayerFolded(self):
        countOfPlayers = 0
        for player in self.players:
            if not player.folded:
                countOfPlayers = countOfPlayers + 1
            if countOfPlayers > 1:
                return False
        return True
Ejemplo n.º 50
0
 def __init__(self, name="Player"):
     """Sets up the player's draw deck and discard deck. """
     self.name = name
     self.drawPile = Deck()
     self.discardPile = Deck()
Ejemplo n.º 51
0
class Game(object):
	"""Represents an entire game of cribbage between two players. A game consists 
	of as many rounds as needed for one player to exceed the final score of 121.
	"""

	WINNING_SCORE = 121

	def __init__(self):
		super(Game, self).__init__()
		self.deck = Deck()
		self.score = dict.fromkeys(['p1', 'p2'], 0) # Should this be a view?
		self.history = OrderedDict()
		self.winner = True in [self.score[p] >= 121 for p in self.score.keys()]

	def run(self):
		'''Simulate a cribbage game, playing rounds until one player reaches the 
		winning score of 121 points.

		'''
		round_num = 1
		
		while (self.score['p1'] < 121) and (self.score['p2'] < 121):
			
			print('Round: {}'.format(round_num))
			# Play a round
			round = self.round(round_num)
			for p in self.score.keys():
				self.score[p] += round[p]['score']
			self.history[round_num] = round
			round_num += 1
		print(self.winner)

	def round(self, round_num):
		'''Plays a single round of cribbage. Deals two hands, discards to the 
		crib, scores hands (and crib), and update the score for each player.

		TODO:
			Pegging

		'''
		round = {
			'p1': {
				'hand': [], 'score': 0, 'brkdwn': None, 'crib': False
			},
			'p2': {
				'hand': [], 'score': 0, 'brkdwn': None, 'crib': False
			},
			'starter': None
		}

		if round_num % 2 == 0:
			round['p2']['crib'] = True
		else:
			round['p1']['crib'] = True


		# Shuffle deck of cards and deal two hands
		self.deck.shuffle()
		p1_hand, p2_hand, crib = Hand(), Hand(), Hand()
		self.deal(p1_hand, p2_hand)

		# Discard phase...send two cards to crib
		self.the_discard(p1_hand, p2_hand, crib)

		round['p1']['hand'] = p1_hand
		round['p2']['hand'] = p2_hand

		# Cut deck and reveal the starter
		self.deck.cut()
		starter = self.deck[0]
		round['starter'] = starter

		p1_hand.cards.append(starter)
		p2_hand.cards.append(starter)

		# The show
		self.the_play(p1_hand, p2_hand)


		# Save round to game history and update total score
		p1_score = self.score_hand(p1_hand)
		round['p1']['score'] += p1_score[0]
		round['p1']['brkdwn'] = p1_score[1]

		p2_score = self.score_hand(p2_hand)
		round['p2']['score'] += p2_score[0]
		round['p2']['brkdwn'] = p2_score[1]

		for p in ['p1', 'p2']:
			if round[p]['crib'] == True:
				round[p]['score'] += self.score_hand(crib)[0]

		# Return all cards to deck
		for hand in [p1_hand, p2_hand, crib]:
			self.deck.return_hand(hand)

		return round

	def score_hand(self, hand):
		'''Given a Hand(), return a list with the total points score for the 
		hand and a dict containing the breakdown by scoring category:

			score = [num_score, {breakdown}]

		FIFTEENS:	2 pts per combo totalling 15
		PAIRS: 		2 pts per pair of same rank
		RUNS:		1 pt per card in run of 3+
		FLUSH:		4 pts for four of same suit in hand
		HIS NOBS:	1 pt for jack matching suit of starter
		'''
		ev = Evaluator(hand)
		breakdown = {
			'fifteens': 2 * len(ev.fifteens()),
			'pairs': 2 * len(ev.pairs()),
			'runs': sum([len(r) for r in ev.runs()]),
			'flush': 0,
			'nobs': 0
		}

		if ev.flush():
			breakdown['flush'] += 4

		num_score = sum([breakdown[key] for key in breakdown.keys()])
		return [num_score, breakdown]

	def deal(self, p1_hand, p2_hand):
		'''Deal six cards to each hand from the top of the deck, alternating 
		between each player as you would deal cards in real life.'''
		for i in range(1,13):
			if i % 2 == 0:
				p1_hand.add(self.deck.draw())
			else:
				p2_hand.add(self.deck.draw())
		return

	def the_discard(self, p1_hand, p2_hand, crib):
		'''Each player looks at his six cards and discards two of them to the 
		crib. Choose the two cards that result in the highest score for the 
		remaining four cards.
		
		TODO:
		  >>Adjust discard strategy according to which player is currently the 
			dealer (has the crib).
		  >>Weight and apply various discard strategies.
		'''

		for hand in [p1_hand, p2_hand]:
			ev = Evaluator(hand)

			discard_results = []
			# check each 2 card combination
			for combo in itertools.combinations(hand.cards, 2):
				test_hand = Hand()
				test_hand.cards = [card for card in hand.cards if card not in combo]
				result = [ev.score()[0], combo]
				discard_results.append(result)
			
			discard_results.sort(key = lambda x: x[0], reverse = True)
			
			for card in discard_results[0][1]:
				index = hand.cards.index(card)
				crib.add(hand.cards.pop(index))

		return

	def the_play(self, p1_hand, p2_hand):
		'''The non-dealer (aka "pone") shows a card to begin the play and the 
		dealer follows accordingly. The goal is to achieve running totals of 15 
		and 31. 

		If a player is unable to add a card without exceeding 31, he says "go" 
		and his opponent "pegs" 1 point.

		** This requires that information about who is currently the dealer gets 
		passed into the function

		'''
		play_score = [0, 0]

		ranks = sorted(p1_hand.ranks()), sorted(p2_hand.ranks())

		# run until there are no cards in either hand
		total = 0
		while len(ranks[0]) > 0 or len(ranks[1]) > 0:
			for i in ranks:
				if len(i) > 0:
					if ranks.index(i) == 0:
						print('Player 1 Cards: {}'.format(i))
					else:
						print('Player 2 Cards: {}'.format(i))
					
					if total + i[0] <= 31:
						# Check each card against the total. If equals 15 or 31,
						# choose that card
						total += i[0]
						print(i[0])
						print('Total: {}'.format(total))
						del i[0]

						if total == 15:
							play_score[ranks.index(i)] += 2
							print('Fifteen for two.')
						elif total == 31:
							print('Total: {}'.format(total))
							print('Thirty-one for two.')

					else:
						
						total = 0	
		print(play_score)
		return

	def the_show(self):
		'''Game phase where each player scores their five cards (hand + starter)  
Ejemplo n.º 52
0
class Player:
    """Represents a player in a card game. When the player
    draws cards, she will draw from her draw deck. When the draw deck runs
    out, the discard pile will be shuffled into the draw deck. 
    When the player takes cards, they will go into the discard deck."""
    def __init__(self, name="Player"):
        """Sets up the player's draw deck and discard deck. """
        self.name = name
        self.drawPile = Deck()
        self.discardPile = Deck()

    def has_any_cards(self):
        """returns True if the player has any cards in either the draw or 
        the discard deck. Otherwise returns False."""
        return not (self.drawPile.empty() or self.discardPile.empty())

    def take_card(self, card):
        "Adds the card to the discard deck"
        self.discardPile.add(card)

    def take_deck(self, deck):
        "Adds the deck to the discard pile"
        self.discardPile.add_deck(deck)

    def draw_card(self):
        """Draws (and returns) a card from the draw pile if possible. If not, 
        shuffles the discard pile into the draw pile. If there are still no
        cards, returns None."""
        if self.drawPile.empty():
            self.shuffle_in_discard_pile()
            if self.drawPile.empty():
                return None
        return self.drawPile.draw()

    def shuffle_discard_deck_into_draw_deck(self):
        """Adds the discard deck to the draw deck and then shuffles the draw
        deck. No return value"""
        self.drawPile.add_deck(self.discardPile)
        self.drawPile.shuffle()
Ejemplo n.º 53
0
 def __init__(self, hand = Deck()) -> None:
     self.hand = hand
     self.playing = True
     self.score = [0,0]
     self.player = 'Player'
Ejemplo n.º 54
0
class Game:
    def __init__(self):
        """
        __init__(): show the rules and initialize the game settings
        """
        # Show the logo during setup
        settings.mainscreen.bkgd(' ', curses.color_pair(1))
        settings.scoreboard.addstr(0, 0, settings.buildLogo())
        settings.scoreboard.refresh()

        # Show the instuctions
        settings.mainscreen.addstr(
            1, 2,
            '🏌  The objective is to get the lowest score over all rounds.')
        settings.mainscreen.addstr(
            3, 2,
            '🏌  Each player starts each round with 6 face-down cards, and flips over 2'
        )
        settings.mainscreen.addstr(4, 2, '   during their first turn.')
        settings.mainscreen.addstr(
            6, 2,
            '🏌  During each turn, players draw a card from the discard or stock stack. This card '
        )
        settings.mainscreen.addstr(
            7, 2,
            '   can either be swapped with one of the six from the player’s hand or discarded.'
        )
        settings.mainscreen.addstr(
            9, 2, '🏌  The round ends when one player’s cards are all face up.')
        settings.mainscreen.addstr(
            11, 2,
            '🏌  The game ends when all rounds are over or [ctrl-c] is pressed')
        settings.mainscreen.addstr(
            13, 2,
            '┌───────┬────────┬───────────────────┬────────────┬───────┐')
        settings.mainscreen.addstr(
            14, 2,
            '│ A = 1 │ 2 = -2 │ 3-10 = Face Value │ Q & J = 10 │ K = 0 │')
        settings.mainscreen.addstr(
            15, 2,
            '└───────┴────────┴───────────────────┴────────────┴───────┘')
        settings.mainscreen.addstr(17, 31, '[ Press any key to begin ]',
                                   curses.color_pair(4))
        start = settings.mainscreen.getch()  # Wait for feedback

        # Initialize number of players
        settings.mainscreen.clear()
        self.numPlayers = -1
        while (self.numPlayers < 2 or self.numPlayers > 4):
            settings.mainscreen.addstr(2, 2,
                                       "How many people are playing? [2-4]: ")
            self.numPlayers = settings.mainscreen.getch() - 48
            if (self.numPlayers < 2 or self.numPlayers > 4):
                settings.mainscreen.addstr(
                    3, 2, "Please enter a number between 2 and 4")

        # Initialize number of rounds
        self.numRounds = -1
        settings.mainscreen.clear()
        while (self.numRounds < 1 or self.numRounds > 9):
            settings.mainscreen.addstr(
                2, 2, "How many rounds would you like to play? [1-9]: ")
            self.numRounds = settings.mainscreen.getch() - 48
            if (self.numRounds < 1 or self.numRounds > 9):
                settings.mainscreen.addstr(
                    3, 2, "Please enter a number between 1 and 9")

        curses.curs_set(0)
        # Hide the cursor

        # Start game from scratch
        self.scores = [0] * self.numPlayers
        self.prevScores = [0] * self.numPlayers
        self.curPlayer = 1
        self.curRound = 0
        self.curTurn = 0
        self.roundFinished = False

        # Prepare the screen for gameplay
        settings.mainscreen.clear()
        # Hide the logo if the terminal is not wide enough to fit it
        if (curses.COLS < 100): settings.scoreboard.clear()

    def buildScoreboard(self):
        """
        buildScoreboard(): Updates the scoreboard on the left of scoreboard screen
        """
        scoreboardText = []
        line = 0

        # Upper Border
        settings.scoreboard.addstr(
            line, 0, ' ┌────────' + ('┬─────' * self.numPlayers) + '┐')
        line += 1

        # Middle Rows
        for i in range(2):
            # Row label
            row = ' │ ' + ('Player │ ' if i == 0 else ' Score │ ')
            # Row content
            for j in range(self.numPlayers):
                row += '{:^3d}'.format(
                    (j + 1) if i == 0 else self.scores[j]) + ' │ '
            # Display row
            settings.scoreboard.addstr(line, 0, row)
            line += 1
            # Middle Border
            settings.scoreboard.addstr(
                line, 0, ' ├────────' + ('┼─────' * self.numPlayers) + '┤')
            line += 1

        # Bottom Border
        settings.scoreboard.addstr(
            line - 1, 0, ' └────────' + ('┴─────' * self.numPlayers) + '┘')

        # Show the scoreboard
        settings.scoreboard.refresh()

    def buildRoundStatus(self):
        """
            buildRoundStatus(): Updates the counter on the right of scoreboard screen
            """
        roundIndicator = [('_', '🏌️‍')[round == self.curRound]
                          for round in range(1, self.numRounds + 1)]
        roundStatus = '│ Round ' + str(
            self.curRound) + ': ' + ' '.join(roundIndicator) + ' │'
        playerStatus = ' P' + str(self.curPlayer) + '\'s turn!'
        boxWidth = len(roundStatus)
        x = curses.COLS - boxWidth - 1

        settings.scoreboard.addstr(0, x, '┌' + ('─' * (boxWidth - 3)) + '┐')
        settings.scoreboard.addstr(1, x, roundStatus)
        settings.scoreboard.addstr(2, x, '│' + (' ' * (boxWidth - 3)) + '│')
        settings.scoreboard.addstr(
            3, x, '│' + playerStatus + (' ' * (boxWidth - 14)) + '│')
        settings.scoreboard.addstr(4, x, '└' + ('─' * (boxWidth - 3)) + '┘')
        settings.scoreboard.refresh()

    def showHand(self):
        """
        showHand(): display the current players hand, as well as discard and draw piles
        """
        # Show the deck and discard pile
        if (len(self.deck.cards) > 0):
            settings.displayCard(1, 48, self.deck.cards[-1], "[7] Draw")
        if (len(self.discard.cards) > 0):
            settings.displayCard(1, 62, self.discard.cards[-1], "[8] Discard")

        # Print the Player's Hand
        i = 0
        for row in range(2):
            for col in range(3):
                settings.displayCard((row * 9) + 1, (col * 14) + 1,
                                     self.hands[self.curPlayer - 1].cards[i],
                                     '[' + str(i + 1) + ']')
                i += 1

    def calculateScores(self):
        """
        calculateScores(): updated the self.scores for the current player
        """
        # For the current  player
        playerHand = self.hands[self.curPlayer - 1]

        # The current tally for this round, which will change every turn.
        # Therefore it is not cemented until the end of the round
        curScore = 0

        # Matching columns count as 0 points
        for col in range(3):
            topCard = playerHand.cards[col]
            bottomCard = playerHand.cards[col + 3]

            if ((topCard.faceUp and bottomCard.faceUp)
                    and (topCard.value == bottomCard.value)):
                continue
            else:
                for card in [topCard, bottomCard]:
                    if (card.faceUp):
                        if (card.value == 2):
                            curScore -= 2
                        elif (card.value == 11 or card.value == 12):
                            curScore += 10
                        elif (card.value != 13):
                            curScore += card.value

        # Update current total score, including previous rounds
        self.scores[self.curPlayer -
                    1] = curScore + self.prevScores[self.curPlayer - 1]

        self.buildScoreboard()

    def takeTurn(self):
        """
        TakeTurn(): One player takes a turn in a round

        There are three turn behaviors: first turn, normal turn, and last turn
        """
        # Update the Screen
        settings.mainscreen.clear()
        self.buildRoundStatus()
        self.showHand()

        # Print the current player
        settings.mainscreen.addstr(11, 48,
                                   'Player ' + str(self.curPlayer) + ':',
                                   curses.color_pair(2))

        # Check if this is the player's first turn
        if (self.curTurn < self.numPlayers):
            settings.mainscreen.addstr(12, 48, 'This is your first turn!',
                                       curses.color_pair(2))
            settings.mainscreen.addstr(14, 48, 'Choose two cards [1-6]',
                                       curses.color_pair(2))
            settings.mainscreen.addstr(15, 48, 'to flip over.',
                                       curses.color_pair(2))
            settings.mainscreen.refresh()
            # Let the player decide which 2 cards to flip
            for i in range(2):
                move = -1
                validInput = False
                while not validInput:
                    move = settings.mainscreen.getch() - 48
                    curses.flushinp()
                    if (move < 1 or move > 6):
                        settings.mainscreen.addstr(17, 48, 'Press [1-6]',
                                                   curses.color_pair(4))
                    else:
                        if not (self.hands[self.curPlayer -
                                           1].cards[move - 1].faceUp):
                            self.hands[self.curPlayer - 1].cards[move -
                                                                 1].flipUp()
                            validInput = True
                self.showHand()
        # Take a normal turn
        else:
            settings.mainscreen.addstr(13, 48, 'Draw from pile',
                                       curses.color_pair(2))
            settings.mainscreen.addstr(14, 48, '[7] or [8]',
                                       curses.color_pair(2))
            # Warn the player if it is their last turn
            if (self.roundFinished):
                settings.mainscreen.addstr(16, 48, 'You have one last turn',
                                           curses.color_pair(4))
                settings.mainscreen.addstr(17, 48,
                                           'before your cards are flipped!',
                                           curses.color_pair(4))
            settings.mainscreen.refresh()

            # Let the player decide where to draw from
            drawFrom = None
            validInput = False
            while not validInput:
                drawFrom = settings.mainscreen.getch() - 48
                curses.flushinp()
                if (drawFrom == 7):
                    # Draw top card of draw pile
                    self.deck.cards[-1].flipUp()
                    self.showHand()
                    settings.mainscreen.addstr(9, 48, '[7]',
                                               curses.color_pair(4))
                    validInput = True
                elif (drawFrom == 8):
                    # Draw top card of discard pile
                    settings.mainscreen.addstr(9, 62, '[8]',
                                               curses.color_pair(4))
                    validInput = True
                else:
                    # Invalid Input
                    settings.mainscreen.addstr(17, 48, 'Press [7] or [8]',
                                               curses.color_pair(4))

            # Let the player decide where to place the drawn card
            settings.mainscreen.addstr(11, 48,
                                       'Player ' + str(self.curPlayer) + ':',
                                       curses.color_pair(2))
            settings.mainscreen.addstr(13, 48, 'Swap with a card [1-6]',
                                       curses.color_pair(2))
            settings.mainscreen.addstr(14, 48, 'or choose discard [8]',
                                       curses.color_pair(2))
            putCard = None
            validInput = False
            while not validInput:
                putCard = settings.mainscreen.getch() - 48
                curses.flushinp()
                if (putCard == 8):
                    # Put the card in the discard pile
                    if (drawFrom == 7):
                        # Move from Drawn to Discard
                        drawnCard = self.deck.cards.pop()
                        self.discard.addCard(drawnCard)
                    # Otherwise leave in discard
                    validInput = True
                elif (putCard >= 1 and putCard <= 6):
                    # Swap with card [putCard-1]
                    toDiscard = self.hands[self.curPlayer -
                                           1].cards.pop(putCard - 1)
                    toDiscard.flipUp()
                    if (drawFrom == 7):
                        # Draw top card of draw pile
                        drawnCard = self.deck.cards.pop()
                    else:
                        # Draw top card of discard
                        drawnCard = self.discard.cards.pop()
                    # Perform the swap
                    self.hands[self.curPlayer - 1].cards.insert(
                        putCard - 1, drawnCard)
                    self.discard.addCard(toDiscard)
                    validInput = True
                else:
                    # Invalid Input
                    settings.mainscreen.addstr(17, 48, 'Invalid input',
                                               curses.color_pair(4))

            if (self.roundFinished):
                # Flip up remaining cards if round is finished
                for card in self.hands[self.curPlayer - 1].cards:
                    if not (card.faceUp): card.flipUp()

        # Calculate scores
        self.showHand()
        self.calculateScores()

        # Give players a chance to see their hand on the last round
        if (self.roundFinished): time.sleep(1)

        # Increment the turn counter
        time.sleep(1)
        self.curTurn += 1

        # Move to the next player
        self.curPlayer += 1
        if (self.curPlayer > self.numPlayers):
            self.curPlayer = 1

    def playGolf(self):
        """
        playGolf(): play a full game of golf
        """
        self.buildScoreboard()

        # For each round
        for round in range(self.numRounds):
            self.roundFinished = False  # Flag for when all cards are flipped
            self.prevScores = self.scores.copy(
            )  # Update based on final scores of previous round
            self.curRound = round + 1  # Label of current round
            self.curTurn = 0  # The turn within the round

            # Initialize a full deck
            self.deck = Deck()
            self.deck.fillDeck()
            self.deck.shuffle()

            # Deal each player 6 cards
            self.hands = []
            for i in range(self.numPlayers):
                curHand = Deck()
                for c in range(6):
                    curHand.addCard(self.deck.drawCard())
                self.hands.append(curHand)

            # Add one card from draw pile to the discard pile
            self.discard = Deck()
            self.discard.addCard(self.deck.drawCard())
            self.discard.cards[0].flipUp()

            # Each player can take turns moving
            # Until one player has all 6 cards face up
            while not self.roundFinished:

                # One player takes a turn
                self.takeTurn()

                # End the round if the previous player has flipped all their cards
                numFaceUp = len([
                    c for c in self.hands[self.curPlayer - 2].cards if c.faceUp
                ])
                if (numFaceUp == 6):
                    self.roundFinished = True
                    # Let each player play one more turn
                    for p in range(self.numPlayers - 1):
                        self.takeTurn()

            # Announce the winner of the round
            settings.mainscreen.clear()
            roundScores = [
                self.scores[i] - self.prevScores[i]
                for i in range(len(self.scores))
            ]
            # Check for ties
            if (len(roundScores) != len(set(roundScores))):
                winner = 'There was a tie in'
            else:
                winnerId = roundScores.index(min(roundScores)) + 1
                winner = 'Player ' + str(winnerId) + ' is the winner of'
            settings.mainscreen.addstr(2, 0, winner.center(curses.COLS - 1))
            settings.mainscreen.addstr(3, 0, ('Round #' + str(self.curRound) +
                                              ' of').center(curses.COLS - 1))
            settings.mainscreen.addstr(5, 0, settings.buildLogo())
            settings.mainscreen.addstr(17, 31, '[ Press any key to continue ]',
                                       curses.color_pair(4))
            settings.mainscreen.refresh()
            start = settings.mainscreen.getch()  # Wait for feeback

        # Announce the winner of the game
        settings.mainscreen.clear()
        # Check for ties
        if (len(self.scores) != len(set(self.scores))):
            winner = 'There was a tie for this game of'
        else:
            winner = 'Player ' + str(self.scores.index(min(self.scores)) +
                                     1) + ' is the winner of'
        settings.mainscreen.addstr(2, 0, winner.center(curses.COLS - 1))
        settings.mainscreen.addstr(5, 0, settings.buildLogo())
        settings.mainscreen.addstr(17, 31, '[ Press any key to continue ]',
                                   curses.color_pair(1))
        settings.mainscreen.bkgd(' ', curses.color_pair(4))
        settings.mainscreen.refresh()
        start = settings.mainscreen.getch()  # Wait for feeback

        # Clean for next game
        settings.mainscreen.clear()
Ejemplo n.º 55
0
import random

from deck import Deck
from functions_for_algorythm import MiniMax, choose_strategy, get_points
from player import Player
import time

deck = Deck()
deck.deck_shuffle()

player1 = Player("player 1", hand=deck.draw(10), turn=True)
player2 = Player("player 2", hand=deck.draw(10))
player3 = Player("player 3", hand=deck.draw(10))
player4 = Player("player 4", hand=deck.draw(10))
player5 = Player("player 5", hand=deck.draw(10))

minimax = MiniMax(deck, [player1, player2, player3, player4, player5])

choose_strategy(player1)
choose_strategy(player2)
choose_strategy(player3)
choose_strategy(player4)
choose_strategy(player5)

player1.hand.sort()
player2.hand.sort()
player3.hand.sort()
player4.hand.sort()
player5.hand.sort()

for player in minimax.players:
Ejemplo n.º 56
0
    def playGolf(self):
        """
        playGolf(): play a full game of golf
        """
        self.buildScoreboard()

        # For each round
        for round in range(self.numRounds):
            self.roundFinished = False  # Flag for when all cards are flipped
            self.prevScores = self.scores.copy(
            )  # Update based on final scores of previous round
            self.curRound = round + 1  # Label of current round
            self.curTurn = 0  # The turn within the round

            # Initialize a full deck
            self.deck = Deck()
            self.deck.fillDeck()
            self.deck.shuffle()

            # Deal each player 6 cards
            self.hands = []
            for i in range(self.numPlayers):
                curHand = Deck()
                for c in range(6):
                    curHand.addCard(self.deck.drawCard())
                self.hands.append(curHand)

            # Add one card from draw pile to the discard pile
            self.discard = Deck()
            self.discard.addCard(self.deck.drawCard())
            self.discard.cards[0].flipUp()

            # Each player can take turns moving
            # Until one player has all 6 cards face up
            while not self.roundFinished:

                # One player takes a turn
                self.takeTurn()

                # End the round if the previous player has flipped all their cards
                numFaceUp = len([
                    c for c in self.hands[self.curPlayer - 2].cards if c.faceUp
                ])
                if (numFaceUp == 6):
                    self.roundFinished = True
                    # Let each player play one more turn
                    for p in range(self.numPlayers - 1):
                        self.takeTurn()

            # Announce the winner of the round
            settings.mainscreen.clear()
            roundScores = [
                self.scores[i] - self.prevScores[i]
                for i in range(len(self.scores))
            ]
            # Check for ties
            if (len(roundScores) != len(set(roundScores))):
                winner = 'There was a tie in'
            else:
                winnerId = roundScores.index(min(roundScores)) + 1
                winner = 'Player ' + str(winnerId) + ' is the winner of'
            settings.mainscreen.addstr(2, 0, winner.center(curses.COLS - 1))
            settings.mainscreen.addstr(3, 0, ('Round #' + str(self.curRound) +
                                              ' of').center(curses.COLS - 1))
            settings.mainscreen.addstr(5, 0, settings.buildLogo())
            settings.mainscreen.addstr(17, 31, '[ Press any key to continue ]',
                                       curses.color_pair(4))
            settings.mainscreen.refresh()
            start = settings.mainscreen.getch()  # Wait for feeback

        # Announce the winner of the game
        settings.mainscreen.clear()
        # Check for ties
        if (len(self.scores) != len(set(self.scores))):
            winner = 'There was a tie for this game of'
        else:
            winner = 'Player ' + str(self.scores.index(min(self.scores)) +
                                     1) + ' is the winner of'
        settings.mainscreen.addstr(2, 0, winner.center(curses.COLS - 1))
        settings.mainscreen.addstr(5, 0, settings.buildLogo())
        settings.mainscreen.addstr(17, 31, '[ Press any key to continue ]',
                                   curses.color_pair(1))
        settings.mainscreen.bkgd(' ', curses.color_pair(4))
        settings.mainscreen.refresh()
        start = settings.mainscreen.getch()  # Wait for feeback

        # Clean for next game
        settings.mainscreen.clear()
Ejemplo n.º 57
0
class War:
    def __init__(self, num_players=2):

        self.num_players = num_players

        self.hands = [Hand for _ in range(num_players)]
        self.deck = Deck()

    def deal_cards(self):
        # Distributes the cards from the deck to the player
        self.deck.shuffle()
        hands = [[] for _ in range(self.num_players)]
        i = 0
        # If 52 isn't divisible by num_players, then we will have extra cards
        while (len(self.deck) != 0):
            player = i % self.num_players
            hands[player] += self.deck.draw_card()
            i += 1

        # Creates hand objects with the list of cards in them
        for i in range(self.num_players):
            self.hands[i] = Hand(hands[i])

    def round_winner(self):
        ''' Checks to see which player is winner and grants them cards '''
        # Keeps check of the values of the cards played.
        played_cards = []
        for i in range(self.num_players):
            if self.hands[i].is_empty():
                self.refill_hand(i)
            played_cards += self.hands[i].play_cards()

        # need to do this so I can keep track of index
        highest_card = played_cards[0].value
        winner = 0
        winners = [0]
        for i in range(1, self.num_players):
            # ensures that there is a high card
            if highest_card < played_cards[i].value:
                highest_card = played_cards[i]
                # Want the first index of the list to be the winner
                winner = i
                winners[0] = i
            if highest_card == played_cards[i].value:
                # Will pass a list into war so that we can have war with all winners
                winners.append(i)
        # if the highest card is tied, go to war
        # goes into this when it shouldn't trying to figure it out
        if (len(winners) > 1):
            winner = self.round_war(winners)

        self.hands[winner].discard(played_cards)

    def round_war(self, winning_indexes):
        '''Called when values equal each other
           winning_index is a list of the winners for war to initiate
        '''
        # Keeps check of the values of the cards played.
        played_cards = []

        winner = winning_indexes[0]
        winners = [winning_indexes[0]]

        for i in range(len(winning_indexes)):
            if self.hands[winning_indexes[i]].is_empty():
                self.refill_hand(winning_indexes[i])
                played_cards.append(self.hands[winning_indexes[i]].play_cards(
                    len(self.hands[winning_indexes[i]].cards)))
            else:
                played_cards.append(
                    self.hands[winning_indexes[i]].play_cards(4))

        # Checks the last card playeds value
        highest_card = played_cards[0][-1].value

        for i in range(1, len(played_cards)):
            # ensures that there is a high card
            if highest_card < played_cards[i][-1].value:
                highest_card = played_cards[i][-1]
                # Want the first index of the list to be the winner
                winner = winning_indexes[i]
                winners[0] = i
            if highest_card == played_cards[i][-1].value:
                # Will pass a list into war so that we can have war with all winners
                winners.append(i)
        if (len(winners) > 1):
            winner = self.round_war(winners)

        for list_of_cards in played_cards:
            self.hands[winner].discard(list_of_cards)

        return winner

    def check_winner(self):
        ''' Checks to see if there was a winner in the game yet. '''
        winners = [len(c) == len(Deck.fullDeck) for c in self.hands]
        if sum(winners) == 0:
            return -1
        return winners.index(True)

    # Deals with empty hand
    def refill_hand(self, index):
        self.hands[index].shuffle()
        self.hands[index] = Hand(self.hands[index].discarded)
Ejemplo n.º 58
0
class Hand():
    # We are assuming the players are in position to act here
    def __init__(self, players, buttonplayer, smallblind, bigblind):
        self.buttonplayer = buttonplayer
        # Just assuming button player is the first player here
        # So the players list is ordered according to order to act
        self.players = players
        self.active_players_pos = range(0, len(players))
        self.players_to_act_pos = range(0, len(players))
        self.deck = Deck()
        self.smallblind = smallblind
        self.bigblind = bigblind
        self.pot = 0
        self.flop = None
        self.turn = None
        self.river = None
        self.action_when = None
        self.player_to_act_pos = -1
        self.nplayers = len(players)
        self.curbet = 0

    def place_blinds(self):
        self.pot = self.smallblind + self.bigblind
        self.players[0].stack = self.players[0].stack - self.bigblind
        self.players[1].stack = self.players[1].stack - self.smallblind
        self.curbet = self.bigblind

    # Returns the player that is next to act
    def next_to_act(self):
        if self.action_when == None:
            print("Need to deal first")
        else:
            return (self.players[self.player_to_act_pos])

    def do_action(self, someaction, betsize):
        type_of_action = self.action_when
        player_to_act = self.next_to_act()
        player_to_act.do_action_player(someaction, betsize, type_of_action)

        # If this player folds, then remove this player from list of active players
        if someaction == "fold":
            self.active_players_pos.remove(self.player_to_act_pos)

        # If this player calls, then put some money in the pot
        # If there is no current bet, then assume this is a check
        if someaction == "call":
            player_to_act.stack -= self.curbet
            self.pot += self.curbet

        # If this player bets, then work out what the current bet size is
        if someaction == "bet":
            # Check that the bet is as big as the current bet
            if betsize <= self.curbet:
                print(
                    "Betsize needs to be as big as the current bet which is ",
                    self.curbet)
                return ()

            self.curbet = betsize
            player_to_act.stack -= betsize
            self.pot += betsize

        # Let's move the next player to act along
        self.player_to_act_pos = self.find_next_active_pos()

        # If there is only one active player left, then this player wins the pot
        if len(self.active_players_pos) == 1:
            self.players[self.player_to_act_pos].stack += self.pot
            print("Hand is done. Pot size is ", self.pot,
                  " current phase is: ", self.action_when)
            return (1)
        else:
            print("Pot size is ", self.pot, " next player to act ",
                  self.player_to_act_pos)

    # Given the current player to act, find the position in the players list of
    # the next player
    def find_next_active_pos(self):
        next_player_to_act_pos = (self.player_to_act_pos + 1) % self.nplayers
        while (next_player_to_act_pos not in self.active_players_pos):
            next_player_to_act_pos = (next_player_to_act_pos +
                                      1) % self.nplayers
        return (next_player_to_act_pos)

    def deal_players(self):
        # Start of the hand where each player is dealt two cards
        for player in self.players:
            player.holecards = self.deck.deal_two_cards()
        self.action_when = "Preflop"
        # Under the gun position is the next to act in preflop
        self.player_to_act_pos = 2

    def deal_flop(self):
        # Check that all players have either acted or folded preflop
        flop1 = self.deck.deal_one_card()
        flop2 = self.deck.deal_one_card()
        flop3 = self.deck.deal_one_card()
        self.flop = (flop1, flop2, flop3)
        self.action_when = "Postflop"
        self.player_to_act_pos = self.active_players_pos[0]
        self.curbet = 0

    def deal_turn(self):
        # Check that all players have either acted or folded preflop
        turncard = self.deck.deal_one_card()
        self.turn = turncard
        self.action_when = "Turn"
        self.player_to_act_pos = self.active_players_pos[0]
        self.curbet = 0

    def deal_turn(self):
        turncard = self.deck.deal_one_card()
        self.turn = turncard
        self.action_when = "Turn"
        self.player_to_act_pos = self.active_players_pos[0]
        self.curbet = 0

    def deal_river(self):
        rivercard = self.deck.deal_one_card()
        self.river = rivercard
        self.action_when = "River"
        self.player_to_act_pos = self.active_players_pos[0]
        self.curbet = 0
class DeckTests(unittest.TestCase):
    def setUp(self):
        self.deck = Deck()

    def test_init(self):
        """decks should have a cards attribute, which is a list with 52 cards"""
        self.assertTrue(self.deck.cards, list)
        self.assertEqual(len(self.deck.cards), 52)

    def test_repr(self):
        """repr should return string: 'Deck of 52 Cards'"""
        self.assertEqual(repr(self.deck), "Deck of 52 cards.")

    def test_count(self):
        """count should return a count of the number of cards in the Deck"""
        self.assertEqual(self.deck.count(), 52)
        self.deck.cards.pop()
        self.assertEqual(self.deck.count(), 51)

    def test_deal_sufficient_cards(self):
        """_deal should deal the number of cards specified"""
        cards = self.deck._deal(10)
        self.assertEqual(len(cards), 10)    
        self.assertEqual(self.deck.count(), 42)    

    def test_deal_insufficient_cards(self):
        """_deal should deal the number of cards left in the deck, no more"""
        cards = self.deck._deal(100)
        self.assertEqual(len(cards), 52)    
        self.assertEqual(self.deck.count(), 0) 

    def test_deal_no_cards(self):
        """_deal should throw ValueError if the deck is empty'"""
        self.deck._deal(self.deck.count())
        with self.assertRaises(ValueError):
            self.deck._deal(1)

    def test_deal_card(self):
        """deal_card should deal a single card from the deck"""
        card = self.deck.cards[-1]
        dealt_card = self.deck.deal_card()
        self.assertEqual(card, dealt_card)    
        self.assertEqual(self.deck.count(), 51)

    def test_deal_hand(self):
        """deal_hand should deal the number of cards passed into it"""
        cards = self.deck.deal_hand(20)
        self.assertEqual(len(cards), 20)    
        self.assertEqual(self.deck.count(), 32)

    def test_shuffle_full_deck(self):
        """shuffle should shuffle the deck if deck is full"""
        cards = self.deck.cards[:]
        self.deck.shuffle()
        self.assertNotEqual(cards, self.deck.cards)
        self.assertEqual(self.deck.count(), 52)

    def test_shuffle_not_full_deck(self):
        """shuffle should throw ValueError if the deck isn't full"""
        self.deck._deal(1)
        with self.assertRaises(ValueError):
            self.deck.shuffle()
Ejemplo n.º 60
0
__author__ = 'luke'
import random

from deck import Deck
from hand import Hand
from cards import Card
from players import Player

# get shuffeled deck
deck = Deck()

# get Players
luke = Player("luke")
toni = Player("toni")

# deal cards
while len(deck.cards) > 0:
    luke.recive_card(deck.deal_one())
    toni.recive_card(deck.deal_one())

print("lukes cards" + str(luke.deck))
print("deck" + str(deck.cards))

# start playing hands
count = 0
luke_max_cards = 0
pile = []
while (len(toni.deck) > 0) and (count < 2000000) and (len(luke.deck) > 0):
    lukes_card = Card(luke.top_card())
    tonis_card = Card(toni.top_card())
    print(lukes_card.name + " vs " + tonis_card.name)