Table of Contents

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:

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:

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.