Table of Contents

Corning Community College

CSCS2320 Data Structures

PROJECT: Card Game Fun (CGF0)

OBJECTIVE

Lay the framework for our doubly-linked list: implement a deck of cards where you can display piles of cards, navigating through and showing each card in the deck (forward and backward).

Implement a simple game if you wish. Note: we'll be progressing to blackjack to cgf1 and then a freecell-style game in cgf2 using stacks.

EDIT

You will want to go here to edit and fill in the various sections of the document:

CGF0

stack API

STACK STRUCT
struct Stack
{
    Node *top;
    List *data;
    int   size;
    
    Stack *next;
    Stack *prev;
};

A useful addition to your stack may be some type of Stack Card Counter that will keep track of how many Cards are in your Stack. This can be implemented with many functions. For example with pop it can be used to make sure you don't pop of NULL from an empty Stack (Card Count value will -= 1 at the end of pop). Or it could be used with push and making sure you don't push a card over your Stack size that will then be lost forever (Card Count value will += 1).

In the cases of using a Stacklist, a next and previous pointer will be essential for success.

MKSTACK
Stack *mkstack (int);

The guts of your mkstack function should be relatively simple, including but not limited to:

  • Allocate the appropriate memory
  • Assign myStack→data to be your list of choosing
  • Assign myStack→top to be one end of your list
  • Assign the appropriate value to myStack→size
RMSTACK
Stack *rmstack (Stack *);

Much like rmlist from previous adventures.
You may want to run a few functions to handle the underlying list prior to handling the stack, as in this case the stack is built upon the list.
Possibly clearlist() rmlist() then you can handle your stack appropriately.
The reason behind handling your list is that you have a stack built upon a list, if you don't want a stack why do you want a list?

The purpose of a rmstack() function is to clear up and deallocate a stack. If you do not remove your stack at the end of the game, the stack elements (card nodes) will not be freed. Over time, the program will allocate more memory without freeing the previously allocated memory, which will lead to memory leak.

Remember too that you are returning a stack pointer when you call your function so you will want to set

myStack = rmstack(myStack)

when the time comes.

POP
Stack *pop (Stack *, Node **);

As stacks are always manipulated from the top you'll want:

  • obtain myStack→top
  • re-assign myStack→top

So long as your stack top isn't NULL that is

If you are using a quantity counter in your List, it would not be a bad idea to have it decrease as part of obtain as well.

PUSH
Stack *push (Stack *, Node *);

The act of pushing to a stack is placing whatever thing you have back to the top of the stack.
Whether you need to use insert() or append() as long as it is appropriately adding to the top of your stack you'll be fine
Of course reassign myStack→top to your new top.

If you are using a quantity counter in your List, it would not be a bad idea to have it increase as part of append / insert as well.

Stacklist

Some people maybe now or maybe later may find that having a list of Stack's useful. This will cause you to have to modify your Stack structure, which will now have some similarities with your nodes. For example you may want to add…

Stack *next;
Stack *prev;

to your stack.

A good Stacklist may look like:

struct Stacklist
{
    Stack *start;
    Stack *end;
    
    int quantity;
}

Although the quantity is not essential, it may not hurt to know how many are in the Stacklist at a given time. This can be useful for debugging, or even utilized for functionality in the game.

mkstacklist
Stack* mkstacklist()
{
    Staklist *mySL;
    mySL = malloc( sizeof(Stacklist));
    mySL -> start = NULL;
    mySL -> end = NULL;
    return mySL;
}

Any other functions with Stacklist will basically be your list functions but with mySL instead of mylist.

Keep in mind that when you “make” a Stacklist, you will want to have the ability to rm / clear a stacklist later on down the line.

Cursor

FreeCell is a game that requires fluent movement for the cards between the original free cells, and the cells that will become available as the game progresses.

Traditionally, a mouse is required for the simplest form of transitioning the cards. However, Vircon32 does not currently have mouse functionality, so one must get creative.

There are a couple schools of thought on how to implement this movement into your game:

1) You could implement a pointer arrow (or a couple) to represent which stack the player is currently looking at. Then, assign keybinds to have the cards go to a certain cell / stack. Vircon32 has more than enough buttons to accomplish this goal.

2) You could introduce new movement patterns to the link list, so that the player may move up / down / left / right to move particular sets of cards at a time.

 

SUBMISSION

To be successful in this project, the following criteria (or their equivalent) must be met:

Submit Tool Usage

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.

RUBRIC

I'll be evaluating the project based on the following criteria:

182:cgf0:final tally of results (182/182)
*:cgf0:card value stored in single int, face and suit extracted [26/26]
*:cgf0:doubly linked card struct with support functions [26/26]
*:cgf0:stack management struct with push and pop functions [26/26]
*:cgf0:ability to shuffle cards [26/26]
*:cgf0:code, XML config, build script, and cartridge submitted [26/26]
*:cgf0:ability to navigate through a dealt pile [26/26]
*:cgf0:code and supporting resources committed to repo [26/26]

Pertaining to the collaborative authoring of project documentation

Additionally