1

Here's a more detailed explanation on what I've tried to achieve and what I want to achieve.

This is for my JavaScript game project for opening a shipment of goods.

Depending on the shipment quality, you can get:

  • A different random set of items and
  • a random amount of each item but
  • the combined value of all items has to be between two minimum and maximum values AND
  • I want to add some sort of limitation for the amount of each item where I don't want 85 lemons generated because the value of each lemon is 1

I currently have the following:

Let's say that one of my "shipments" is defined as an object.

let shipment = {
 name: 'common',
 items: ['lemons', 'oranges', 'apples', 'plums'],
 minValue: 170,
 maxValue: 230
}
 

Now, out of this object I want to generate the random amount of items so that their sum of values falls between those two min and max values.

The value of each item is stored in my database but for the sake of this example, let's say that their values are defined in a completely different array:

let values = [5, 6, 2, 10]

The order of the elements in the values array corresponds with the value for each item in the items array.

I also want when the algorithm generates an amount for an item in the items array, its pushed into a new result array:

result.push({name: itemName, amount: itemAmount});

So that after the entire generating of those items is done, each item and its corresponding amount generated is an element(object) in the result array that I can use.

I'm using Node.js.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Torrino
  • 163
  • 13
  • maybe you have a look here for random parts giving a sum: https://stackoverflow.com/questions/50405397/split-number-into-4-random-numbers/50405632#50405632 (look to the comments part) do you accept zero values? do you like to get an equal distribution? – Nina Scholz Oct 09 '20 at 10:40

1 Answers1

0

You can generate a random number in that range, then generate 4 weight values to divide that number into 4 unequal parts, here is an example:

let shipment = {
 name: 'common',
 items: ['lemons', 'oranges', 'apples', 'plums'],
 minValue: 170,
 maxValue: 230
};


function randomNumberInRange(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

const totalQuantity = randomNumberInRange(shipment.minValue, shipment.maxValue);

const weight1 = randomNumberInRange(1, 97); // 97 is used to make sure the remaining 3 weight can be at least 1
const weight2 = randomNumberInRange(1, 98 - weight1);
const weight3 = randomNumberInRange(1, 99 - (weight1 + weight2));


const quantities = [weight1, weight2, weight3]
  .map((v) => (v / 100))
  .map((v) => Math.floor(totalQuantity * v));

quantities.push(totalQuantity - quantities.reduce((a, c) => (a + c))); // set the 4th weight to be equal to the remaining quantity

shipment.items = shipment.items.map((name, index) => ({ name, quantity: quantities[index] }))

console.log(shipment);

The 4 generated values are not that random, the first one will tend to be bigger than the rest, the second one will tend to be smaller than the first but bigger than the third and forth and so on.

Titus
  • 22,031
  • 1
  • 23
  • 33
  • I'm not sure if this gives me the answer I need. If I understood this correctly, this code generates an array of `items` and the sum of their quantity is that number between min and max value. But each element in the items array already has a value thats not 1 and I need the sum of those values to be between min and max. – Torrino Oct 09 '20 at 18:50