Search code examples
c++classdynamiclinked-listinventory

Dynamic Link List RPG Inventory Program - Help (How do I link to classes ?)


I'm making a class-based inventory system using two classes: one for characters and one for items.

Code by Ryan Newell - NEW14136796 Uclan Student (Need to put this in so plagarism monitors won't flag me for copying my own work)

Here's what I got so far.

    ///Code by Ryan Newell - NEW14136796 Runshaw College - Uclan
#include<iostream> //Base C++ required #
#include<string> //Allows input of strings
#include<iomanip>  //Base C++ required #
#include <conio.h> //Getchar error workaround
#include <cstdlib>  // Provides EXIT_SUCCESS
#include <fstream> // Allows output of txt files
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <utility>
#include <Windows.h>//ConsoleSleep

using namespace std;

class itemspell{
    string itemname; //Name ((( what if items are the same name ? make difficult for finding statements ? maybe more char with same name item ?
    string itemtype; // Spell/Weapon/Armour/Magic Misc?
    string itemact; // What type of action does this item do ?
    string itemdesc; // Some random ingame description
    itemspell* inext; //The next pointer location


    bool isspell;   //Is Spell Boolean
    bool isweapon;  // Weapon
    bool isarmour; // So on so forth
    bool ismisc; // Misc
    bool offensiveitem; //Offensive item
    bool defensiveitem; // defensive item
    bool passiveitem; // Passive effect

    int damage;
    int armour;
    int magicbonus;
    int magicresistance;
    int cost;


    void item_spellsearch(itemspell* ihead, itemspell* &ipast, itemspell* &icurrent)
    {
        string search;
        if (ihead==NULL)
        {
            cout<<"There are no items on the list to search"<<endl;
        }
        else
        {
            cout<<"Enter the type item you are searching for :"<<endl;
            getline(cin,search);
            icurrent=ihead; //current pointer goes to -> header
            cout<<icurrent<<" "<<search<<" "<<icurrent->itemtype<<endl; 
            while(icurrent!=NULL && search>icurrent->itemname)
            {
                cout<<"Item Type:"<<icurrent->itemtype<<" "<<cout<<icurrent->itemname<<endl;
                ipast=icurrent;  //Past = new current pointer
                icurrent=icurrent->inext; //current pointer = next pointer

            }
        }
    }
public:
    itemspell()//Building a new item // -- Cannot put byref / by values in here remember, needs to be default constructor for some reason ??
    {
        cout<<"Enter Item Type: "<<endl;
        getline(cin,itemtype);
        cout<<"Enter Item Name:  "<<endl;
        getline(cin,itemname);
        cout<<"Enter Item Description: "<<endl;
        getline(cin,itemdesc);
        cout<<"Enter Item Action :"<<endl;
        getline(cin,itemact);
    }

    ~itemspell()//Delete record output
    {
        cout<<"Item being deleted"<<endl;
        Sleep(500);
        cout<<"Item deleted"<<endl;
        getch();
    }


        void additemspell(itemspell* &ihead) // Add record code
        {
            itemspell *icurrent;
            itemspell *ipast;
            itemspell *newitem;

            newitem = new itemspell;  // New itemspell
            if (ihead == NULL || newitem->itemname<ihead->itemname) //If no header or itemname is null;
            {
                newitem->inext = ihead;
                ihead = newitem;
            }
            else
            {
                icurrent= ihead;
                while(icurrent !=NULL&&icurrent->itemname<newitem->itemname) // While the current char Does not equal NULL/"Nothing and charcurrent itemname = newitemitemname"
                {
                    ipast=icurrent;
                    icurrent=icurrent->inext;
                }
                newitem->inext=icurrent; // Sets the next char to current and the past char to next to add in new record.
                ipast->inext=newitem;
            }
        }

        void deleteitemspell(itemspell* &ihead) /// Getting the address of the itemspell not the itemspell itself
        {
            itemspell *ipast=NULL, *icurrent=NULL;
            item_spellsearch(ihead, ipast, icurrent);
            if(ihead!=NULL) 

            if(icurrent==NULL)
                {
                    cout<<"ERROR: No itemspell Found"<<endl;
                    Sleep(500);
                    cout<<"returning to menu... press enter"<<endl;
                    getch();
                }
            else
            {
                if (icurrent == ihead)
                {
                    ihead = ihead->inext;
                }
                else
                {
                    ipast->inext=icurrent->inext; //Resets the pointer and header's back to previous positions....

                    delete icurrent;// Calls the deletion of the itemspell entry.
                    cout<<"itemspell found was deleted press enter to confirm"<<endl;
                    getch();
                }
            }
        }


class character
{
    string forename;
    string surname;
    string nickname;
    string race;
    string alignment;
    string alignment_type;
    string character_class;
    int Strength; //Strength
    int Intelligence; //Magick 2
    int Willpower; //Magick 1
    int Endurance; //Health
    int Agility; //Agility
    int StartingWealth; //StartingWealth       
    character* char_itemp; // Character - Item pointer - Adress location of the characters items
    character* char_next; // Next Pointer Value- Points to the location of the next person in the Dynamic Linked List

What I'm trying to do is when I create a new item, I want to be able to give that item to a character to use.

I know somewhere along the lines of I need to create a pointer value in the character class to point to the itemspell class but I am unsure what to do and could do with some help.

Essentially I want to get the character class to point to the item class when the item class is called from the constructor within the item class.

Please, if you can, don't give just code. Rather, please highlight areas where I should change and give suggestion examples. My degree program is strict about plagiarism.


Pseudo Code

When newitemspell created 
get input charactername ()
: 
if no current itemspell created for that character

  add item to 
 character->charactername
else      
 add item to next pointer character->charactername      


Solution

  • By looking at your code and looking at the descriptor of what you're trying to accomplish, why don't you just create an Inventory class to handle a users items? It should be able to handle 99% of anything you're wanting to do. Let me know if this example is anything like what you're trying to do.

    To be completely honest, I have nary a clue what it is exactly you're trying to do in your code. As a previous user mentioned, "linking" two classes is a simple matter of giving the base class a variable of the required class. For example:

    #include <vector> //I prefer to use vectors for just about any list of objects.
                      //It's just more convenient for me.
    using std::vector;
    
    class Inventory //A handler for all of your character's stuff.
    {
    private:
        vector<object_class> objs; //To actually store an array of whatever objects
                                    //you need to.
    
    //Just some example functions to make the class useful.
    public:
       int MAX = -1; //The size limit for the inventory. This can be used as a useful
                     //statistic in the specific inventory, depending on how it's being
                     //used. My example shows the value at -1, which, at least for me,
                     //means that any maximum size checks being done won't bother it
                     //because I usually have a setting of -1 as being unlimited.
    
       getItem(int slot); //Return item
       removeItem(int slot) //Removing items
       addItem(object_class object) //Adding items
    }
    

    This is just really simple programming from here. All you need to do is create variables with the type of Inventory. Any reference to an object_class is just a generic fill-in for the class type of whatever object you're wanting the Inventory to handle. This will most likely be a base class while you're using derivatives.

    class Character //The character class with all kinds of stuff to needs to be handled
    {
    public:
       Inventory items; //A regular inventory bag for items.
       Inventory equip; //The items the character is currently using.
       Inventory spells; //An alternate use for Inventory to be used as a handler for
                         //spell lists and other cool stuff.
    }
    

    And from here you should be able to understand what exactly is going on. Inventory isn't "linked" to Character. Character has three variables with the type Inventory and the Inventory class itself will handle all of the adding, removing, sorting and retrieving of items in its vector.

    Now you can make everything work like so:

    int main(int argc, char *argv[])
    {
       Character player;
       Armor shield = new Armor(); //A dummy object
       player.items.addItem(shield); //Assuming the Inventory is setup to handle Armor items.
                                    //This will add the shield to the player's inventory.
       player.items.MAX = 10; //Setting the maximum capacity of items to 10, obviously.
       Armor A = player.items.getItem(0); //returns the piece of armor in the first spot in the vector.
    }
    

    I would normally write way more modular code for something like this, such as making Inventory a template class, but I digress. This was just to show you how to attach one class object to another.

    I hope this was remotely like what you were searching for. If not, please try rewriting your question a little more specifically.