Frequently Asked Questions

ChangeLog

Where will I find answers to the frequently asked questions?
Frequently asked questions will be answered on this page.

Implementation

Can/should we use linked lists?

Yes.

Can we just use a really big array of Cards to store the deck, discard pile, or player hands?

No. There is no limit on how big a deck can be, or how many cards a player can have in their hand, beyond the memory limits of the computer running the code.

Can we make assumptions about what order the cards in a player’s hand are?

No. For example, a player may reorder cards during a turn.

Does our ADT have to handle multiple rounds?

No, the ADT only needs to handle one round (game) .

Can I reuse code from stage1.c and stage2.c in testGame.c?

You can use code available in stage1.c and stage2.c for testGame.c. Make sure that you properly attribute your reuse of the code from stage1.c and stage2.c by clearly providing suitable comments.

Importantly, you need to implement additional test cases that cover all the functions in Game.h and explore as many different program execution pathways as possible.

You will not be awarded marks for the tests already available in stage1.c and stage2.c. We will consider additional coverage. You can use some of the helper functions from stage1.c and stage2.c and quickly write additional tests.

Game End

Does the game end as soon as somebody plays their final card, or do they also need to call END_TURN?

The game ends as soon as they put their final card down; they don’t have to call END_TURN (and can’t, as the game has now ended).

When can the game end with NO_WINNER?

The game ends with no winner when a player attempts to draw a card, but there is no way to draw a card – i.e. there are no cards left in the deck, and the discard pile only has one card in it.

What are the others ways in which the game can end?

These are answered in the Game Rules.

The Deck

What size can the deck be?

It’s valid for the deck to be any size larger than the minimum deck size (which is 30: 7 cards * 4 players = 28 cards, + 1 card flipped to make the discard pile, + 1 card in the deck so that a player can draw).

However, the “full deck” consists of two copies of each card, and since there are 2 of each card * 5 suits * 5 colors * 16 values = 800 cards. In tournament games we may use “full deck” (unless it turns out there’s some reason we need to use fewer cards).

But in terms of writing tests, and later implementing the ADT, it’s valid for the deck to be any size >= 30. (It’s also valid for the deck to be > 800).

Do we need to shuffle the deck?

No, you should deal the cards in the order they were given to you when passed in to the newGame function.

What happens when the deck is empty?

When the deck is empty, the discard pile is “flipped over”, and becomes the deck, except for the top card on the discard pile which stays there.

The last card to be played into the discard pile must always be the card that is on top of the discard pile. This means that when the discard pile is used to form the draw pile, the card on top remains in the discard pile.

What order are the cards in after flipping the discard pile over?

The card that was on the bottom of the discard pile (i.e. the first card that was discarded) is now the top card on the deck.

The deck / discard pile aren’t shuffled at any point.

Valid / Invalid Input

Does the ADT have to deal with invalid input?
What should the ADT return if the input is invalid?

The ADT implementation can assume that the input is valid, and doesn’t have to check for invalid input.

If a test gives an ADT function invalid input, that test is considered incorrect.

Special Cards

What happens if the first card in the discard pile at the start of the game is a special card?
The card will have the effect that it usually had, see the section "Playing the Game" under "Final Card-Down Rules".

Specific ADT Functions

numCards

Will numCards always give 800?
And thus, numOfSuit = 800/5 = 160?
numOfColor = 800/5 = 160?
numOfValue = 800/16 = 50?

No, you can’t assume fixed values. numCards won’t always be 800. It will be however many cards are in the deck that’s provided to the game. So the numbers specified above (numCards giving 800, numOfColor giving 160, etc) won’t be right.

newGame

What is deckSize in the newGame function?

In the newGame function:

Game newGame(int deckSize, value values[], color colors[], suit suits[]);

deckSize is the size of the deck, i.e. the number of cards (and is what numCards should return).

What input does the newGame function take?

When you call newGame, you give it 3 arrays, each that are deckSize big. The deck must contain at least 30 cards.

So if deckSize was 50, you’d give it an array of 50 values, another array of 50 colors, and another array of 50 suits.

The order that these values are in each array gives the cards in the deck, i.e. the first card in the deck has the value values[0], the color colors[0], and the suit suits[0].

In the newGame function, can we assume that the arrays of values, colors and suits we are passed has already been ‘shuffled’?

Yes. The order that the cards are passed in is the order that they should be in the deck, you don’t need to (and shouldn’t) change the ordering.

Is index 0 of the values/colors/suits arrays on the top or bottom of the deck?

Index 0 is the first card on the deck (so it will be dealt immediately to the first player).

If the card values you were passed in were like

colors: { RED,    BLUE,     GREEN,  YELLOW,   PURPLE } 
values: { 3,        4,        5,      6,        7   }
suits:  { HEARTS, DIAMONDS, HEARTS, DIAMONDS, HEARTS}    

the resulting deck will be:

{ RED 3 of HEARTS, BLUE 4 of DIAMONDS, GREEN 5 of HEARTS, YELLOW 6 of DIAMONDS, PURPLE 7 of HEARTS }

and players will get:

Player 1 gets a RED 3 of HEARTS

Player 2 gets a BLUE 4 of DIAMONDS

Player 3 gets a GREEN 5 of HEARTS

Player 4 gets a YELLOW 6 of DIAMONDS

Player 1 gets a PURPLE 7 of HEARTS

(etc for the rest of the cards)

playMove

What values should the unused fields of playerMove have?

If the nextColor field and/or card members of playerMove are not used (because, for example, the action is DRAW_CARD), no value should be assigned to them.

playerPoints

Do the points have to be calculated at any point during the game, or just at the end?

playerPoints could be called at any point during the game, and must return the sum of the values of cards in each player’s hand.

Definitions

round
one full playthrough of the game, from when the game first begins (the cards are dealt, etc) through to when somebody puts their final card down (or the game ends in another way, i.e. through an invalid move or running out of cards)
turn
all of the actions that one player does, starting immediately after the player before them has finished making moves, and ending immediately before the player after them makes any moves.

e.g. if Alice, Bob, Jack, and Mallory are playing, Bob’s “turn” would come after Alice has finished all of her moves, and Bob’s “turn” would end once he’s finished playing all of his moves, at which point it would become Jack’s “turn”.

move
one individual action played by a player, during their turn.

The possible moves are defined in the playerMove struct.

It’s often valid to make several moves, such as drawing multiple cards (e.g. if the player before you played a card with value "2").

discard
play
place a card from your hand onto the discard pile. (note that the two terms are equivalent)