// Battle Royale Linked List Demo
// Part 1: Creating a linked list using a function
// that creates a single node.
// Looping through the list and printing out the names
// Part 2: Inserting into the linked list.
// Also finding specific insertion points and
// inserting into an ordered list
// Part 3: Removing from the linked list.
// Specifically removing by finding a player
// by their name
// Freeing a memory allocated linked list
// Marc Chee (cs1511@cse.unsw.edu.au) November 2020
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_NAME_LENGTH 100
struct player {
struct player *next;
char name[MAX_NAME_LENGTH];
};
struct player *createPlayer(char *newName, struct player *newNext);
int printPlayers(struct player *playerList);
struct player *insertAfter(struct player *insertPos, char *newName);
struct player *insertAlpha(struct player *list, char *newName);
struct player *removePlayer(struct player *list, char *remName);
void freePlayerList(struct player *head);
int main(void) {
struct player *head = NULL;
head = insertAlpha(head, "Marc");
head = insertAlpha(head, "Chicken");
head = insertAlpha(head, "Aang");
head = insertAlpha(head, "Zuko");
head = insertAlpha(head, "Katara");
// Game loop. Keep looping until there's only one player left
while (printPlayers(head) > 1) {
printf("Please type in the name of a player to knock out: ");
char input[MAX_NAME_LENGTH];
fgets(input, MAX_NAME_LENGTH, stdin);
if (input[strlen(input) - 1] == '\n') {
input[strlen(input) - 1] = '\0';
}
head = removePlayer(head, input);
}
// there's one (or less) player remaining
printf("Winner winner Chicken's Dinner. %s has won.\n", head->name);
freePlayerList(head);
return 0;
}
// create player allocates memory for a new player and
// populates it with newName and newNext.
// returns a pointer the the newly created player
struct player *createPlayer(char *newName, struct player *newNext) {
struct player *newPlayer = malloc(sizeof (struct player));
strcpy(newPlayer->name, newName);
newPlayer->next = newNext;
return newPlayer;
}
// takes the pointer to the head of a list of players
// prints their names, one per line
// returns the number of players that were printed out
int printPlayers(struct player *playerList) {
int numPlayers = 0;
printf("The players remaining in the game are:\n");
struct player *curr = playerList;
while (curr != NULL) {
//fputs(curr->name, stdout);
//putchar('\n');
printf("%s\n", curr->name);
numPlayers++;
curr = curr->next;
}
return numPlayers;
}
// Insert a newly created player after insertPos in a list
// If the list was empty, return a pointer to the new list
// Otherwise, return insertPos
struct player *insertAfter(struct player *insertPos, char *newName) {
// create a new player
struct player *newPlayer = createPlayer(newName, NULL);
if (insertPos == NULL) {
// inserting into an empty list
insertPos = newPlayer;
} else {
// inserting into a list that exists
// set the new player's next to be insertPos' next
newPlayer->next = insertPos->next;
// set insertPos' next to aim at the new player
insertPos->next = newPlayer;
}
return insertPos;
}
// Insert an element into an already alphabetically ordered list
// Will insert into the correct position, then return the head
// of the list, even if it has changed
struct player *insertAlpha(struct player *list, char *newName) {
// loop through looking for the insertion point
struct player *curr = list;
struct player *prev = NULL;
// stop when we see something that's after us in the alphabet
while (curr != NULL && strcmp(newName, curr->name) > 0) {
prev = curr;
curr = curr->next;
}
// prev now aims at where the insertion should happen
// Use insertAfter
struct player *newHead = insertAfter(prev, newName);
if (prev == NULL) {
// the new player is the head of the list
newHead->next = list;
} else {
// the new player is inserted somewhere other than the head
newHead = list;
}
return newHead;
}
struct player *removePlayer(struct player *list, char *remName) {
// find the player to remove
struct player *prev = NULL;
struct player *curr = list;
// loop through the list, maintaining a prev pointer
// stop when you find a name match
while (curr != NULL && strcmp(remName, curr->name) != 0) {
prev = curr;
curr = curr->next;
}
// curr will now point at the node that matched or NULL
if (curr != NULL) {
// we found a match, so we'll remove it
if (prev == NULL) {
// the node we're removing is the head of the list
list = list->next;
} else {
// we're removing another element of the list
prev->next = curr->next;
}
free(curr);
}
return list;
}
// Loop through the list, freeing all the player nodes
void freePlayerList(struct player *head) {
while (head != NULL) {
struct player *remNode = head;
head = head->next;
free(remNode);
}
}
Resource created Friday 06 November 2020, 01:20:03 PM.
file: battleRoyale.c