Probability of an event occurring when represented as whole numbers in percentage form

Currently, I'm developing a unique job system within a Discord bot that allows users to mine various types of ores. The probability of receiving specific ores is based on the user's mining skill level, which is stored in a database and can vary accordingly. For example, at Skill Level 1, the chances are as follows:

let coal_chance = 80
let copper_chance = 15
let iron_chance = 5
let gold_chance = 0
let diamond_chance = 0
let emerald_chance = 0

Conversely, at Skill Level 2, the distribution changes:

let coal_chance = 50
let copper_chance = 35
let iron_chance = 10
let gold_chance = 5
let diamond_chance = 0
let emerald_chance = 0

This pattern continues for higher skill levels. However, my current dilemma lies in creating a dynamic chance system based on these percentages.

I initially attempted to implement a solution using Math.Random() alongside a series of if statements. Unfortunately, this approach proved inefficient since it required separate conditionals for each skill level. Furthermore, any adjustments made to the ore probabilities within the database would necessitate corresponding alterations to the codebase.

Answer №1

After seeing a suggestion from @sudheeshix, I devised this makeshift solution:

const cumulativeChances = [ 
  {c: 100, i: "coal"},
  {c: 50, i: "copper"},
  {c: 15, i: "iron"},
  {c: 5, i: "gold"},
  {c: 0, i: "emerald"},
  {c: 0, i: "diamond"}
]
const mineOre = () => {
  let rng = Math.random() * 100
  let won = 'coal'
  for (item of cumulativeChances) {
    if (item.c < rng) break
    won = item.i
  }
  return won
}

// Testing if it works as intended
const calculatedChances = {
  coal: 0,
  copper: 0,
  iron: 0,
  gold: 0,
  emerald: 0,
  diamond: 0
}
let tries = i = 10000;
while(i--) {
  let won = mineOre()
  calculatedChances[won] += (1 / tries * 100)
}
console.log(calculatedChances)

While there may be areas for enhancement, this concept offers a starting point. Happy coding :)

Answer №2

Let's explore a different approach:

First, transform your resource values into an array:

resources = ["silver", "bronze", "steel", "titanium", "platinum", "sapphire"];
chances = [70, 10, 15, 5, 0, 0];

Next, calculate cumulative sums of the percentages, following the method described in this response.

const cumulativeSum = (sum => value => sum += value/100)(0);
cum_chances = chances.map(cumulativeSum);

The division by 100 is necessary to obtain float values since Math.random() generates numbers between 0 and 1. Using the chances values above, cum_chances would be [0.7, 0.8, 0.95, 1, 1, 1].

Now, generate a random probability.

random_prob = Math.random();

Then, determine the index of the first element in the array where random_prob fits using the guidance provided in this suggestion.

idx = cum_chances.findIndex(function (el) {
    return el >= random_prob;
});
resource_found = resources[idx];

For instance, if random_prob equals 0.85, this process will yield an index of 2, resulting in resources[idx] returning "steel".

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the usage of multidimensional arrays in React components

