Completed the conversion to the new linked-list type.

- Moved all code relating to skills to use the new linked-lists.
- Removed all old code relating to other lists.
- Improved linked lists to get nodes more efficiently in the second half of the list.
This commit is contained in:
Barry Kane 2022-11-29 21:04:36 +00:00
parent 51f1a953e7
commit 4cc0d3a0f6
6 changed files with 86 additions and 173 deletions

View File

@ -468,13 +468,15 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
bzero(statMessage->messageContent, sizeof(char) * MAX);
if(currentCommand->caller->skills->head != NULL)
{
skillNode * currentSkill = currentCommand->caller->skills->head;
size_t skillIndex = 0;
int charCount = 0;
bool addNewline = false;
while(currentSkill != NULL)
playerSkill * skill;
while(skillIndex < currentCommand->caller->skills->itemCount)
{
snprintf(formattedString, 120, "| %2d | %31s ",
currentSkill->skill->skillPoints, currentSkill->skill->skillName);
skill = getFromList(currentCommand->caller->skills, skillIndex)->skill;
skillIndex++;
snprintf(formattedString, 120, "| %2d | %31s ", skill->skillPoints, skill->skillName);
charCount += 43;
strncat(statMessage->messageContent, formattedString, 120);
if((charCount + 43) >= MAX)
@ -494,9 +496,7 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
else
{
addNewline = true;
}
currentSkill = currentSkill->next;
}
}
queueTargetedOutputMessage(parameters->outputQueue, statMessage, &currentCommand->caller, 1);
}
@ -617,14 +617,16 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
}
if(strncmp(currentCommand->command, "listskills", 10) == 0)
{
skillNode * currentSkill = parameters->globalSkillList->head;
userMessage * listMessage = calloc(1, sizeof(userMessage));
char * formattedString = calloc(121, sizeof(char));
int charCount = 0;
size_t skillIndex = 0;
bool addNewline = false;
while(currentSkill != NULL)
playerSkill * currentSkill;
while(skillIndex < parameters->globalSkillList->itemCount)
{
snprintf(formattedString, 120, "| %-31s ", currentSkill->skill->skillName);
currentSkill = getFromList(parameters->globalSkillList, skillIndex)->skill;
snprintf(formattedString, 120, "| %-31s ", currentSkill->skillName);
charCount += 43;
strncat(listMessage->messageContent, formattedString, 120);
if((charCount + 46) >= MAX)
@ -644,7 +646,7 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
{
addNewline = true;
}
currentSkill = currentSkill->next;
skillIndex++;
}
queueTargetedOutputMessage(parameters->outputQueue, listMessage, &currentCommand->caller, 1);
free(listMessage);
@ -727,7 +729,7 @@ outcome statCheck(playerInfo * player, int chance, coreStat statToCheck)
}
// Run a skill check:
outcome skillCheck(playerInfo * player, int chance, char * skillName, size_t skillNameLength, skillList * globalSkillList)
outcome skillCheck(playerInfo * player, int chance, char * skillName, size_t skillNameLength, list * globalSkillList)
{
// Calculate the chance:
if(chance > 100 || chance < 0)
@ -738,46 +740,39 @@ outcome skillCheck(playerInfo * player, int chance, char * skillName, size_t ski
// Check if the player has the given skill:
bool playerHasSkill = false;
skillNode * currentPlayerNode = player->skills->head;
while(currentPlayerNode != NULL)
size_t playerIndex = 0;
while(playerIndex < player->skills->itemCount)
{
if(strncmp(skillName, currentPlayerNode->skill->skillName, skillNameLength) == 0)
if(strncmp(skillName, getFromList(player->skills, playerIndex)->skill->skillName, skillNameLength) != 0)
{
playerHasSkill = true;
break;
}
currentPlayerNode = currentPlayerNode->next;
playerIndex++;
}
// If the player doesn't have the skill, check if it's in the game and is trained:
bool trainedSkill = false;
if(!playerHasSkill)
size_t globalIndex = 0;
while(globalIndex < globalSkillList->itemCount)
{
skillNode * currentNode = globalSkillList->head;
while(strncmp(skillName, currentNode->skill->skillName, 32) != 0)
if(strncmp(skillName, getFromList(globalSkillList, globalIndex)->skill->skillName, skillNameLength) != 0)
{
if(currentNode->next == NULL)
{
fprintf(stderr, "Skill doesn't exist in skill list.\n");
return ERROR;
}
currentNode = currentNode->next;
}
if(currentNode->skill->trainedSkill == true)
{
trainedSkill = true;
trainedSkill = getFromList(globalSkillList, globalIndex)->skill->trainedSkill;
break;
}
globalIndex++;
}
// Calculate the modifier:
int modifier = 0;
if(trainedSkill)
{
modifier = -100;
}
else
else if(playerHasSkill)
{
modifier = currentPlayerNode->skill->skillPoints * 4;
modifier = getFromList(player->skills, playerIndex)->skill->skillModifier * 4;
}
// Attempt the check:

View File

@ -20,7 +20,7 @@ typedef struct gameLogicParameters
playerInfo * connectedPlayers;
inputMessageQueue * inputQueue;
outputMessageQueue * outputQueue;
skillList * globalSkillList;
list * globalSkillList;
} gameLogicParameters;
// Thread function which runs the main game loop, given the needed parameters:
@ -90,6 +90,6 @@ typedef enum outcome
outcome statCheck(playerInfo * player, int chance, coreStat statToCheck);
// Run a skill check:
outcome skillCheck(playerInfo * player, int chance, char * skillName, size_t skillNameLength, skillList * globalSkillList);
outcome skillCheck(playerInfo * player, int chance, char * skillName, size_t skillNameLength, list * globalSkillList);
#endif

View File

@ -121,12 +121,24 @@ listNode * getNodeFromList(list * list, size_t listIndex)
// Loop through the entries in the list until we get to the right one:
else
{
listNode * currentNode = list->head;
while(listIndex-- > 0)
if((list->itemCount / 2) < listIndex)
{
currentNode = currentNode->next;
listNode * currentNode = list->tail;
while(listIndex-- > 0)
{
currentNode = currentNode->previous;
}
return currentNode;
}
else
{
listNode * currentNode = list->head;
while(listIndex-- > 0)
{
currentNode = currentNode->next;
}
return currentNode;
}
return currentNode;
}
}

