Corning Community College
CSCS2320 Data Structures
With the cards and various properties laid out, implement and use doubly-linked lists to arrange cards in a deck, or piles, foundations, as if setting the stage to make a card game.
You will want to go here to edit and fill in the various sections of the document:
A doubly-linked list is a natural extension from a singly-linked list. Where in the latter you're only able to move in one direction along each node in the list, a doubly-linked list allows you to move in both directions.
To create the infrastructure needed to make our doubly-linked list, your node structure will need an additional pointer. Previously, we only had a single pointer to connect to the next node in the list. Now, we'll need a second one to point to the previous node.
struct Node { [ Node properties ] Node* prev; Node* next; };
Navigating through a singly-linked list is something we're familiar with by now. Assuming the list exists, it was:
// Moves the pointer to the next node. temp = temp->next;
Now within our doubly-linked list, we have two pointers to move through the list. Moving forward through the list is exactly the same as before. Moving backwards through the list is almost identical:
// Moves the pointer to the previous node. temp = temp->prev;
Insertion is the process of adding a new node to your linked list anywhere except the end (that is appending in the next section). When performing an insertion, a common problem to be careful of is breaking the chain in your linked list. All of the nodes are “chained” together and if we break it then we will not be able to traverse it. Below will be examples of insertion in a doubly linked list.
The first thing you will do is Make sure you have a “start” pointer pointing at the first node in the list. Then create your new node using malloc like all your other nodes and have a temp pointer pointing to it.
- Inserting a node in the beginning
temp -> prev = NULL; temp -> your_data = your_data temp -> next = start; start -> prev = temp; start = temp;
The most important thing is to ensure connection and move your start pointer last.
- Inserting a node in the middle
Move your pointer to the node that's “next” pointer will be pointing to the new node.
temp -> your_data = your_data; temp -> prev = ptr; ptr = ptr -> next; temp -> next = ptr; ptr -> prev = temp ptr = temp -> prev; ptr -> next = temp;
You can see that it requires more steps than inserting at the beginning since we deal with 3 nodes rather than just 2.
Appending is similar to insertion, but presumably at the end. Its still a similar process though
newcard = (cardnode*)malloc(sizeof(cardnode)); previouscard->next = newcard; newcard->previous = previouscard; newcard->next = NULL;
Removing a node on a double-linked list is a somewhat easy process first you have to set the previous node's next pointer to the node you want to remove's next, and then you want to set the next node's previous to the current node's previous. Make sure to set the start and end of the list if the node to be removed is at the start or end of the list.
if(node->next!=NULL){ node->next->previous=node->previous; } if(node->previous!=NULL){ node->previous->next=node->next; } if(node is at start of list){ move start of list forward; } if(node is at end of list){ move end of list backward; } node->previous=NULL; node->next=NULL;
Thus you can detach the node from the list that it is from, to instead delete the node you would follow up the last if statement with a free(node);
To randomize your deck you can implement the Fisher-Yates shuffle algorithm which implements the rand() function and an array. To start you can make your array two different ways.
First way:
int[52] cardValues = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
Second way:
int[52] array for (int i = 0; i < 52; i++) { array[i] = i; }
Once you have created your array using one of the above methods it is time to shuffle the cards. To do so, use the following snip of code. It is the Fisher-Yates shuffle algorithm.
for (int i = 52; i > 0; i--) { // Generate a random index between 0 and i. int j = rand() % (i + 1); // Swap cardOrder[i] and cardOrder[j]. int temp = cardOrder[i]; // Store the value at cardOrder[i] in a temporary variable. cardOrder[i] = cardOrder[j]; // Replace the value at cardOrder[i] with the value at cardOrder[j]. cardOrder[j] = temp; // Set the value at cardOrder[j] to the value stored in the temporary variable. }
Your array is now shuffled and you can implement it into your card game to randomize your deck.
You could also use srand() with a seed so that every time you open the game the deck is shuffled differnetly. To do this you will need time.h and use the time to seed srand() then just use rand() as normal but now it is really random.
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:
104:cgf1:final tally of results (104/104) *:cgf1:doubly linked list implemented and used [52/52] *:cgf1:functional card game of some sort [52/52]