Corning Community College
CSCS2320 Data Structures
Using your experience playing with cards from the previous projects, implement a Freecell or Forty Thieves-style game making use of stacks.
You will want to go here to edit and fill in the various sections of the document:
The following is a simple struct for a stack. It includes a pointer to a deck class, a pointer to the top card in a stack, and the size of a stack.
struct stack { deck* deckPtr; // Pointer to the deck structure cardnode* top; // Pointer to the top card in the stack int size; // Size of the stack };
After Making your struct stack you can choose to make a function that you can call every time you make a new stack. You'll want to do this considering how many stacks you need for creating FreeCell.
//Creates a stack when called stack* createStack(deck* d) { stack* newStack = (stack*)malloc(sizeof(stack)); newStack->deckPtr = d; newStack->top = NULL; newStack->size = 0; return newStack; }
LIFO stands for last in, first out. In a LIFO system, the last item added to the structure is the first one to be removed. It's similar to a stack data structure, where you can think of items being stacked on top of each other, and the most recently added item is the first to be taken off the stack. FILO stands for first in, last out. In the FILO structure, the first item to get added to a list is the last one to get taken out. You can think of this as a queue where the item that has been in queue the longest is the one that gets taken out next.
The following is a function that grabs a card from the deck list and pushes it onto the specified stack.
void push(stack* s, cardnode* card) { card->next = s->top; // Link the new card to the previous top s->top = card; // Set the new card as the top s->size++; // Increase the size of the stack }
This is an example of what your pop function might look like.
void pop(stack* s, Cardnode* card) { s->top = card->prev; card->next->prev = card->prev; card->prev->next = card->next; if(s->size!=0){ s->size--; } }
The foundations in Freecell are 4 piles of cards in the upper-right. You're only able to place cards in foundations in a specific order, and you cannot take them back out. The order in which cards are placed in foundations goes from Ace to King, and each foundation represents one of the four suits.
At the start of the game, all the foundations are empty. To win Freecell, all four foundations must be filled up with the entire deck of cards.
To accomplish this functionality you can create the following bool function:
// Funtion for checking a valid placment of a card in the final destination bool isMoveValid(stack* upperStack, cardnode* card) { // If the stack is empty, only Ace can be placed if (upperStack->size == 0) { return card->value == 1; } cardnode* topCard = upperStack->top; // Checks if suits are the same and the card being added is one higher than the current card return (topCard->suit == card->suit) && (topCard->value + 1 == card->value); }
This function checks if the current card in your hand can be placed onto one of the final stacks (NOTE: This also takes into account that the current card you have matches the suit you are trying to place it on)
Here is a possible example of calling the function:
// Checks if the card can be dropped with the isMoveValid funtion and drops if so if (isMoveValid(currentStack, Hand->top)) { cardnode* topCard = pop(Hand); push(currentStack, topCard); }
Note: hand→top Refers to the card you are moving.
There are four Storage piles in the top-left of the board. Unlike the foundations, the each storage slot can only hold one card at a time.
Like the foundations, these start empty at the start of the game. The player may choose to take a card from any tableau and place it within a storage slot, and they can take it back at any time. If all the storage slots are filled, no more cards can be placed into the Storage piles.
The tableaus are the eight piles of cards below the storage piles and foundation piles.
At the start of the game, the tableaus are filled up with all 52 cards in a shuffled manner (It can be purely random, or placed strategically, it doesn't matter. The tableaus don't need to be a specific size.) The player is only able to interact with the top-most card of the tableau. The player has the option to move that card from one tableau into another tableau. However, a card can only be placed onto a tableau if:
The strategy for the player is to try to line up tableaus into positions going from King to Ace. This makes it much easier to place the cards into the foundations.
Note: When coding the tableaus, a max size for each stack may be desirable so that cards do not go off-screen.
To be successful in this project, the following criteria (or their equivalent) must be met:
Let's say you have completed work on the project, and are ready to submit, you would do the following:
lab46:~/src/SEMESTER/DESIG/PROJECT$ submit DESIG PROJECT file1 file2 file3 ... fileN
You should get some sort of confirmation indicating successful submission if all went according to plan. If not, check for typos and or locational mismatches.
I'll be evaluating the project based on the following criteria:
208:cgf2:final tally of results (208/208) *:cgf2:doubly linked stack implemented atop list [104/104] *:cgf2:doubly linked stack usable push and pop functions [104/104]