Rand result equals an object

I'm trying to re-create the 'opening of a chest' to find a random item inside (which itself is an object of a class).

In this example, I would have my rand find a number from 1 to 4.

1
2
3
4
    theClass objectA(1, stringHere);
    theClass objectB(2, stringHere);
    theClass objectC(3, stringHere);
    theClass objectD(4, stringHere);


If the rand result was 3, I'd want stringHere for objectC to be printed.

I could do a bunch of if..else statements (if randResult == 1..) or a switch, but it would be better if I could tie everything in together. Thanks in advance.
If every result has a different item, you could do this with a lookup table.

Also do you need just a string? Or does 'theClass' have any other important meaning?

Here's an example of how you could do it with just strings:

1
2
3
4
5
6
7
8
9
10
11
12
string GetRandomItem()
{
  static const string items[] = {
    "item 1",
    "item 2",
    "item 3",
    "item 4"
    };
  static const unsigned itemcount = arraysize(items);  // itemcount=4

  return items[rand() % itemcount];
}
The string of the object would be printed, but the object also has at least 5 other integer variables.

int ID (if there are 57 items and this is the 31st, this would be 31)
int speed
int .. (other stats)
int tier
string name

The object is essentially 'obtained', but only the name is printed and the object is chosen according to the int ID variable.
Okay then.. same idea just initialize your lookup table differently:

1
2
3
4
5
  static YourItemClass items[] = {
    YourItemClass(0,whatever,"item 1"),
    YourItemClass(1,whatever,"item 2"),
 //   etc
    };


Of course storing the ID in the actual item is a little redundant and probably shouldn't be necessary.
You could still do this with a lookup table the array index would take the place of your "theClass::ID" member and the returned value could be the location of the item on the lookup table (which I have a feeling might be better if made as a Global constant).

EDIT: So untested psuedo-code:
1
2
3
4
5
6
7
/*Global Space*/
const theClass ITEMS[] = {/*Code depends on your constructor*/};

int GetRandomThing()
{
    return (rand() % Some_Limit); /*So this version just returns the index number of the item*/
}
Last edited on
It's also worth mentioning that this approach sucks if you want some items to be generated more frequently than others.
So I should put my objects into an array and draw them that way?

I don't know if this is relevant, but I already made a program for a tiered loot table, only that uses a big bunch of strings. I'm trying to merge this class idea with that table. So yeah, I need to get this to work with the following code:

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
    bool loopAgain = true;
    int lootLevel = 1, loot, rollResult, rollChange = 3;

    int counter = 1;

    while(loopAgain)
    {
        rollResult = rollDie();

        cout << "Roll " << counter << ": " << rollResult << ".\n";

        if(lootLevel == 3 && chooseJob == 2) {
            if(rollResult >= 2 && rollResult <= rollChange) {
                cout << "Loot Tier: " << lootLevel << ".\n\n";
                break;
            } else if((rollResult > rollChange && rollResult < 7) || rollResult == 1) {
                lootLevel++;
            }
        } else if(rollResult >= 1 && rollResult <= rollChange) {
            cout << "Loot Tier: " << lootLevel << ".\n\n";
            break;
        } else if(rollResult > rollChange && rollResult < 7) {
            lootLevel++;
        }

        if(lootLevel == 4) {
            cout << "Loot Tier: " << lootLevel << ".\n\n";
            break;
        }

        rollChange++;
        counter++;
    }


This basically translates to (using a 1-6 die):

Roll 1: 1-3 gets Tier 1, 4-6 move up a tier
Roll 2: 1-4 gets Tier 2, 5-6 move up a tier
Roll 3: 1-5 gets Tier 3, 6-6 gets Tier 4 (top)
IF PLAYER IS A ROGUE
Roll 3: 2-5 gets Tier 3, 1or6 gets Tier 4 (top)

The output of that gives a Tier level, then I just have a rand function which chooses an item form that tier. That brings us to this problem, instead if getting a random string after that, I want a random object from the tier. The array idea will still work, right?
Although it may seem like a simple chart to look at at first, that's actually pretty complex to code and it would pretty much always be a mess.

My attempt at Untested-Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*Assuming That All Class Members Called Are Present And Public*/
void Function(PlayerClass* Player)
{
     int TierMod = 2 + Player->Loot_Tier;

     if(rollDice() <= TierMod) /*Assuming that "rollDice()" Always returns at least 1*/
     {
         std::cout << Player->Name << " Gets Tier " << Player->Loot_Tier << " Treasure\n";
         return;
      }
      else
      {
          std::cout << Player->Name << " Upgrades Their Tier!!!\n";
          Player->Loot_Tier++;
          Function(Player);
          return;
       }
}
So in this approach, is TierMod 2 because Loot_Tier is currently 1, making this "if you roll <= 2 + 1 (so form 1-3) you get Loot_Tier 1. Else, Loot_Tier++ (so it's now 2 + 2 meaning 1-4) then recursion by calling itself?

It seems like a much neater approach, but I wasn't confident about using recursion yet. It'd be great if someone could explain the parts I haven't understood from the above text.
Sorry I didn't respond right away, family outing this weekend.

Don't worry about using recursion in this scenario. It's a scary word but it only means something calling itself over and over, in this case it's simply so that we don't have to write the same code over and over.

There are issues with this example, the most obvious one is that it doesn't check for a "cap" on the Loot_Teir, it also does not take into account the exception you have for the "Rouge". These, amoung others, are all things you can write in yourself so I didn't include them in my example.

Which parts did you need cleared up? I think I covered the recursion part.
Topic archived. No new replies allowed.