Question: To Home Page IT 212 -- Project 4 Goal: Implement and test a PokerHand class. Prerequisites: The Card and Deck classes from the Deck Example.

To Home Page

IT 212 -- Project 4

Goal: Implement and test a PokerHand class.

Prerequisites: The Card and Deck classes from the Deck Example.

Deliverables: card.py deck.py test2a.py constants.py pokerhand.py test2b.py test3.py

Poker Hands in Rank Order:

Hand Type Expected Frequency per 10,000 Hands
No Pair 5,012
One Pair 4,225
Two Pairs 475
Three of a Kind 211
Straight 39.2
Flush 19.6
Full House 14.4
Four of a Kind 2.4
Straight Flush 0.14

Details:

Here are the UML diagrams for the Card, Deck, and PokerHand classes. Only the methods used in this project are included in the Card and Deck diagrams.

In the card.py module, add __lt__ and __eq__ methods to the existing Card class. See the SortPersonArray Example to see how to do this. The Card instance methods __lt__ and __eq__ should return self.rank < other.rank, and self.rank == other.rank, respectively.

Optional: add a __repr__ method to the Card class so that the output of print(cards_array) is something like this:

[2H, KS, 10D] 

See the SortPersonArray Example.

In the test2a.py file, write unit tests to test the __lt__ and __eq__ methods in Item 2.

Use a copy the module constants.py, which contains constants for the PokerHand class.

Implement a PokerHand class in the pokerhand.py module that inherits from the base class Deck. Use these import statements at the top of the pokerhand.py module:

from card import Card from deck import Deck from constants import * 

Define an __init__ method with the header

def __init__(self, the_array): 

that (i) initializes the _cards instance variable to [ ], (ii) appends each Card object in the_array to the _cards array, (iii) initializes the instance variable hand_type to UNCLASSIFIED.Implement the instance method classify, which determines the hand type of the PokerHand object. This source code contains the complete source code to check for a hand of type FOUR_OF_A_KIND and hints for completing the other hand types:

def classify(self): self._cards.sort( ) if # ... code to classify hand of type STRAIGHT_FLUSH: elif self._cards[0] == self._cards[1] and \ self._cards[1] == self._cards[2] and \ self._cards[2] == self._cards[3]: self.hand_type = FOUR_OF_A_KIND elif self._cards[1] == self._cards[2] and \ self._cards[2] == self._cards[3] and \ self._cards[3] == self._cards[4]: self.hand_type = FOUR_OF_A_KIND elif # ... code to classify hand of type FULL_HOUSE: elif # ... code to classify hand of type FLUSH: elif # ... code to classify hand of type STRAIGHT: elif # ... code to classify hand of type THREE_OF_A_KIND: elif # ... code to classify hand of type TWO_PAIR: elif # ... code to classify hand of type ONE_PAIR: else: self.hand_type = NO_PAIR 

Note: self._cards.sort( ) works because you added the __lt__ method to the card class.

In the test2b.py test file, write unit tests to test your PokerHand class. See the additional hints below for some sample source code.

In the test3.py file, create a new array like this:

counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 

This counts array will keep track of how many poker hands of each type are obtained. In the test3.py file, repeat the following 2,000 times:

Create a new deck object.

Shuffle the deck object.

Deal out five poker hands. Use an array to hold the five PokerHand objects.

Classify the five poker hands by calling the PokerHand#classify method for each hand.

Update the counts array like this:

for ph in poker_hands counts[ph.hand_type] += 1 end 

Compare your results to the expected values shown in the Poker Hands in Rank Order section. Here is some pseudocode that you can translate. Recall that if you want the range to be the values 0, 1, 2, 3, 4, you need to use range(0, 5). 0 is the starting point and 5 is the length of the range.

