(Edited: to include also weapon type as per follow-up question Random number to print array (Swift))
As above, use the arc4random
function. A more complete "Monster" example follows.
It could be appropriate to hold different rarity and weapon types as enum
cases
enum Rarities {
case Normal
case Rare
case Legendary
}
enum Weapons {
case Knife
case Sword
case Katana
}
Each monster could be an instance of a Monster
class with it's own specific item and rarity drop rates, initialized when creating the Monster
object.
class Monster {
var name : String
var dropRatesRarity = [Rarities:Double]()
var dropRatesWeapons = [Weapons:Double]()
init(name: String, dropRatesRarity: [Rarities:Double], dropRatesWeapons: [Weapons:Double]) {
self.name = name
var rateSum = dropRatesRarity.values.reduce(0.0, combine: +)
var dropRatesCumSum = 0.0
for (k, v) in dropRatesRarity {
self.dropRatesRarity[k] = v/rateSum + dropRatesCumSum
dropRatesCumSum += v/rateSum
}
rateSum = dropRatesWeapons.values.reduce(0.0, combine: +)
dropRatesCumSum = 0.0
for (k, v) in dropRatesWeapons {
self.dropRatesWeapons[k] = v/rateSum + dropRatesCumSum
dropRatesCumSum += v/rateSum
}
}
func dropItem() -> (Weapons,Rarities) {
return (generateItemType(), generateRarity())
}
func generateRarity() -> Rarities {
let random = Double(Float(arc4random()) / Float(UINT32_MAX))
return dropRatesRarity.filter({ (k, v) in v >= random }).minElement({ $0.1 < $1.1 })?.0 ?? .Normal
}
func generateItemType() -> Weapons {
let random = Double(Float(arc4random()) / Float(UINT32_MAX))
return dropRatesWeapons.filter({ (k, v) in v >= random }).minElement({ $0.1 < $1.1 })?.0 ?? .Knife
}
}
Example for some Monster
instance:
/* Example */
var myDropRatesRarity = [Rarities:Double]()
myDropRatesRarity[.Normal] = 73 // relative drop rates, needn't sum to 100
myDropRatesRarity[.Rare] = 25
myDropRatesRarity[.Legendary] = 2
var myDropRatesWeapons = [Weapons:Double]()
myDropRatesWeapons[.Knife] = 50
myDropRatesWeapons[.Sword] = 30
myDropRatesWeapons[.Katana] = 20
var myMonster = Monster(name: "Godzilla", dropRatesRarity: myDropRatesRarity, dropRatesWeapons: myDropRatesWeapons)
var myItem = myMonster.dropItem()
print(myMonster.name + " dropped a \(myItem.0) of \(myItem.1) rarity!")
/* "Godzilla dropped a Katana of Normal rarity!" */
/* ... most likely Normal rarity ... keep grinding! */