0

I am learning to code Javascript and I am currently trying this out! I have an object of 'player' and with chestRewards. In the chest, there are some items to be randomly given. How can I add weight to different items in the array so that item 'gold' is not so frequently given out(rare item). I am also confused with the output, it is printing undefined but I don't understand where that is coming from.

const lootBoxA = ['gold', 'silver', 'shirt', 'shorts'];

const player = {

  chestReward: lootBoxA,

    currentReward(){

      while (this.currentReward){
        this.currentReward = this.chestReward[Math.floor(Math.random() * 4)];
        console.log(this.currentReward);

      if (this.currentReward === 'gold'){
        console.log('Bonus!');
      }break;
    }
  }
}
console.log(player.currentReward()); 
/*Outputs 
gold
Bonus!
undefined*/
  • Does this answer your question? [Generate random integers with probabilities](https://stackoverflow.com/questions/8877249/generate-random-integers-with-probabilities) – aerial Dec 23 '21 at 09:07
  • Why are you overriding the method by the value of the reward? They both have the same name. – M0nst3R Dec 23 '21 at 09:18
  • What do you mean by overriding? –  Dec 24 '21 at 03:28

1 Answers1

1

You will need more information than just the name of your items. So, instead of representing your items with string, you can use objects :

const lootBoxA = [
  { name: 'gold', probability: 0.1 },
  { name: 'silver', probability: 0.3 },
  { name: 'shirt', probability: 0.7 },
  { name: 'shorts', probability: 0.5 }
];

That way, you give each item a probability to get picked.

Then, I see no reason why the current reward of your player should be a function (currentReward()). It can just be a property, so you would have something like that :

const player = {
  name: 'Henry',        // for example
  currentReward: null   // the player starts without reward
}

You can have a function to pick a reward for your player. It will take a "lootBox" and pick an item with the right probability :

function pickItemFromLootBox(lootBox) {
  const randomIndex  = Math.floor(Math.random() * lootBox.length);
  const randomNumber = Math.random(); // between 0 and 1
  
  const selectedLootBoxItem = lootBox[randomIndex];

  if (selectedLootBoxItem.probability >= randomNumber) {
    return selectedLootBoxItem;
  } else {
    return null; // no item selected
    // or if you want to always select an item, replace the above line with this : 
    // return pickItemFromLootBox(lootBox);
  }
}

Now that you have a player, a lootBox and a function to pick an item from the lootBox, you can do what you want :

player.currentReward = pickItemFromLootBox(lootBoxA);

if (player.currentReward !== null && player.currentReward.name === 'gold') {
  console.log('Bonus !')
}
boehm_s
  • 5,254
  • 4
  • 30
  • 44
  • Nice solution but the probability check is backwards, it should be `if (selectedLootBoxItem.probability >= randomNumber) {`. – M0nst3R Dec 23 '21 at 09:39
  • Thanks, you're right, it is fixed now :) – boehm_s Dec 23 '21 at 09:52
  • Sure, it's also worth noting that the probabilities are a bit skewed from the values defined, because of the chances to get nothing as a reward. – M0nst3R Dec 23 '21 at 10:03
  • 1
    That's why I've offered to recursively call the `pickItemFromLootBox` function when we get no reward – boehm_s Dec 23 '21 at 10:19
  • Thanks for your help! It looks cleaner but is there a method, I could hide the probability from printing out with the name of the items? For the function 'pickItemFromLootBox(lootBox)', why is the parameter 'lootbox' and not 'lootBoxA'? –  Dec 24 '21 at 04:08
  • If you want to hide the probability, you can either `return selectedLootBoxItem.name` or when you log the item, `console.log(player.currentReward.name)`. The function parameter `lootBox` represents any lootBox that is passed to the function `pickItemFromLootBox` and is a different variable than `lootBoxA`, hence the different name. But it would also work with the same name, just remember that these 2 variables are not the same – boehm_s Dec 24 '21 at 17:16