View File

@ -9,12 +9,12 @@
#include "playerdata.h"
// Create a new skill and add it to the global skill list:
int createSkill(skillList * globalSkillList, char * skillName, int skillNameLength, bool trainedSkill)
listNode * createSkill(list * globalSkillList, char * skillName, int skillNameLength, bool trainedSkill)
{
if(skillNameLength >= 32)
{
fprintf(stderr, "Skill name is too long. Please shorten the name and try again.\n");
return -1;
return NULL;
}
playerSkill * newSkill = malloc(sizeof(playerSkill));
@ -26,112 +26,56 @@ int createSkill(skillList * globalSkillList, char * skillName, int skillNameLeng
newSkill->trainedSkill = trainedSkill;
// Add the skill to a node in the list:
return(addSkillNode(globalSkillList, newSkill));
}
// Add a skill node to a skill list:
int addSkillNode(skillList * skillList, playerSkill * skill)
{
if(skillList->head == NULL)
{
skillList->head = malloc(sizeof(skillNode));
skillList->head->skill = skill;
skillList->head->next = NULL;
skillList->skillCount = 1;
return 0;
}
else
{
skillNode * currentNode = skillList->head;
while(currentNode->next != NULL)
{
currentNode = currentNode->next;
}
currentNode->next = malloc(sizeof(skillNode));
currentNode->next->skill = skill;
currentNode->next->next = NULL;
skillList->skillCount++;
return skillList->skillCount;
}
}
// Remove a skill node from a skill list:
int removeSkillNode(skillList * skillList, playerSkill * skill)
{
// Check the validity of the pointers:
if(skillList->head == NULL || skill == NULL)
{
return -1;
}
if(skillList->head->skill == skill)
{
skillNode * newHead = skillList->head->next;
free(skillList->head->skill);
free(skillList->head);
skillList->head = newHead;
return 0;
}
else
{
skillNode * currentNode = skillList->head;
skillNode * previousNode = skillList->head;
while(currentNode->skill != skill)
{
if(currentNode->next == NULL)
{
return -1;
}
previousNode = currentNode;
currentNode = currentNode->next;
}
free(currentNode->skill);
previousNode->next = currentNode->next;
free(currentNode);
return 0;
}
return(addToList(globalSkillList, newSkill, SKILL));
}
// Take a skill and add it to the player's skill list:
int takeSkill(skillList * globalSkillList, char * skillName, int skillNameLength, playerInfo * targetPlayer)
int takeSkill(list * globalSkillList, char * skillName, int skillNameLength, playerInfo * targetPlayer)
{
skillNode * currentNode = globalSkillList->head;
while(strncmp(skillName, currentNode->skill->skillName, 32) != 0)
// Check if the skill exists in the game:
size_t globalIndex = 0;
bool skillExists = false;
while(globalIndex < globalSkillList->itemCount)
{
if(currentNode->next == NULL)
if(strncmp(skillName, getFromList(globalSkillList, globalIndex)->skill->skillName, skillNameLength) == 0)
{
fprintf(stderr, "Skill doesn't exist in skill list.\n");
return -1;
skillExists = true;
break;
}
currentNode = currentNode->next;
globalIndex++;
}
bool playerHasSkill = false;
skillNode * currentPlayerNode = targetPlayer->skills->head;
while(currentPlayerNode != NULL)
if(!skillExists)
{
if(strncmp(skillName, currentPlayerNode->skill->skillName, skillNameLength) == 0)
fprintf(stderr, "Skill doesn't exist in skill list.\n");
return -1;
}
// Check if the player has the skill:
size_t playerIndex = 0;
bool playerHasSkill = false;
while(playerIndex < targetPlayer->skills->itemCount)
{
if(strncmp(skillName, getFromList(targetPlayer->skills, playerIndex)->skill->skillName, skillNameLength) == 0)
{
playerHasSkill = true;
break;
}
currentPlayerNode = currentPlayerNode->next;
playerIndex++;
}
if(playerHasSkill)
{
currentPlayerNode->skill->skillPoints++;
getFromList(targetPlayer->skills, playerIndex)->skill->skillPoints++;
}
// Copy the skill into the player's skill list:
else
{
addSkillNode(targetPlayer->skills, currentNode->skill);
currentPlayerNode = targetPlayer->skills->head;
while(currentPlayerNode->next != NULL)
{
currentPlayerNode = currentPlayerNode->next;
}
currentPlayerNode->skill->skillPoints = 1;
playerSkill * newSkill = calloc(1, sizeof(playerSkill));
strncpy(newSkill->skillName, getFromList(globalSkillList, globalIndex)->skill->skillName, 32);
printf("%s ", newSkill->skillName);
newSkill->skillPoints = 1;
addToList(targetPlayer->skills, newSkill, SKILL);
}
return 0;
}
@ -268,25 +212,7 @@ coreStat getCoreStatFromString(char * inputString, int stringLength)
int deallocatePlayer(playerInfo * playerToDeallocate)
{
// Deallocate the skill list:
if(playerToDeallocate->skills->skillCount > 0)
{
// Allocate enough pointers:
skillNode * nodesToDeallocate[playerToDeallocate->skills->skillCount];
skillNode * currentSkillNode = playerToDeallocate->skills->head;
// Get a list of all the nodes together:
for(int index = 0; index < playerToDeallocate->skills->skillCount; index++)
{
nodesToDeallocate[index] = currentSkillNode;
currentSkillNode = currentSkillNode->next;
}
// Deallocate all the nodes:
for(int index = 0; index < playerToDeallocate->skills->skillCount; index++)
{
free(nodesToDeallocate[index]);
}
}
destroyList(&(playerToDeallocate->skills));
// Deallocate the stat block:
free(playerToDeallocate->stats);

View File

@ -11,6 +11,8 @@
// Let the compiler know there will be structs defined elsewhere:
typedef struct playerPath playerPath;
typedef struct playerArea playerArea;
typedef struct list list;
typedef struct listNode listNode;
typedef struct statBlock
{
@ -42,25 +44,12 @@ typedef struct playerSkill
bool trainedSkill;
} playerSkill;
typedef struct skillNode skillNode;
struct skillNode
{
playerSkill * skill;
skillNode * next;
};
typedef struct skillList
{
skillNode * head;
int skillCount;
} skillList;
typedef struct playerInfo
{
char playerName[32];
playerArea * currentArea;
statBlock * stats;
skillList * skills;
list * skills;
} playerInfo;
typedef enum coreStat
@ -74,18 +63,11 @@ typedef enum coreStat
} coreStat;
// Create a new skill and add it to the global skill list:
int createSkill(skillList * globalSkillList, char * skillName, int skillNameLength, bool trainedSkill);
// Add a skill node to a skill list:
int addSkillNode(skillList * skillList, playerSkill * skill);
// Remove a skill node from a skill list:
int removeSkillNode(skillList * skillList, playerSkill * skill);
int removeSkillByID(skillList * skillList, playerSkill * skill);
listNode * createSkill(list * globalSkillList, char * skillName, int skillNameLength, bool trainedSkill);
// Take a skill and add it to the player's skill list:
int takeSkill(skillList * globalSkillList, char * skillName, int skillNameLength, playerInfo * targetPlayer);
int takeSkillbyID(skillList * globalSkillList, int skillID, playerInfo * targetPlayer);
int takeSkill(list * globalSkillList, char * skillName, int skillNameLength, playerInfo * targetPlayer);
int takeSkillbyID(list * globalSkillList, int skillID, playerInfo * targetPlayer);
// Take a string containing a core stat name and return the core stat:
coreStat getCoreStatFromString(char * string, int stringLength);

View File

@ -94,8 +94,7 @@ int main(int argc, char ** argv)
createOneWayPath(getFromList(areas, 2)->area, getFromList(areas, 3)->area,
"Continue to station interior. ");
skillList * globalSkillList = malloc(sizeof(skillList));
globalSkillList->head = NULL;
list * globalSkillList = createList(SKILL);
// Create a few basic skills:
createSkill(globalSkillList, "Medicine", 8, true);
@ -116,8 +115,7 @@ int main(int argc, char ** argv)
connectedPlayers[index].stats = calloc(1, sizeof(statBlock));
connectedPlayers[index].stats->specPoints = 30;
connectedPlayers[index].stats->skillPoints = 30;
connectedPlayers[index].skills = calloc(1, sizeof(skillList));
connectedPlayers[index].skills->head = NULL;
connectedPlayers[index].skills = createList(SKILL);
}
// -==[ TEST GAME-STATE INITIALIZATION END ]==-