RuneHive-Game
Loading...
Searching...
No Matches
Chance.java
Go to the documentation of this file.
1package com.runehive.util.chance;
2
3import com.runehive.game.world.items.Item;
4
5import java.util.LinkedList;
6import java.util.List;
7
8/**
9 * Handles a random chance.
10 *
11 * @param <T> - The representation type.
12 * @author Michael | Chex
13 */
14public class Chance<T> {
15
16 public enum ChanceType {
17 ALWAYS(100),
18 COMMON(100),
20 RARE(.6),
22
23 private final double weight;
24
26 this.weight = weight;
27 }
28
29 public double getWeight() {
30 return weight;
31 }
32 }
33
34 /** The list of weighted object. */
35 private final List<WeightedObject<T>> objects;
36
37 /** The sum of the weights. */
38 private double sum;
39
40 /** Creates a new instance of the class. */
42 this.objects = objects;
43 sum = objects.stream().mapToDouble(WeightedObject::getWeight).sum();
44 objects.sort((first, second) -> (int) Math.signum(second.getWeight() - first.getWeight()));
45 }
46
47 /** Creates a new instance of the class. */
48 public Chance() {
49 this.objects = new LinkedList<>();
50 sum = 0;
51 }
52
53 /** Adds a new {@code WeightedObject} to the {@code #object} list. */
54 public final void add(double weight, T t) {
55 objects.add(new WeightedChance<>(weight, t));
56 sum += weight;
57 objects.sort((first, second) -> (int) Math.signum(second.getWeight() - first.getWeight()));
58 }
59
60 /** Adds a new {@code WeightedObject} to the {@code #object} list. */
61 public final void add(ChanceType type, T t) {
62 add(type.getWeight(), t);
63 }
64
65 /** Generates a {@code WeightedObject}. */
66 public T next() {
67 double rnd = Math.random() * sum;
68 double hit = 0;
69
70 for (WeightedObject<T> obj : objects) {
71 hit += obj.getWeight();
72
73 if (hit >= rnd) {
74 return obj.get();
75 }
76 }
77
78 throw new AssertionError("The random number [" + rnd + "] is too large!");
79 }
80
81 /** Generates a {@code WeightedObject}. */
82 public WeightedObject<T> next(double boost) {
83 if (boost <= 0 || boost > 1) {
84 throw new IllegalArgumentException("Boost is outside of the domain: (0, 1]");
85 }
86
87 double rnd = Math.random() * sum;
88 double hit = 0;
89
90 for (WeightedObject<T> obj : objects) {
91 hit += obj.getWeight() + boost;
92
93 if ((int) (hit * (1 + boost)) >= (int) rnd) {
94 return obj;
95 }
96 }
97
98 throw new AssertionError("The random number [" + rnd + "] is too large!");
99 }
100
101 public Item[] toItemArray() {
102 int count = 0;
103 Item[] array = new Item[objects.size()];
104 for (WeightedObject<T> obj : objects) {
105 array[count] = (Item) obj.get();
106 count++;
107 }
108 return array;
109 }
110
111 @Override
112 public String toString() {
113 return objects.toString();
114 }
115
116}
The container class that represents an item that can be interacted with.
Definition Item.java:21
double sum
The sum of the weights.
Definition Chance.java:38
final void add(double weight, T t)
Adds a new WeightedObject to the #object list.
Definition Chance.java:54
Chance()
Creates a new instance of the class.
Definition Chance.java:48
final void add(ChanceType type, T t)
Adds a new WeightedObject to the #object list.
Definition Chance.java:61
WeightedObject< T > next(double boost)
Generates a WeightedObject.
Definition Chance.java:82
T next()
Generates a WeightedObject.
Definition Chance.java:66
Chance(List< WeightedObject< T > > objects)
Creates a new instance of the class.
Definition Chance.java:41
final List< WeightedObject< T > > objects
The list of weighted object.
Definition Chance.java:35
Represents a weighted object.
double getWeight()
Gets the object's weight.