0

So I want there to be a lower chance that the randomly generated number is between 0 to 20 or between 75 to 90 but a higher chance that the number is between 20 and 75 current randomizing code.

I have tried numerous types of things but I can't seem to figure it out.

The math for generating the number

function doDamage(attacker, reciever, channel, attack) {

      let healthbothusers = 100

      const healing = testing === false ? Math.floor(healthbothusers = Math.random() * 80) : 100
      const damage = testing === false ? Math.floor(healthbothusers = Math.random() * 90) : 100

      let recieverHealth = usersHealth.get(reciever)
      let attackerHealth = usersHealth.get(attacker)

      let newHealth = recieverHealth - damage

      let beenhealed = attackerHealth + healing

This is my first ever stack post so I hope it's done properly ;)

Adriano
  • 3,788
  • 5
  • 32
  • 53
Faint
  • 11
  • 2
  • This is similar: https://stackoverflow.com/questions/8435183/generate-a-weighted-random-number – Stefan Mar 15 '21 at 22:49
  • alright i'll look at it ty ! – Faint Mar 15 '21 at 22:53
  • I like to create an array of possible outcomes, then randomly draw from that instead of thin air. To weigh, simply repeat some of the array items that you want to occur more frequently, ex: pulling from `[1,1,2,3]` lets 1 come up twice as often as 2 or 3. – dandavis Mar 15 '21 at 22:54
  • 1
    Well, certainly your game mechanics are up to you and the game your are trying to make, but I would argue that sampling through essentially three uniform distributions with "hard" bounds is somewhat arbitrary. So 21, 74 and 45 all have the same likelihood, but 20 and 75 don't. It seems strange. Arguably, a gaussian distribution centered at 45 would give you more natural damage values. Of course you would have to clip it and plot a couple of bar graphs to get the variance as you would like. – kyriakosSt Mar 15 '21 at 23:53
  • i thought about the damage values for a while but i also have healing so thats why i ended up using these values – Faint Mar 16 '21 at 00:05
  • have you considered using a Gausiian function? See here: https://stackoverflow.com/questions/25582882/javascript-math-random-normal-distribution-gaussian-bell-curve/36481059#36481059. If you change the last line in that function to `return 45 * Math.cos( Math.PI * v ) + 45;` then you can achieve a more "fluid" result than the OP called for. it might not fit your use case, or it might fit it better than you wanted. Edit: I see someone else mentioned Gaussian. I upvoted. – Peaceful James Mar 16 '21 at 00:46
  • What do you mean by specific %? Currently `0-19` and `76-90` take up approximately `38%` while `20-75` takes up approximately `62%` of `0-90`. – StackSlave Mar 16 '21 at 02:26

2 Answers2

1

Do Math.random twice - first time to determine which block of results you want (the wings, or the more common central range), then do it again to work out the random result from within that block.
Therefore, you can control how frequently the wings come up. This halves the chances of each wing coming up, compared to natural distribution:

let r=Math.random()
if (r<0.1) { // Giving 0-20 only a 10% chance of occurring
 r=Math.floor(Math.random() * 20)
} else if (r>0.92){  // Giving 75-90 only a 8% chance of occurring
 r=75+Math.floor(Math.random() * 15)
} else { //Giving central range the remainder chance (82%) 
 r=20+Math.floor(Math.random() * 55) //Range goes from 20 to 75
}
Adriano
  • 3,788
  • 5
  • 32
  • 53
Vexen Crabtree
  • 339
  • 3
  • 16
0

Math.floor(Math.random()*100)+1 should give you percents between 1 and 100. As long as that random percent is > 100-yourPercent it should be approximately the correct percent of the time. Check this out:

//<![CDATA[
/* js/external.js */
let doc, htm, bod, nav, M, I, mobile, S, Q, Hopeful; // for reuse on other loads
addEventListener('load', ()=>{
doc = document; htm = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
mobile = nav.userAgent.match(/Mobi/i) ? true : false;
S = (selector, within)=>{
  let w = within || doc;
  return w.querySelector(selector);
}
Q = (selector, within)=>{
  let w = within || doc;
  return w.querySelectorAll(selector);
}
Hopeful = function(percent){
  this.percent = percent;
  this.chanceIt = ()=>{
    const p = this.percent;
    return Math.floor(Math.random()*100)+1 > 100-this.percent;
  }
}
// small Library above for reuse - magic below can be put on another page using a load Event *(except // end load line and below)*
const fifty = new Hopeful(50), twentyFive = new Hopeful(25), one = new Hopeful(1);
const seventyFive = new Hopeful(75), oneHundred = new Hopeful(100), zero = new Hopeful(0);
function test(){ // approximates showing proof of concept
  let zeroN = 0, fiftyN = 0, twentyFiveN = 0, oneN = 0, seventyFiveN = 0, oneHundredN = 0;
  for(let i=0,l=100; i<l; i++){
    if(zero.chanceIt())zeroN++;
    if(one.chanceIt())oneN++;
    if(twentyFive.chanceIt())twentyFiveN++;
    if(fifty.chanceIt())fiftyN++;
    if(seventyFive.chanceIt())seventyFiveN++;
    if(oneHundred.chanceIt())oneHundredN++;
  }
  console.clear();
  console.log('zero', zeroN); 
  console.log('one', oneN); 
  console.log('twentyFive', twentyFiveN);
  console.log('fifty', fiftyN);
  console.log('seventyFive', seventyFiveN);
  console.log('oneHundred', oneHundredN);
}
const chance = I('chance');
test(); chance.onclick = test;
}); // end load
//]]>
/* css/external.css */
*{ /* font size may affect white space line breaks - set individually */
  box-sizing:border-box; font:0; padding:0; margin:0;
}
html,body,.full{
  width:100%; height:100%;
}
.full{
  background:#ccc; padding:7px;
}
button{
  cursor:pointer; width:100%; background:linear-gradient(#1b7bbb,#147); color:#fff; font:bold 28px Tahoma, Geneva, sans-serif; padding:5px 10px; border:1px solid #007; border-radius:10px;
}
<!DOCTYPE html>
<html lang='en'>
  <head>
    <meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
    <title>Title Here</title>
    <link type='text/css' rel='stylesheet' href='css/external.css' />
    <script src='js/external.js'></script>
  </head>
<body>
  <div class='full'>
    <button id='chance'>chance it</button>
  </div>
</body>
</html>

This design allow you to give a percent chance to anything.

StackSlave
  • 10,613
  • 2
  • 18
  • 35
  • I don't understand what you've done here. I'm sure it will work, but it seems to me you've been addressing too many problems outside the scope and thus I get lost in what would be relevant for the OP and what was an addition to solve other problems. – Adriano Mar 16 '21 at 01:41