0

I am trying to find a way to import stat data into a game in progress Via spread sheets? Here's what I am working with:

Right now for example.. The spells, in order to name them, set stats, ect and be able to call them via Number I Have something like this going on in the actual code:

    void spell(int & eMoney, int eSpell[10])
{
    using namespace std;
    char spellname[10][25] = {"Minor Heal", "Fire Shard", "Lightening Shard", "Ice Shard", "Magic Barrier", "Essence Of Life", 
"Earth Shard", "Wind Shard", "Insigma", "Weaken"};
    int spellcost[10] = {50, 80, 80, 80, 100, 100, 80, 80, 120, 80};

Which is all fine and dandy, it works... But it's an issue now and later.. I want to be able to use a spread sheet, like a CSV file, so I can have a spread sheet for like just spells, just swords, just clubs... I plan to have a very large selection, it's more ideal to be able to edit a single file in columns and rows and have the actual game pull the information from an external file when it's needed... But I am not able to figure out how to go about this? I am open to any ideas..

Here is an example of how I call on a spell's info now:

case 2:
            do
            {
                cout << "Which spell would you like to cast?\n\n";
                for(x=0;x<10;x++)
                    cout << x+1 << ". " << spellname[x] << ": " << eSpell[x] << " left" << endl;
                cout << "11. Leave\n\n>> ";
                cin >> decision;
                system("cls");
            }
            while((decision<1)&&(decision>11)||(eSpell[decision-1]==0));
            switch(decision)

and here is an example of the spread sheet I have in mind basically? Starting at A1:

Type        sName   mDmg    sPrice
Spell   1   Minor Heal  10  100
Spell   2   Fire Shard  12  100
Spell   3   Lightening Shard    12  200
Spell   4   Ice Shard   12  150
Spell   5   Magic Barrier   10  130
Spell   6   Essence Of Life 15  10
Spell   7   Earth Shard 12  120
Spell   8   Wind Shard  12  230
Spell   9   Insigma 12  90
Spell   10  Weaken  12  100

Another Example:

Current Code:

char monsters[16][25] = {"Wolf", "Bear", "Bandit", "Traveler", "Gargoyle", "Knight", "Warlock", "Mammoth", "Cyclops", "Unicorn", "Dragon", "Your Mother", "Demon", "Jesus", "Satan", "God"};
    //monster strengths
    int monsterdamagemax[16] = {32, 42, 53, 53, 65, 65, 75, 75, 85, 85, 90, 90, 95, 95, 110, 110};
    int monsterdamagemin[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    int monsterdefensemax[16] = {2, 7, 13, 13, 20, 20, 25, 25, 35, 35, 40, 40, 45, 45, 55, 55};
    int monsterdefensemin[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    int monsterhealth[16] = {32, 52, 73, 73, 95, 95, 118, 118, 142, 142, 167, 167, 193, 193, 220, 220};
    int monsterspeed[16] = {7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
    int monstergold[16] = {20, 30, 41, 41, 53, 53, 66, 66, 80, 80, 95, 95, 110, 110, 125, 125};

Ideally, I want to be able to get all that from a CSV file like:

mID mName   mDmgMax mDmgMin mDefMax mDefMin mHp mSpeed  mGold
1   Wolf    32  0   2   0   32  7   20
2   Bear    42  0   7   0   52  8   30
3   Bandit  53  0   13  0   73  9   41
4   Traveler    53  0   13  0   73  9   41
5   Gargoyle    65  0   20  0   95  10  53
6   Knight  65  0   20  0   95  10  53
7   Warlock 75  0   25  0   118 11  66
8   Mammoth 75  0   25  0   118 11  66
9   Cyclops 85  0   35  0   142 12  80
10  Unicorn 85  0   35  0   142 12  80
11  Dragon  90  0   40  0   167 13  95
12  Your Mother 90  0   40  0   167 13  95
13  Demon   95  0   45  0   193 14  110
14  Jesus   95  0   45  0   193 14  110
15  Statan  110 0   55  0   220 15  125
16  God 110 0   55  0   220 15  125
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Leaum
  • 1
  • 1
  • How about making a file with information you need and reading from it? – lapk Dec 23 '11 at 04:40
  • @AzzA That's the idea, but I can't get the actual game to read the information from the file correctly =\ – Leaum Dec 23 '11 at 04:41
  • Take a look at C++ file streams at http://www.cplusplus.com/reference/iostream/fstream/, for example. They have mini examples for most functions to get you started. Basically, if you have never tried to read/write from a file, you'll need to do some practicing how to read formatted data and how to extract information from it. It's not hard at all, you just need to try it to see how it works, which functions are useful etc. – lapk Dec 23 '11 at 04:47
  • One of your "mName" has space in it. Thus it would be better to use some other delimiter – Vinayak Garg Dec 23 '11 at 13:54

4 Answers4

1

How about writing a small command based application that creates records for you, and in your "main" program that is game, you just have to read these records.

A sample structure -

struct monster
{
  int mID;
  char mName[25]; //from your code
  int mDmgMax;
  //and these as well mDmgMin mDefMax mDefMin mHp mSpeed  mGold
};

in this "helper" program read each data item (like the mName) in a record one by one, and insert in this structure. Write the structure to monsters.dat file

std::ofstream fout;
fout.open("monsters.dat", std::ios::app | std::ios::binary);    
fout.write( (char*) &monsterInstance, sizeof(monsterInstance) );
fout.close();

This will simply append records. (I have skipped error checking and reading data.) For greater ease, this program should be able to show current monsters, add monster, delete monster (by entering mID).

Reading such records in your main program should be a easy task.

Vinayak Garg
  • 6,518
  • 10
  • 53
  • 80
0

If you're going to have a lot of table-based data to keep around, you might look into using SQLite. It has some interesting costs and benefits.

On the down side (maybe), it's SQL. It can be a bit more complex and depending on your searching algorithm, could be slower. It also can't be edited by hand, you need something to open the database (there are free tools available).

On the up side, you get all the sorting and filtering power of a database (anything you'll need, like spell='fireball' AND damage < 5), and SQLite is fast (easily enough to store game data in, and very possibly faster than your own code). You can store all your data in a single file for easy deployment or modding, with unique tables for each type (weapons, spells, characters, etc), and no server involved (SQLite is a single DLL).

Relational databases excel at working with consistently-formed tables of data, which is exactly what you have in a game environment (each object type has a few fields, not much variation, maybe some blanks, with various data types). SQLite, despite being the smallest database, can handle thousands of rows with excellent time, so you won't have to worry about your game data becoming unwieldy (which happens very quickly with pure text table files, like NWN(2)'s 2DA format).

There is a learning curve to it, but you do gain some simplicity in the future (adding a new object type is a new table and queries, not a whole lot of code) and a very stable data format and load/save library. Depending on your needs, it may be worth a shot.

ssube
  • 47,010
  • 7
  • 103
  • 140
0

As pointed in question comments, you should go for <fstream> if you really want to deal with CSV files. Using that approach, getline should be enough for what you need.

This thread in C++.com and this question should point you some directions on how to handle CSV.

Community
  • 1
  • 1
Alexandre
  • 1,245
  • 1
  • 13
  • 22
0

I use Boost to parse the CSV files I work with. Here's a simple example.

I agree with peachykeen though, SQLite may suit you better, but maybe this will help you get started.

#include <iostream>
#include <fstream>
#include <vector>

#include <boost/tokenizer.hpp>
#include <boost/token_functions.hpp>

typedef std::vector<std::string> csvLine;
typedef std::vector<csvLine> csvLines;
typedef boost::tokenizer<boost::escaped_list_separator<char> > csvTokenizer;

csvLines ReadCSVFile(const std::string& fileName)
{
    csvLines retVec;
    std::ifstream inFile(fileName.c_str());
    if(inFile)
    {
        std::string fileLine;
        while(std::getline(inFile, fileLine))
        {
            csvTokenizer lineTokens(fileLine);
            retVec.push_back(csvLine(lineTokens.begin(), lineTokens.end()));
        }
        inFile.close();
    }
    return retVec;
}

int main(int argc, char** argv) 
{
    csvLines lines(ReadCSVFile(argv[1]));
    for(csvLines::iterator lineIt = lines.begin(); lineIt != lines.end(); ++lineIt)
    {
        for(csvLine::iterator tokenIt = (*lineIt).begin(); tokenIt != (*lineIt).end(); ++tokenIt)
        {
            std::cout << *tokenIt << " ";
        }
        std::cout << std::endl;
    }
    return 0;
}
Retired Ninja
  • 4,785
  • 3
  • 25
  • 35