In: Computer Science
Write a C++ program that reads five (or more) cards from the user, then analyzes the cards and prints out the category of hand that they represent.
Poker hands are categorized according to the following labels: Straight flush, four of a kind, full house, straight, flush, three of a kind, two pairs, pair, high card.
To simplify the program we will ignore card suits, and face cards. The values that the user inputs will be integer values from 2 to 9. When your program runs it should start by collecting five integer values from the user and placing the integers into an array that has 5 elements. It might look like this:
Enter five numeric cards, no face cards. Use 2 - 9. Card 1: 8 Card 2: 7 Card 3: 8 Card 4: 2 Card 5: 3
(This is a pair, since there are two eights)
No input validation is required for this assignment. You can assume that the user will always enter valid data (numbers between 2 and 9).
Since we are ignoring card suits there won't be any flushes. Your program should be able to recognize the following hand categories, listed from least valuable to most valuable:
| Hand Type | Description | Example |
| High Card | There are no matching cards, and the hand is not a straight | 2, 5, 3, 8, 7 |
| Pair | Two of the cards are identical | 2, 5, 3, 5, 7 |
| Two Pair | Two different pairs | 2, 5, 3, 5, 3 |
| Three of a kind | Three matching cards | 5, 5, 3, 5, 7 |
| Straight | 5 consecutive cards | 3, 5, 6, 4, 7 |
| Full House | A pair and three of a kind | 5, 7, 5, 7, 7 |
| Four of a kind | Four matching cards | 2, 5, 5, 5, 5 |
(A note on straights: a hand is a straight regardless of the order. So the values 3, 4, 5, 6, 7 represent a straight, but so do the values 7, 4, 5, 6, 3).
Your program should read in five values and then print out the appropriate hand type. If a hand matches more than one description, the program should print out the most valuable hand type.
Here are three sample runs of the program:
Enter five numeric cards, no face cards. Use 2 - 9. Card 1: 8 Card 2: 7 Card 3: 8 Card 4: 2 Card 5: 7 Two Pair!
Enter five numeric cards, no face cards. Use 2 - 9. Card 1: 8 Card 2: 7 Card 3: 4 Card 4: 6 Card 5: 5 Straight!
Enter five numeric cards, no face cards. Use 2 - 9. Card 1: 9 Card 2: 2 Card 3: 3 Card 4: 4 Card 5: 5 High Card!
Additional Requirements
1) You must write a function for each hand type. Each function must accept a const int array that contains five integers, each representing one of the 5 cards in the hand, and must return "true" if the hand contains the cards indicated by the name of the function, "false" if it does not. The functions should have the following signatures.
bool containsPair(const int hand[]) bool containsTwoPair(const int hand[]) bool containsThreeOfaKind(const int hand[]) bool containsStraight(const int hand[]) bool containsFullHouse(const int hand[]) bool containsFourOfaKind(const int hand[])
Note that there are some interesting questions regarding what some of these should return if the hand contains the target hand-type and also contains a higher hand-type. For example, should containsPair() return true for the hand [2, 2, 2, 3, 4]? Should it return true for [2, 2, 3, 3, 4]? [2, 2, 3, 3, 3]? I will leave these decisions up to you.
2) Of course, as a matter of good practice, you should use a constant to represent the number of cards in the hand, and everything in your code should still work if the number of cards in the hand is changed to 4 or 6 or 11 (for example). Writing your code so that it does not easily generalize to more than 5 cards allows you to avoid the objectives of this assignment (such as traversing an array using a loop). If you do this, you will receive a 0 on the assignment.
3) You do not need to write a containsHighCard function. All hands contain a highest card. If you determine that a particular hand is not one of the better hand types, then you know that it is a High Card hand.
4) Do not sort the cards in the hand. Also, do not make a copy of the hand and then sort that.
5) An important objective of this assignment is to have you practice creating excellent decomposition. Don't worry about efficiency on this assignment. Focus on excellent decomposition, which results in readable code.This is one of those programs where you can rush and get it done but end up with code that is really difficult to read, debug, modify, and re-use. If you think about it hard, you can think of really helpful ways in which to combine the tasks that the various functions are performing. 5 extra credit points on this assignment will be awarded based on the following criteria: no function may have nested loops in it. If you need nested loops, the inner loop must be turned into a separate function, hopefully in a way that makes sense and so that the separate function is general enough to be re-used by the other functions. Also, no function other than main() may have more than 5 lines of code. (This is counting declarations, but not counting the function header, blank lines, or lines that have only a curly brace on them.) In my solution I was able to create just 3 helper functions, 2 of which are used repeatedly by the various functions.
These additional criteria are intended as an extra challenge and may be difficult for many of you. If you can't figure it out, give it your best shot, but don't be too discouraged. It's just 5 points. And be sure to study the posted solution carefully.
Suggestions
Test these functions independently. Once you are sure that they all work, the program logic for the complete program will be fairly straightforward.
Here is code that tests a containsPair function:
int main() {
int hand[] = {2, 5, 3, 2, 9};
if (containsPair(hand)) {
cout << "contains a pair" << endl;
}
}
Here is the code:
#include<iostream>
using namespace std;
bool containsPair(const int hand[]);
bool containsTwoPair(const int hand[]);
bool containsThreeOfaKind(const int hand[]);
bool containsStraight(const int hand[]);
bool containsFullHouse(const int hand[]);
bool containsFourOfaKind(const int hand[]);
int howManyPresent(const int hand[], int card);
#define NO_OF_CARDS 5
int main()
{
int hand[NO_OF_CARDS], num=1;
while(true)
{
cout<<"Enter "<< NO_OF_CARDS << " numeric cards,
no face cards. Use 2 - 9"<<endl;
for(int i=0;i<NO_OF_CARDS;i++){
cout << "Card "<< i+1 << ": ";
cin >>hand[i];
}
if(containsFullHouse(hand)) {
cout<<"Contains Full House!";
} else if(containsFourOfaKind(hand)) {
cout<<"Contains four of a kind!";
} else if(containsThreeOfaKind(hand)) {
cout<<"Contains three of a kind!";
} else if(containsTwoPair(hand)){
cout<<"Contains two Pair!";
} else if(containsPair(hand)) {
cout<<"Contains a Pair!";
} else if(containsStraight(hand)) {
cout<<"contains Straight!";
} else {
cout<<"contains High Card!";
}
cout<<"\nEnter 0 to exit: ";
cin>>num;
if(num == 0)
break;
}
}
// Find how many same card are present in hand
int howManyPresent(const int hand[], int card){
int cnt = 0;
for(int i=0;i<NO_OF_CARDS;i++){
if(hand[i]==card)
cnt++;
}
return cnt;
}
// function to check Two of the cards are identical
bool containsPair(const int hand[])
{
for(int i=0;i<NO_OF_CARDS;i++) {
if (howManyPresent(hand, hand[i]) == 2)
return true;
}
return false;
}
// check if Two different pairs are present
bool containsTwoPair(const int hand[])
{
int pair1 = -1;
int pair2 = -1;
for(int i=0;i<NO_OF_CARDS;i++) {
if (howManyPresent(hand, hand[i]) == 2) {
if(pair1 == -1 ){
pair1 = hand[i]; // set it to pair1
}else if(pair1 != hand[i] && pair2 == -1 ){
pair2 = hand[i]; // set it to pair2
}
}
}
if(pair1 != -1 && pair2 != -1)
return true;
return false;
}
// check if Three matching cards present
bool containsThreeOfaKind(const int hand[])
{
for(int i=0;i<NO_OF_CARDS;i++) {
if (howManyPresent(hand, hand[i]) == 3)
return true;
}
return false;
}
// check if all cards are consecutive
bool containsStraight(const int hand[])
{
// if all consecutive cards are in increasing order by 1, it is
Straight
// if all consecutive cards are in decreasing order by -1, it is
Straight
int diff = 0;
for(int i=0;i<NO_OF_CARDS-1;i++) {
// Find the difference between first two elements
if(diff == 0) {// if diff is not set yet
diff = hand[i+1]-hand[i]; // set the diff only once
// for consecutive cards diff should be 1 or -1
if(abs(diff) != 1){
return false;
}
}
// if two consecutive card not in same order return false
if((hand[i+1]-hand[i]) != diff) {
return false;
}
}
return true;
}
// check if a pair and three of a kind
bool containsFullHouse(const int hand[])
{
bool three_flag = false;
bool two_flag = false;
for(int i=0;i<NO_OF_CARDS;i++) {
if (howManyPresent(hand, hand[i]) == 2) {
two_flag = true;
}else if (howManyPresent(hand, hand[i]) == 3) {
three_flag = true;
}
}
if(two_flag && three_flag)
return true;
return false;
}
// check if four matching cards present
bool containsFourOfaKind(const int hand[])
{
for(int i=0;i<NO_OF_CARDS;i++) {
if (howManyPresent(hand, hand[i]) == 4)
return true;
}
return false;
}
Sample output:

