CSI2372A – Fall 2020
In this project, you are asked to program a card game in C++ language. The game is played with a deck of
cards with comical illustrations of eight different types of beans (some more scarce than others), which
two players place cards in chains, trade the cards and sell the chains in order to raise money.
The player obtains cards of all different types randomly from the deck, and so must engage in trade with
the other player to be successful.
The cards have 8 different faces corresponding to different types of Beans (see Table below). The goal of
the game is to chain-up the cards of same bean to gain coins. The player with the most coins at the end
wins. The chains for the cards are formed by each player for all to see and there are a maximum of either
two or three chains at any point per player. Each chain can only be formed with a single type of Bean.
Each player is dealt a hand of five cards to start and the remaining cards form a draw deck. The rule is
that cards in a player’s hand need to be kept sorted. Cards will be placed on a discard pile during the
Cards in the hand are kept hidden. Cards in trading areas and chains are visible to all players. The discard
pile is face up, but only the top card is visible.
The game proceeds with the players taking turns. During their turn, each player does the following:
1. If the other player has left cards in the trade area from the previous turn (in Step 5), the player
may add these cards to his/her chains or discard them.
2. The player then plays the topmost card from his/her hand. The card must be added to a chain with
the same beans. If the player has currently no such chain on the table, an old chain on the table
will have to be tied and sold, and a new chain must be started. If the chain has not reached a
sufficient length, a player may receive 0 coins.
3. The player has the option to repeat Step 2.
4. Then, the player has the option of discarding one arbitrary card (in any order) from his/her hand
on the discard pile face up.
5. The player draws three cards from the draw deck and places them in the trade area. Next, the
player draws cards from the discard pile as long as the card matches one of the beans in the trade
area. Once the top card does not match or the pile is empty, the player can either chain the cards
or leave them in the trade area for the next player. As in Step 2, if the player has currently no such
chain matching the bean of the card, an old chain on the table will have to be tied and sold, and
then a new chain is started.
6. The turn ends with the player drawing always two cards from the deck and placing them at the
back of his/her hand.
Whenever a player ties a chain and sells it (Steps 2,3 or 5), the player receives coins in trade for the chain.
A player can purchase the right to form a third chain for three coins. No more than three chains can be
formed simultaneously by a player during the game.
The game ends when the deck becomes empty.
Each component of the game is represented by its corresponding class:
Card, Deck, DiscardPile, Chain, Table, TradeArea, Coins, Hand,
The classes Deck, DiscardPile, Hand and Chain are all containers holding cards.
– Deck will initially hold all the cards which will have to be shuffled to produce a randomized
order, then players’ hands are dealt and during game play players draw cards from the Deck.
There is no insertion into the Deck. Deck can therefore usefully extend a std::vector.
– DiscardPile must support insertion and removal but not at random locations but all at the
end. Again a std::vector will work fine but here we can use simple aggregation.
– Hand is well mapped by a queue since players have to keep their hand in order and the first card
drawn is the first card played. The only derivation form this pattern is if players discard a card
from the middle in Step 4 in the above description of a player’s turn. Therefore, we can use a
std::list to remove at an arbitrary location efficiently with a std::queue adapter.
– Chain is also a container and will have to grow and shrink as the game progresses. Again
insertion is only to one end of the chain and a std::vector is fine (see below).
A template class will have to created for Chain being parametric in the type of card. In this
project, we will instantiate Chain for the corresponding bean card.
– Card will be an abstract base class and the eight different bean cards will be derived from it
(inheritance). All containers will hold cards through the base type. However, standard containers
do not work well with polymorphic types because they hold copies (slicing will occur).
– TradeArea class will have to hold cards openly and support random access insertion and
– CardFactory will generate all cards, and so, we will explore the factory pattern. A factory
ensures that there is only a single unit in the program that is responsible to create and delete
cards. Other parts of the program will only use pointers to access the cards. Note that means, we
will delete the copy constructor and assignment operator in Card.
You will be using:
– exceptions: with downcasts to distinguish between different bean cards, and also of
IllegalType if a player attempts to place a card illegally into a chain (a chain that holds
– standard algorithms: such as std::shuffle at the beginning to ensure the cards in the deck
are in a random order.
– stream insertion and extraction operator to save and reload the game from file (for pause