array, map, multimap??? which to use

Hi,I'm trying to create a text rpg based loosely on the original Bardstale/Wizardy series games of the eighties(for learning c++).I've been stuck in one aspect for quite some time now.

GOAL: What I want to do is take the player's initiative rolls and compare them to the enemy's rolls to determine who goes first. The player can have up to six characters(goodguys) and confront up to 15 badguys.

EXAMPLE:
From this.......................to this...................then to this

Name init(d20).................sorted High to Low..........Next action for each

Jobe=15.........................Rudy=18.....................Rudy { do something}
Henry=7.........................Badguy3=17...............Badguy3{do something}
Storm=10.......................Jobe=15.....................Jobe {do something}
Rudy=18............->.........Badguy1=14..........->.etc.. etc...
Charlie=11.....................Charlie=11
Badguy1=14..................Storm=10
Badguy2=9....................Badguy2=9
Badguy3=17..................Henry=7

the code I do have for this part is terrible and might be painful for others to see. I hope someone will turn me in the right direction...Thank you
Last edited on
If each goodguy and badguy and have an unique name you can use a map with string as key type. That would be the easiest thing.
If two (or more) can have the same name, you should use a multimap.
So map<Key,Value> allows you to easily sort by Value, but requires that all Keys are unique.
multimap<Key, Value> is the same, except Keys do not have to be unique.

boost::multi_index_container<Struct> is even more general, in that Struct can contain any number
of elements (for example Name and Roll) and can trivially sort by any or all of the elements. You
could, for example, sort it by Name AND Roll. This might be what you want if you also want to
be able to sort by Name.

How do you sort a map by value? I thought that this can only be done by the key. Since you are learning C++ and working on your own project I'd strongly recommend downloading the boost libraries if you haven't already. You'll have access to much more advanced capabilities. If you can't use boost for whatever reason, I would think that you'd be better off with an array of structures or classes. Is each character in the game implemented as a class or struct with properties? If so, I'd think that you would be be sorting an array or list of classes using customized predicate functions so that you can resort using different criteria.
Last edited on
Oh, sorry, yes, I meant sort by Key.

Thanks for the reply all, I'm unfamiliar with the boost libraries but I will look into it. Each character in the game is represented as an object and put into an array for the purpose of determining initiative.

Goodguys/Badguys come from a common character class.

I admit some of the terminology and advanced features in C++ are still Japanese to me...

this is the function I have so far... doesn't work correctly I know.. The test zone below only determines whether or not the first player in the array go's first and that is all I could do.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

void PlayerGoesFirst(CPlayer &badguy)  // determines who has the first attack
{
    badguy.SetInit();//  sets one enemy's inititive . multiple enemies have not been implemented yet.
    int intNumOfPlayers = 0;
    intNumOfPlayers = HowManyPlayers(); // check to see how many player characters are playing at the moment- could be one player, could be up to 7 players.
    int compareArray[7];// get each players initiative and save the values in compareArray

    cout << " intNumOfPlayers =" << intNumOfPlayers << endl;_getch();
       cout << "" << endl;

  // below is a for loop that adds each player's(hero) init roll to a separate array that will be used to sort the values from low to high then from high to low

    for (int i = 0; i < intNumOfPlayers; i++)  
        {
            hero[i].SetInit(); // sets player's inititive
            compareArray[i] = hero[i].GetInit(); // use compareArray to see which init is higher
           // cout << hero[i].GetName() << " Init: " << hero[i].GetInit() << endl; //Get each init
        }



        //----------testing this code below to see how the stl sort function works----------

        cout << "intNumOfPlayers = " << intNumOfPlayers << endl;// this confirms the number of players after the loop, not sure if necessary

        cout << "\n" << badguy.GetName() << "'s Init: " << badguy.GetInit() << endl << endl;

        sort(compareArray, compareArray + (intNumOfPlayers)); // sorts each players initiative from low to high
        reverse (compareArray,compareArray + (intNumOfPlayers));// reverses the low to high from sort()- to high to low



        for (int i = 0; i < intNumOfPlayers; i++) // show contents of compareArray-new list of players init's from highest to lowest-
        {
           cout << "compareArray " << i << " = " << compareArray[i] << "   " << hero[i].GetName() << " Init: " << hero[i].GetInit() << endl;



        }
        cout << "PAUSE " << endl;_getch();


        //--------------------------test zone-----------------------

        if (badguy.GetInit() > hero[0].GetInit())
            {Combat(badguy,hero[Dice(intNumOfPlayers)-1]);} // this algorithm sucks, basically if the badguy's initiative
// is higher than player 1's initiative, then badguy starts its combat sequence

// so this is the part Im stuck on, how do I get the enemy's init/s to compare with all of my 
//player's inits not just the first player in the array? 
       //----------------------------------------------------------------------------------------------------------------------- 


The problem with this approach should it work flawlessly is once I sort the values (init) for each character and badguy I lose the value's needed correlation with the each character name....

eg.. Jobe = 15 ends with Jobe = something else....which obviously won't work since I need to retain each character value even after it sorts.. Hope this makes sense
Last edited on
You should be able to

sort( hero.begin(), hero.end(), std::greater<character>() );

provided that

hero is a std::vector<> and your character class has an operator< defined.

The above line would then replace your lines 12-30.
Thanks jsmith, that would help condense a lot of unnecessary code.

Perhaps the best way is for me to solve this is to ask the question? how would you (asking anyone and everyone) solve this problem without looking at my mess of code (in relation to my first post)...
Last edited on
Topic archived. No new replies allowed.