import constants module Create array named counts, initialized to [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] repeat 2,000 times: Create a new Deck object. Call it deck. Shuffle the deck object. Create an an empty array like this: poker_hands = [ ] repeat 5 times: Create an empty array called arr. repeat 5 times: Deal a card from deck and append it to arr. end Create a new PokerHand object ph using the cards in arr and append ph to poker_hands. end end for each ph in the poker_hands array: invoke the classify method of ph. end for each ph in the poker_hands array: counts[ph.hand_type] += 1 end end Print out the number of occurances of each hand type. 

Here is an example of the beginning of the output printing the number of occurances of each hand type:

print("Number of Occurrences of each Hand Type") print("=======================================") print(f"Straight Flush: {counts[STRAIGHT_FLUSH]}") print(f"Four of a Kind: {counts[FOUR_OF_A_KIND]}") ... 

Grading Breakdown: Modified Card.py: 5%; test2a.py: 5%; PokerHand.py: 35%; test2b.py: 15%; test3.py: 10%; Comments: 10%, Indentation: 10%; Submitted Properly (header with name, project number, and submission date, files named properly): 10%.

Additional Suggestions, Hints, and Observations

In the PokerHand classify method, the first thing that you do is sort the hand. This is important to simplify the classification because it insures that all four of a kinds, all three of a kinds, and all pairs are adjacent before you start comparing cards in the if..elif statements.

When checking for FOUR_OF_A_KIND, only three comparisons that are needed:

elif self._cards[0] == self._cards[1] and \ self._cards[1] == self._cards[2] and \ self._cards[2] == self._cards[3] 

This if this if statement is true, then these other equalities are also automatically true by the transitive property:

self._cards[0] == self._cards[2] self._cards[0] == self._cards[3] self._cards[1] == self._cards[3] 

The transitive property of equality says that if a == b and b == c, then automatically a == c. When you look at the two cases for classifying a hand that is a FOUR_OF_A_KIND, there are two cases:

rank of four of a kind < rank of kicker card,

rank of four of a kind > rank of kicker card,

Therefore, two cases are needed for classifying a FOUR_OF_A_KIND in the PokerHand classify method.Similarly there are two different cases for classifying a FULL_HOUSE hand:

rank of three of a kind < rank of pair,

rank of three of a kind > rank of pair,

Therefore, two cases are needed for classifying a FULL_HOUSE in the PokerHand classify method

For classifying TWO_PAIR, there are three cases. The kicker can be greater than both pairs, it can be between the pairs, or it can be less than both pairs.

For classifying ONE_PAIR, there are four cases. Here is an example that shows all of these cases:

# Pair is at indices 0 and 1 4S 4H 5D 7C JS # Pair is at indices 1 and 2 2D 4S 4H 5D JS # Pair is at indices 2 and 3 2S 3H 7D 7C JS # Pair is at indices 3 and 4 2S 4H 5D JC JS 

The else case of the if..elif statements is for NO_PAIR; this is because you have checked all other possibilities and the only remaining possibility is NO_PAIR.

Use these import statements for the test2a.py and test2b.py unit test files:

from card import Card from pokerhand import PokerHand from constants import * import unittest 

Here are some assertEqual statements to check whether your statements to check for FOUR_OF_A_KIND are working:

# Case where four of a kind < kicker. arr = [ Card(9, "C"), Card(9, "S"), Card(9, "H"), Card(9, "D"), Card(11, "S") ] ph = PokerHand(arr) ph.classify( ) self.assertEqual(ph.hand_type, FOUR_OF_A_KIND) # Case where four of a kind > kicker. arr = [ Card(3, "S"), Card(13, "C"), Card(13, "S"), Card(13, "H"), Card(13, "D") ] ph = PokerHand(arr) ph.classify( ) self.assertEqual(ph.hand_type, FOUR_OF_A_KIND) 

This table shows how many assertEqual statements are needed in test2b.py for each card type:

Card Type Number of assert_equal Statements Needed
FOUR_OF_A_KIND 2
FULL_HOUSE 2
THREE_OF_A_KIND 3
TWO_PAIRS 3
ONE_PAIR 4
NO_PAIR 1

http://facweb.cdm.depaul.edu/sjost/it212/projects/proj4.htm

More information is available in the ablove mentioned URL.

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!