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 "areadata.h"
#include "playerdata.h"
#include "linkedlist.h"
// ====================
// -=[ Area/Paths: ]=-:
@ -22,12 +23,9 @@ playerArea * createArea(char * nameString, char * descriptionString)
createdArea->areaName[31] = '\0';
createdArea->areaDescription[MAX - 36] = '\0';
// Ensure that all the paths are set to NULL:
for(int index = 0; index < 16; index++)
{
createdArea->areaExits[index] = NULL;
}
// Create a list for the paths in the area:
createdArea->pathList = createList(PATH);
// Return the pointer:
return createdArea;
}
@ -35,39 +33,24 @@ playerArea * createArea(char * nameString, char * descriptionString)
// Create a path between two areas given two areas and two strings:
int createPath(playerArea * fromArea, playerArea * toArea, char * fromDescription, char * toDescription)
{
int fromAreaSlot, toAreaSlot;
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;
}
}
// Allocate the new paths:
playerPath * fromPath = 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);
fromPath->pathName[31] = '\0';
fromPath->pathName[31] = '\0';
fromPath->areaToJoin = toArea;
// Setup the to path:
strncpy(toPath->pathName, toDescription, 32 - 1);
toPath->pathName[31] = '\0';
fromArea->areaExits[fromAreaSlot]->areaToJoin = toArea;
toArea->areaExits[toAreaSlot]->areaToJoin = fromArea;
toPath->pathName[31] = '\0';
toPath->areaToJoin = fromArea;
// Add to the lists:
addToList(fromArea->pathList, fromPath, PATH);
addToList(toArea->pathList, toPath, PATH);
return 0;
}
@ -85,16 +68,6 @@ areaNode * createAreaList(playerArea * initialArea)
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:
int addAreaNodeToList(areaNode * toList, playerArea * areaToAdd)
{
@ -134,45 +107,6 @@ int deleteAreaNodeFromList(areaNode * fromList, playerArea * areaToDelete)
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:
areaNode * getAreaNode(areaNode * fromList, int listIndex)
{
@ -191,24 +125,6 @@ areaNode * getAreaNode(areaNode * fromList, int listIndex)
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:
playerArea * getAreaFromList(areaNode * fromList, int listIndex)
{

View File

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

View File

@ -8,6 +8,7 @@
#include "constants.h"
#include "gamelogic.h"
#include "playerdata.h"
#include "linkedlist.h"
#include "inputoutput.h"
// =======================
@ -364,16 +365,25 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
strncat(lookMessage->messageContent, currentCommand->caller->currentArea->areaDescription, MAX - 35);
queueTargetedOutputMessage(parameters->outputQueue, lookMessage, &currentCommand->caller, 1);
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(int index = 0; index < 16; index++)
for(size_t index = 0; index < currentCommand->caller->currentArea->pathList->itemCount; 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);
strncat(lookMessage->messageContent, formattedString, 64);
queueTargetedOutputMessage(parameters->outputQueue, lookMessage, &currentCommand->caller, 1);
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);
}
@ -469,7 +479,7 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
strncat(statMessage->messageContent, formattedString, 120);
if((charCount + 43) >= MAX)
{
strncat(statMessage->messageContent, "\n", 2);
// strncat(statMessage->messageContent, "\n", 2);
queueTargetedOutputMessage(parameters->outputQueue, statMessage, &currentCommand->caller, 1);
bzero(statMessage, sizeof(userMessage));
charCount = 0;
@ -800,13 +810,13 @@ outcome skillCheck(playerInfo * player, int chance, char * skillName, size_t ski
int movePlayerToArea(playerInfo * player, char * requestedPath)
{
// Check if a number was given first:
int selected = atoi(requestedPath);
if(selected != 0)
size_t selected = atoi(requestedPath);
if(selected != 0 && !(selected > player->currentArea->pathList->itemCount))
{
if(player->currentArea->areaExits[selected - 1] != NULL &&
player->currentArea->areaExits[selected - 1]->areaToJoin != NULL)
if(getFromList(player->currentArea->pathList, selected - 1)->path != 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;
}
else
@ -816,17 +826,15 @@ int movePlayerToArea(playerInfo * player, char * requestedPath)
}
// 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, player->currentArea->areaExits[index]->pathName);
player->currentArea = player->currentArea->areaExits[index]->areaToJoin;
return 0;
}
}
}
printf("%s: %s\n", player->playerName, getFromList(player->currentArea->pathList, index)->path->pathName);
player->currentArea = getFromList(player->currentArea->pathList, index)->path->areaToJoin;
return 0;
}
}
return 1;
}

View File

@ -90,7 +90,7 @@ listData * getFromList(list * list, size_t listIndex)
// Return the head if index is 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:
else
@ -100,7 +100,7 @@ listData * getFromList(list * list, size_t listIndex)
{
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;
}
for(*index = 0; *index < list->itemCount; *index++)
for(*index = 0; *index < list->itemCount; *index += 1)
{
switch(type)
{

View File

@ -2,8 +2,14 @@
// Barry Kane, 2022.
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "playerdata.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 ]=-:

View File

@ -6,6 +6,11 @@
#include <stdbool.h>
#include "areadata.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
{
@ -49,7 +54,7 @@ typedef struct skillList
skillNode * head;
int skillCount;
} skillList;
\
typedef struct playerInfo
{
char playerName[32];