1.1 Basic Game Flow
In this will write programs to emulate the flow of a new type of card game called CCC (CityU Card Combat), which is played among two players. The game starts with a deck of 50 unique cards, which is shuffled thoroughly. In each turn, 5 cards are dealt alternately to each player. With the 5 cards, each player constructs a hand of cards according to the categories listed in session 1.3. The player with a better hand of cards scores 1 point in this turn. After a single turn, the 10 dealt cards are discarded. The same process is then repeated at most 4 more times until there is no unused card left in the deck, or until either player scored 3 marks. The player with higher total score is the winner of the game.
1.2 CCC Cards
Each Card is marked with a digit in range [0..9] and shaded by one of the colors as in the zones of the CityU building: {red, yellow, blue, green, purple}. (The fact that they put blue (instead of green) as the neighbor of yellow is one of the seven greatest mysteries in CityU…). Each Number Card exists only once and holds a unique card rank (there’s never a tie). When comparing the ranks of two cards, the card with the larger digit is considered as having a higher rank (9876543210). Only if the two cards are having the same digit, we consider the color
(redyellowbluegreenpurple).
1.3 Card Hands
With 5 CCC Cards, a player can construct one of the predefined card hands. There is a total of 10 card ranks as listed below (in the order of descending rank):
Legend: [R: Red][Y: Yellow][B: Blue][G: Green][P: Purple]
Rank Name
Criteria
Examples
Straight Flush
l Only 1 color in hand
l 5 sequential digits
R1 R2 R3 R4 R5
Five Of A Kind
l All cards with the same digit
R4 Y4 B4 G4 P4
Four Of A Kind
l 4 cards with the same digit
G0
R4 Y4 B4 G4
Rainbow
l 5 unique colors in hand
R1 Y3 B4 G7 P9
Flush
l Only 1 color in hand
R1 R3 R4 R7 R9
Straight
l 5 sequential digits
R1 Y2 Y3 G4 G5
Three Of A Kind
l 3 cards with the same digit
R1 Y1 B1
G6 G7
Two Pair
l 2 cards with the same digit
l Another 2 cards with the same digit
R1 Y1 B2 B3 G3
One Pair
l 2 cards with the same digit
B0
R1 Y1
G2 B4
High Card
l None of the above
B0 R1 G2 B4 Y7
When building card hands, we consider only the highest rank achievable. For instance, [R4 Y4 B4 G4 P4], despite having 5 colors, is regarded as “Five Of A Kind” rather than “Rainbow” (as the former is in higher rank).
For hands requiring sequential digits (“Straight”, “Straight Flush”), a special rule applies: The digit 0 can optionally be considered as 10. Therefore The hand {6,7,8,9,0} is also considered as sequential. Do note that 1 is not considered as 11, therefore {7,8,9,0,1} is NOT sequential.
When the players compare their hands of cards, the player with a higher rank is the winner of that turn. Only when the two players have the same rank, we’ll break tie with the highest card in hand. For instance, when player A holds [B6 G7 Y8 Y9 R0] and player B holds [B3 Y4 Y5 G6 R7], both hands are considered as “Straight”. We then compare the highest card of player A (Y9) against the highest card of player B (R7), the winner in that turn is player A.
(Note: Although R0 is used as 10 for building “Straight”, we still consider it as 0 when we break tie).
2. Class construction
Students need to create at least 3 classes, with properties and methods as shown below.
(Students may create extra constructors, properties and methods if needed)
2.1 Card class
Private Properties:
Description
char color
Single character for the card color
[R: Red][Y: Yellow][B: Blue][G: Green][P: Purple]
char digit
Single character for the card digit
Range: [‘0’..’9’],
Public Methods:
Description
Card(c,d)
Constructor setting the color and digit respectively
bool greater (Card)
Input: another Card object
Output: Boolean
true if the rank of current card is greater than the input card, false otherwise
2.2 Hand class
Private Properties:
Description
Card cards
An array of 5 Card objects
int length
Number of cards in hand (constructor set default to 0)
Private Methods:
Description
bool isRainbow()
Whether the Hand could form a “Rainbow” hand. (Note: the function just checks whether it is possible, the final result may turn out to be something else like “Five Of a Kind”.) Return false if there’re less than 5 cards.
bool isFlush()
Whether the Hand could form a “Flush” hand. Also return false if there’re less than 5 cards.
bool isStraight()
Whether the Hand could form a “Straight” hand. Also return false if there’re less than 5 cards.
bool isTwoPair()
Whether the Hand could form a “Two Pair” hand. Also return false if there’re less than 5 cards.
int getMaxDup()
Return the maximum count of duplicate digits in hand. (e.g. 3 for three-of-a-kind) Note: For multiple-duplicates (e.g. “Two Pair”), return the maximum count (2 for Two Pair)
Public Methods:
Description
void discard()
Make the hand empty (0 cards)
bool take(Card)
Input: A Card object
The method appends the input Card to the private cards array if there’re less than 5 cards. length member is updated accordingly.
Output: Boolean
true if the Card is appended successfully, false if there’re already 5 cards.
bool greater(Hand)
Input: two Hand objects Output: Boolean
true if the current hand is greater than that of the input hand object (as described in session 1.3)
false is returned if the current hand is not greater, or if either hand has less than 5 cards.
char* getRankName()
Return the name of rank formed by the 5 cards as described in session 1.3. Return NULL if there are less than 5 cards.
Card getHighCard()
Return (not remove!) the single Card object with the highest rank. (you may assume there’s at least 1 card when called)
2.3 Deck class
Private Properties:
Description
Card cards
An array of 50 Card objects
int length
Number of cards in Deck
Public Methods:
Description
Deck()
Constructor automatically fills the cards array with 50 cards, in the order (starting from position [0]): Red 0..9, Yellow 0..9, Blue 0..9, Green 0..9, Purple 0..9.
void refresh()
Dispose the remaining cards in Deck and refill the Deck with 50 cards as in the constructor
Card deal()
Remove the Card with the highest array index from the deck. (you may assume that the deck is non-empty when being called). The length member should be updated accordingly.
void swap(int s, int e)
If 0≤S,E<length, swap the card at index s with the card at index e. For example, in deck
[R0 R1 R2 R3...], swap(1,3) will result in [R0 R3 R2 R1…]
3. Program construction
Students need to prepare two C++ programs for Part A and B respectively, subjected to the following requirements:
3.1 Part A
In Part A, you need to write a program to classify hands. The input is consisted of multiple test cases, one at a line. The first line of input is the number of test cases follow. Each line contains 5 unique cards, each represented by the two-character code as in session 1.3 (case sensitive). Spaces may appear on a line (e.g. between cards), but never between the two characters of the card code. For each input line, your program should print out, on a single line, the name of the highest achievable rank as listed in session
1.3 (case sensitive).
Sample Input
Sample Output
3
R1 R2 R3 R4 R5
R5 B1 B2 Y5 P5
B1 Y2 Y3 Y4 Y5
Straight Flush
Three Of A Kind
Straight
3.2 Part B
In Part B, you need to write a program to emulate a game with a full deck. The program first reads an integer (N≥1) from keyboard, which represents the number of games to play. Each game begins with an unshuffled deck of 50 cards (as in the constructor mentioned in session 2.3). For each game, the program reads an integer (H≥0), which represents the number of swap operations required. The program then reads H pairs of integer (S,E) from the keyboard and pass the pair to Deck::swap() function mentioned in session 2.3. After swap, cards are deal alternatively (with Deck::deal()) to the players. Dealing of cards always starts from Player A and ends when each player holds 5 cards in their hands. For each turn, display the cards of each player (as in the deal order), together with the name of the hands on a line of its own (see below for detail output format). Also generate a line with the accumulated score of the current game so far, followed by a blank line. The game then continues until the final winner is confirmed (i.e. either player scored 3 marks). Finally print a single line with the name of the winner, followed by a blank line.
Sample Input
Sample Output (for easy observation, empty lines are
highlighted
here)
1
1
48 49
PlayerA: [P8 P7 P5 P3 P1] is Flush PlayerB: [P9 P6 P4 P2 P0] is Flush
PlayerB won in this turn (PlayerA:0 PlayerB:1)
PlayerA: [G9 G7 G5 G3 G1] is Flush PlayerB: [G8 G6 G4 G2 G0] is Flush
PlayerA won in this turn (PlayerA:1 PlayerB:1)
PlayerA: [B9 B7 B5 B3 B1] is Flush PlayerB: [B8 B6 B4 B2 B0] is Flush
PlayerA won in this turn (PlayerA:2 PlayerB:1)
PlayerA: [Y9 Y7 Y5 Y3 Y1] is Flush
PlayerB: [Y8 Y6 Y4 Y2 Y0] is Flush
PlayerA won in this turn (PlayerA:3 PlayerB:1)
PlayerA is the final winner!
(Description: The 1 in first line means that there is only ONE game. The 1 in second line means that there’s only one swap operation. 48 49 means swapping