// Another version without #define constant
#include<iostream>
#include <array>
using namespace std;
bool containsPair(const int hand[]);
bool containsTwoPair(const int hand[]);
bool containsThreeOfaKind(const int hand[]);
bool containsStraight(const int hand[]);
bool containsFullHouse(const int hand[]);
bool containsFourOfaKind(const int hand[]);
int howManyPresent(const int hand[], int card);
int main()
{
// variable defines number of cards in hand
int no_of_cords = 5;
int hand[no_of_cords];
char cont;
// Run the game in repeat mode till user enters '0' to exist.
while(true)
{
cout<<"Enter "<< no_of_cords << " numeric cards,
no face cards. Use 2 - 9"<<endl;
// Store the card's value in the nad array.
for(int i=0;i<no_of_cords;i++){
cout << "Card "<< i+1 << ": ";
// store the entered card at index i of hand array
cin >>hand[i];
}
//Check the cards in hand and find the type.
if(containsFullHouse(hand)) {
cout<<"Contains Full House!";
} else if(containsFourOfaKind(hand)) {
cout<<"Contains four of a kind!";
} else if(containsThreeOfaKind(hand)) {
cout<<"Contains three of a kind!";
} else if(containsTwoPair(hand)){
cout<<"Contains two Pair!";
} else if(containsPair(hand)) {
cout<<"Contains a Pair!";
} else if(containsStraight(hand)) {
cout<<"contains Straight!";
} else {
cout<<"contains High Card!";
}
// Ask user if he wants to exit
cout<<"\nEnter any key to continue (0 to exit): ";
cin>>cont;
// If user enters 0, exit
if(cont == '0')
break;
}
}
// Find how many same card are present in hand
int howManyPresent(const int hand[], int card){
int no_of_cards = 5;
int cnt = 0;
for(int i=0;i<no_of_cards;i++){
if(hand[i]==card)
cnt++;
}
return cnt;
}
// function to check Two of the cards are identical
bool containsPair(const int hand[])
{
int no_of_cards = 5;
for(int i=0;i<no_of_cards;i++) {
if (howManyPresent(hand, hand[i]) == 2)
return true;
}
return false;
}
// check if Two different pairs are present
bool containsTwoPair(const int hand[])
{
int pair1 = -1;
int pair2 = -1;
int no_of_cards = 5;
for(int i=0;i<no_of_cards;i++) {
if (howManyPresent(hand, hand[i]) == 2) {
if(pair1 == -1 ){
pair1 = hand[i]; // set it to pair1
}else if(pair1 != hand[i] && pair2 == -1 ){
pair2 = hand[i]; // set it to pair2
}
}
}
if(pair1 != -1 && pair2 != -1)
return true;
return false;
}
// check if Three matching cards present
bool containsThreeOfaKind(const int hand[])
{
int no_of_cards = 5;
for(int i=0;i<no_of_cards;i++) {
if (howManyPresent(hand, hand[i]) == 3)
return true;
}
return false;
}
int getMinimum(const int hand[]) {
int no_of_cards = 5;
int min = 10;
for(int i=0;i<no_of_cards;i++) {
if(hand[i] < min)
min = hand[i];
}
return min;
}
int getMaximum(const int hand[]) {
int no_of_cards = 5;
int max = 0;
for(int i=0;i<no_of_cards;i++) {
if(hand[i] > max)
max = hand[i];
}
return max;
}
// check if all cards are consecutive
bool containsStraight(const int hand[])
{
int no_of_cards = 5;
int min = getMinimum(hand);
int max = getMaximum(hand);
for(int i=0;i<no_of_cards;i++) {
if (howManyPresent(hand, hand[i]) != 1) // each card should be
unique
return false;
}
// if the cards are consecutive max-min will be no_of_cards -
1
if((max - min) == (no_of_cards - 1)) {
return true;
}
return false;
}
// check if a pair and three of a kind
bool containsFullHouse(const int hand[])
{
int no_of_cards = 5;
bool three_flag = false;
bool two_flag = false;
for(int i=0;i<no_of_cards;i++) {
if (howManyPresent(hand, hand[i]) == 2) {
two_flag = true;
}else if (howManyPresent(hand, hand[i]) == 3) {
three_flag = true;
}
}
if(two_flag && three_flag)
return true;
return false;
}
// check if four matching cards present
bool containsFourOfaKind(const int hand[])
{
int no_of_cards = 5;
for(int i=0;i<no_of_cards;i++) {
if (howManyPresent(hand, hand[i]) == 4)
return true;
}
return false;
}