Refactored paths to use linked lists.

- Removed the code for the now-obsolete-before-actually-being-used pathLists.
- playerAreas now contain a list called pathList.
- Refactored createArea, createPath, and the /move and /look commands.
- Added typedefs to prevent the compiler being unable to link.
This commit is contained in:
Barry Kane 2022-11-13 00:23:42 +00:00
parent f3ad758e4f
commit 582a0d02ae
6 changed files with 68 additions and 130 deletions

View File

@ -3,6 +3,7 @@
#include <string.h> #include <string.h>
#include "areadata.h" #include "areadata.h"
#include "playerdata.h" #include "playerdata.h"
#include "linkedlist.h"
// ==================== // ====================
// -=[ Area/Paths: ]=-: // -=[ Area/Paths: ]=-:
@ -22,11 +23,8 @@ playerArea * createArea(char * nameString, char * descriptionString)
createdArea->areaName[31] = '\0'; createdArea->areaName[31] = '\0';
createdArea->areaDescription[MAX - 36] = '\0'; createdArea->areaDescription[MAX - 36] = '\0';
// Ensure that all the paths are set to NULL: // Create a list for the paths in the area:
for(int index = 0; index < 16; index++) createdArea->pathList = createList(PATH);
{
createdArea->areaExits[index] = NULL;
}
// Return the pointer: // Return the pointer:
return createdArea; return createdArea;
@ -35,39 +33,24 @@ playerArea * createArea(char * nameString, char * descriptionString)
// Create a path between two areas given two areas and two strings: // Create a path between two areas given two areas and two strings:
int createPath(playerArea * fromArea, playerArea * toArea, char * fromDescription, char * toDescription) int createPath(playerArea * fromArea, playerArea * toArea, char * fromDescription, char * toDescription)
{ {
int fromAreaSlot, toAreaSlot; // Allocate the new paths:
for(fromAreaSlot = 0; fromAreaSlot < 16; fromAreaSlot++)
{
if(fromArea->areaExits[fromAreaSlot] == NULL)
{
break;
}
if((fromArea->areaExits[fromAreaSlot] != NULL) && (fromAreaSlot == 15))
{
return 1;
}
}
for(toAreaSlot = 0; toAreaSlot < 32; toAreaSlot++)
{
if(toArea->areaExits[toAreaSlot] == 0)
{
break;
}
if((toArea->areaExits[toAreaSlot] != 0) && (toAreaSlot == 31))
{
return 2;
}
}
playerPath * fromPath = malloc(sizeof(playerPath)); playerPath * fromPath = malloc(sizeof(playerPath));
playerPath * toPath = malloc(sizeof(playerPath)); playerPath * toPath = malloc(sizeof(playerPath));
fromArea->areaExits[fromAreaSlot] = fromPath;
toArea->areaExits[toAreaSlot] = toPath; // Setup the from path:
strncpy(fromPath->pathName, fromDescription, 32 - 1); strncpy(fromPath->pathName, fromDescription, 32 - 1);
fromPath->pathName[31] = '\0'; fromPath->pathName[31] = '\0';
fromPath->areaToJoin = toArea;
// Setup the to path:
strncpy(toPath->pathName, toDescription, 32 - 1); strncpy(toPath->pathName, toDescription, 32 - 1);
toPath->pathName[31] = '\0'; toPath->pathName[31] = '\0';
fromArea->areaExits[fromAreaSlot]->areaToJoin = toArea; toPath->areaToJoin = fromArea;
toArea->areaExits[toAreaSlot]->areaToJoin = fromArea;
// Add to the lists:
addToList(fromArea->pathList, fromPath, PATH);
addToList(toArea->pathList, toPath, PATH);
return 0; return 0;
} }
@ -85,16 +68,6 @@ areaNode * createAreaList(playerArea * initialArea)
return newAreaList; return newAreaList;
} }
// Create and initialize an pathList:
pathNode * createPathList(playerPath * initialPath)
{
pathNode * newPathList = malloc(sizeof(pathNode));
newPathList->data = initialPath;
newPathList->next = NULL;
newPathList->prev = NULL;
return newPathList;
}
// Adds an areaNode to the end of a list, returning it's position: // Adds an areaNode to the end of a list, returning it's position:
int addAreaNodeToList(areaNode * toList, playerArea * areaToAdd) int addAreaNodeToList(areaNode * toList, playerArea * areaToAdd)
{ {
@ -134,45 +107,6 @@ int deleteAreaNodeFromList(areaNode * fromList, playerArea * areaToDelete)
return 0; return 0;
} }
// Adds an pathNode to the end of a list, returning it's position:
int addPathNodeToList(pathNode * toList, playerPath * pathToAdd)
{
pathNode * current;
int index = 0;
current = toList;
while(current->next != NULL)
{
current = current->next;
index++;
}
current->next = malloc(sizeof(pathNode));
current->next->prev = current;
current->next->data = pathToAdd;
current->next->next = NULL;
return index;
}
// Removes an pathNode from the list, returning 0 on success and -1 on failure:
int deletePathNodeFromList(pathNode * fromList, playerPath * pathToDelete)
{
pathNode * current = fromList;
while(current->data != pathToDelete || current->next != NULL)
{
current = current->next;
}
if(current->next == NULL && current->data != pathToDelete)
{
return -1;
}
current->prev->next = current->next;
if(current->next != NULL)
{
current->next->prev = current->prev;
}
free(current);
return 0;
}
// Return the areaNode at the given index from the list: // Return the areaNode at the given index from the list:
areaNode * getAreaNode(areaNode * fromList, int listIndex) areaNode * getAreaNode(areaNode * fromList, int listIndex)
{ {
@ -191,24 +125,6 @@ areaNode * getAreaNode(areaNode * fromList, int listIndex)
return current; return current;
} }
// Return the pathNode at the given index from the list:
pathNode * getPathNode(pathNode * fromList, int listIndex)
{
pathNode * current = fromList;
for(int index = 0; index < listIndex; index++)
{
if(current->next != NULL)
{
current = current->next;
}
else
{
return NULL;
}
}
return current;
}
// Return the playerArea of the areaNode at the given index from the list: // Return the playerArea of the areaNode at the given index from the list:
playerArea * getAreaFromList(areaNode * fromList, int listIndex) playerArea * getAreaFromList(areaNode * fromList, int listIndex)
{ {

View File

@ -3,6 +3,8 @@
#ifndef AREADATA_H #ifndef AREADATA_H
#define AREADATA_H #define AREADATA_H
#include "constants.h" #include "constants.h"
#include "linkedlist.h"
// ==================== // ====================
// -=[ Area/Paths: ]=-: // -=[ Area/Paths: ]=-:
// ==================== // ====================
@ -18,9 +20,10 @@ struct playerPath
struct playerArea struct playerArea
{ {
list * pathList;
char areaName[32]; char areaName[32];
char areaDescription[MAX - 35]; char areaDescription[MAX - 35];
playerPath * areaExits[16]; // playerPath * areaExits[16];
}; };
// Create an area given a name and description: // Create an area given a name and description:

View File

@ -8,6 +8,7 @@
#include "constants.h" #include "constants.h"
#include "gamelogic.h" #include "gamelogic.h"
#include "playerdata.h" #include "playerdata.h"
#include "linkedlist.h"
#include "inputoutput.h" #include "inputoutput.h"
// ======================= // =======================
@ -364,16 +365,25 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
strncat(lookMessage->messageContent, currentCommand->caller->currentArea->areaDescription, MAX - 35); strncat(lookMessage->messageContent, currentCommand->caller->currentArea->areaDescription, MAX - 35);
queueTargetedOutputMessage(parameters->outputQueue, lookMessage, &currentCommand->caller, 1); queueTargetedOutputMessage(parameters->outputQueue, lookMessage, &currentCommand->caller, 1);
bzero(lookMessage, sizeof(userMessage)); bzero(lookMessage, sizeof(userMessage));
if(currentCommand->caller->currentArea->areaExits[0] != NULL)
// Loop through the paths and send the appropriate amount of messages:
int charCount = 13;
strncat(lookMessage->messageContent, "You can go:", 13);
if(currentCommand->caller->currentArea->pathList->itemCount > 0)
{ {
strncat(lookMessage->messageContent, "You can go:", 13); for(size_t index = 0; index < currentCommand->caller->currentArea->pathList->itemCount; index++)
for(int index = 0; index < 16; index++)
{ {
if(currentCommand->caller->currentArea->areaExits[index] != NULL) if((charCount + 64) >= MAX)
{ {
snprintf(formattedString, 64, "\n\t%d. %s", index + 1, currentCommand->caller->currentArea->areaExits[index]->pathName); queueTargetedOutputMessage(parameters->outputQueue, lookMessage, &currentCommand->caller, 1);
strncat(lookMessage->messageContent, formattedString, 64); bzero(lookMessage, sizeof(userMessage));
charCount = 0;
} }
snprintf(formattedString, 64, "\n\t%ld. %s", index + 1,
getFromList(currentCommand->caller->currentArea->pathList, index)->path->pathName);
strncat(lookMessage->messageContent, formattedString, 64);
charCount += 64;
} }
queueTargetedOutputMessage(parameters->outputQueue, lookMessage, &currentCommand->caller, 1); queueTargetedOutputMessage(parameters->outputQueue, lookMessage, &currentCommand->caller, 1);
} }
@ -469,7 +479,7 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
strncat(statMessage->messageContent, formattedString, 120); strncat(statMessage->messageContent, formattedString, 120);
if((charCount + 43) >= MAX) if((charCount + 43) >= MAX)
{ {
strncat(statMessage->messageContent, "\n", 2); // strncat(statMessage->messageContent, "\n", 2);
queueTargetedOutputMessage(parameters->outputQueue, statMessage, &currentCommand->caller, 1); queueTargetedOutputMessage(parameters->outputQueue, statMessage, &currentCommand->caller, 1);
bzero(statMessage, sizeof(userMessage)); bzero(statMessage, sizeof(userMessage));
charCount = 0; charCount = 0;
@ -800,13 +810,13 @@ outcome skillCheck(playerInfo * player, int chance, char * skillName, size_t ski
int movePlayerToArea(playerInfo * player, char * requestedPath) int movePlayerToArea(playerInfo * player, char * requestedPath)
{ {
// Check if a number was given first: // Check if a number was given first:
int selected = atoi(requestedPath); size_t selected = atoi(requestedPath);
if(selected != 0) if(selected != 0 && !(selected > player->currentArea->pathList->itemCount))
{ {
if(player->currentArea->areaExits[selected - 1] != NULL && if(getFromList(player->currentArea->pathList, selected - 1)->path != NULL &&
player->currentArea->areaExits[selected - 1]->areaToJoin != NULL) getFromList(player->currentArea->pathList, selected - 1)->path->areaToJoin != NULL)
{ {
player->currentArea = player->currentArea->areaExits[selected - 1]->areaToJoin; player->currentArea = getFromList(player->currentArea->pathList, selected - 1)->path->areaToJoin;
return 0; return 0;
} }
else else
@ -816,16 +826,14 @@ int movePlayerToArea(playerInfo * player, char * requestedPath)
} }
// Otherwise search for the description: // Otherwise search for the description:
for (int index = 0; index < 16; index++) for (size_t index = 0; index < player->currentArea->pathList->itemCount; index++)
{ {
if(player->currentArea->areaExits[index] != NULL) if(strncmp(getFromList(player->currentArea->pathList, index)->path->pathName,
requestedPath, 32) == 0)
{ {
if(strncmp(player->currentArea->areaExits[index]->pathName, requestedPath, 32) == 0) printf("%s: %s\n", player->playerName, getFromList(player->currentArea->pathList, index)->path->pathName);
{ player->currentArea = getFromList(player->currentArea->pathList, index)->path->areaToJoin;
printf("%s: %s\n", player->playerName, player->currentArea->areaExits[index]->pathName); return 0;
player->currentArea = player->currentArea->areaExits[index]->areaToJoin;
return 0;
}
} }
} }
return 1; return 1;

View File

@ -90,7 +90,7 @@ listData * getFromList(list * list, size_t listIndex)
// Return the head if index is 0: // Return the head if index is 0:
else if(listIndex == 0) else if(listIndex == 0)
{ {
return &list->head->data; return &(list->head->data);
} }
// Loop through the entries in the list until we get to the right one: // Loop through the entries in the list until we get to the right one:
else else
@ -100,7 +100,7 @@ listData * getFromList(list * list, size_t listIndex)
{ {
currentNode = currentNode->next; currentNode = currentNode->next;
} }
return &currentNode->data; return &(currentNode->data);
} }
} }
@ -424,7 +424,7 @@ bool getIndexFromList(list * list, void * data, listDataType type, size_t * inde
return false; return false;
} }
for(*index = 0; *index < list->itemCount; *index++) for(*index = 0; *index < list->itemCount; *index += 1)
{ {
switch(type) switch(type)
{ {

View File

@ -2,8 +2,14 @@
// Barry Kane, 2022. // Barry Kane, 2022.
#ifndef LINKEDLIST_H #ifndef LINKEDLIST_H
#define LINKEDLIST_H #define LINKEDLIST_H
#include "playerdata.h"
#include "areadata.h" #include "areadata.h"
#include "playerdata.h"
// Let the compiler know there will be structs defined elsewhere:
typedef struct playerPath playerPath;
typedef struct playerArea playerArea;
typedef struct playerInfo playerInfo;
typedef struct playerSkill playerSkill;
// ======================== // ========================
// -=[ Data Structures ]=-: // -=[ Data Structures ]=-:

View File

@ -6,6 +6,11 @@
#include <stdbool.h> #include <stdbool.h>
#include "areadata.h" #include "areadata.h"
#include "constants.h" #include "constants.h"
#include "linkedlist.h"
// Let the compiler know there will be structs defined elsewhere:
typedef struct playerPath playerPath;
typedef struct playerArea playerArea;
typedef struct statBlock typedef struct statBlock
{ {
@ -49,7 +54,7 @@ typedef struct skillList
skillNode * head; skillNode * head;
int skillCount; int skillCount;
} skillList; } skillList;
\
typedef struct playerInfo typedef struct playerInfo
{ {
char playerName[32]; char playerName[32];