How can I extract data such as teamId from the "teams" array using datas.map() method in a multidimensional array? Any tips or help would be appreciated. Is there another way to map out this data? { "gameId": 3226262256, "platformId": "NA1", " ...

How come the back button does not initiate client-side navigation in a Next.js application?

In my Next.js application utilizing GraphQL to fetch articles from a server, I encountered an issue with dynamic routing when reloading the page while on an article and attempting to navigate back. The usual scenario works as expected: Index -> [slu ...

How do I create a sliding dropdown notification bar?

Can anyone provide some guidance on how to create a sliding dropdown section for my homepage, similar to the one on this website: . (Please note, be cautious of potential malware) I'm interested in replicating the dropdown section that says "call for ...

Combining two items from separate arrays

How can I efficiently merge objects that share the same index in two different arrays of objects? Below is the first array const countries = [ { "name": "Sweden", "nativeName": "Sverige" }, ...

Receiving the latest global variable in JavaScript using jQuery

I keep receiving undefined type for: $(".ui-slider-handle").attr("title", '"'+current+'"'); Even though I can successfully alert the updated value of current on line 29, it seems to not be working with .at ...

Utilizing union type return values in Typescript

Looking to incorporate shelljs (via DefinitelyTyped) into my Typescript 1.5-beta project. I want to utilize the exec function with the specified signature: export function exec(command: string, options: ExecOptions): ExecOutputReturnValue | child.ChildPro ...

Is there a way for me to compare a string A1 with a value A2 located in index 0 within an array of values?

In my current task, I am attempting to compare two sets of strings: A1 must match A2 when selected. However, if A1 is chosen along with B1, C1, or D1, the comparison should return false. Similarly, selecting B1 should result in a match with only B2, while ...

Adjusting the background element of a fullpage.js layout during resizing and customization

Is there a way to make the background image responsive on a fullpage.js page, specifically for mobile and tablet devices? How can I ensure that a specific part of the image stays at the center of the page when resizing? For instance, in the provided imag ...

Tips for reducing the amount of repetitive code in your reducers when working with redux and a plain old JavaScript object (

When it comes to writing reducers for Redux, I often encounter challenges. My struggle usually lies in wrapping a lot of my state manipulation in functions like .map and .slice. As the structure of my state object becomes more complex, the reducers become ...

A guide on cropping and uploading images using ejs and Node.JS

Currently I am utilizing JQuery to crop an image. <link href="/public/css/jquery.Jcrop.min.css" rel="stylesheet" type="text/css" /> <!-- add scripts --> <script src="http://code.jquery.com/jquery-1.9.0.js"></script& ...

Implementing Othello Minimax Algorithm in React.js Yields Unsuccessful Results

I need assistance with a recurring issue where the AI player consistently plays the first available move it encounters. My objective was to implement an AI using the Minimax Algorithm, but I'm facing challenges in achieving the desired functionality. ...

The DataTable is encountering difficulties with processing JSON data retrieved from the database

Setting up a datatable on my website has been quite the challenge. I came across a table that I wanted to use here, but converting it to fit my needs has not been successful. Currently, the table is not populating with rows from a database table and I&apos ...

How to incorporate an icon into a React Bootstrap Dropdown menu

I'm struggling to figure out how to include an icon in my react dropdown button, similar to the one shown in the following example. https://i.sstatic.net/cn0b0.png The react bootstrap package I am currently using does not seem to offer a straightfor ...

What is preventing the console from displaying [Object] instead of my information?

Looking to add a meme command to my Discord bot using data stored in a JSON file called memes.json. In my index.js file, I have a variable set up to retrieve the data as follows: const meme = require("./memes.json"). However, when trying to embed the meme ...

Obtain an identifier to be used as dynamic data in an ajax request with jQuery

I am struggling to extract the id from links that trigger the same ajax function. I have over 30 links generated dynamically, as shown below: <a href="javascript:void(0)" id="105">Item 105</a> <a href="javascript:void(0)" id="379">Item 3 ...

Node path response not being properly configured

Just diving into the world of node and typescript and could use a bit of guidance. Currently utilizing node/express/postres as backend and leveraging https://github.com/typeorm/typeorm as an orm, which offers a function to open a connection structured as f ...

Employing ng-repeat within a ui-scope

I'm having trouble getting my ui-view to update dynamically using ng-repeat. I'm not sure if what I want to do is even possible because when I add static objects to intro.html, they display properly. Thank you for any assistance, JS }).st ...

Retrieve data from each URL listed in a JSON array using React

My json file structure was as follows: [ { "name": "google", "route": "/google", "url": "www.google.com" }, { "name": "bing", "route": " ...

Is it possible to increment an integer value in jQuery after obtaining the sum result?

Actually, I'm trying to extract the integer value from my input field. For example, if I enter the value 4+5, I want to display the result as 9 in a separate div. However, instead of getting the expected result, I am receiving [object Object]. I&apo ...

Ways to retrieve the complete user object in passport

Recently, I've been diving into utilizing Express authentication with Passport and React for the frontend. While working on this project, a question came up: How can I access the entire authenticated user object? This is what my database model looks l ...