View Single Post
Old 01-24-2013, 02:40 AM   PM User | #9
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,455
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
Originally Posted by komichi View Post
Here's a basic generator, but right now it's fully random, I want to control the rate of generation via probability.
like the probability of generating common is 60% or the probability of generating sword is 50%
one simple way is to simply build an array of the options, and repeat the items you want to be more common than others:

Code:
// helper function: random slot from array grabber:


// our dice-roll outcomes (some happen more often)
var rarity =[ "common",  "common",  "common",  "uncommon", "rare"];
var weapons =[ "sword",  "sword",  "bow",  "staff "];

// show a random pull using all the list's overlaped probabilities:
alert(  rarity.random() );
now, all things being equal, a sword will hit 50% of the time, bow 25%, and staff 25%, common 60%, uncommon 20%, and rare 20%...

EDIT:
we can indeed calculate many-item probabilities using existing data and a little math. buckle your seatbelt:

Code:
Array.prototype.random=function random(){
  function Rnd(w){return parseInt(Math.random()*(w+1));}
 return this[Rnd(this.length-1)];
};

Array.prototype.counts=function(name){
  var ob={};
  this.forEach(function(a){ ob[a]=ob[a]?(ob[a]+1):(ob[a]=1); });
 return name ? ob[name] : ob;
};



function combinedProb(rareness, weapon){
  return (rarity.counts(rareness) / rarity.length) *
       (weapons.counts(weapon) / weapons.length);
}


var rarity =[ "common",  "common",  "common",  "uncommon", "rare"];
var weapons =[ "sword",  "sword",  "bow",  "staff "];

combinedProb("common", "sword");//0.3
combinedProb("common", "bow");//0.15
combinedProb("rare", "bow");//0.05
in this fashion, we don't have to hand-code numbers or maintain tables of figures, we can just paste item names and let JS to the rest of the work.


edit2:

if you are using it a lot (hundreds of times or more) it might be worth it to pre-calc all the combined probabilities for instant lookup instead of on-demand calculation:
Code:
Array.prototype.counts=function(name){
  var ob={};
  this.forEach(function(a){ ob[a]=ob[a]?(ob[a]+1):(ob[a]=1); });
 return name ? ob[name] : ob;
};

function combinedProb(rareness, weapon){
  return (rarity.counts(rareness) / rarity.length) *
       (weapons.counts(weapon) / weapons.length);
}

var rarity =[ "common",  "common",  "common",  "uncommon", "rare"];
var weapons =[ "sword",  "sword",  "bow",  "staff "];


var combined={}; //the table of combined probs

//populat prob table using all possible combos of rarity and weapons:
rarity.forEach(function(r){
  var x=combined[r]={};
  weapons.forEach(function(w){
     x[w]=combinedProb(r,w);
  });
});

//now, we can use the combined object to instantly lookup combos:

combined.common.sword //0.3
combined.common.bow //0.15
combined.rare.bow //0.05
this not only performs faster, it allows the developer to skip the extra quotes around the names, and avoids the parens, making it more letters than syntax, all in all: a lot less typing on a complex application.
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%

Last edited by rnd me; 01-24-2013 at 03:12 AM..
rnd me is offline   Reply With Quote