User Tools

Site Tools


notes:data:fall2023:projects:cgf1

cgf1

doubly linked lists

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

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

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;

removal

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);

Randomizing Deck

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.

card game

notes/data/fall2023/projects/cgf1.txt · Last modified: 2023/10/19 00:36 by cfoster8