Completed
Push — trunk ( 0d0bfe...e6cc80 )
by SuperNova.WS
03:47
created

OutcomeManager::remove()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 4
ccs 0
cts 4
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Created by Gorlum 17.02.2018 23:55
4
 */
5
6
namespace Common;
7
8
/**
9
 * Class OutcomeManager
10
 *
11
 * Manage outcomes for a bunch of random cases
12
 *
13
 * @package Common
14
 */
15
class OutcomeManager implements \Countable {
16
17
  /**
18
   * Possible outcomes
19
   *
20
   * @var array $outcomes
21
   */
22
  protected $outcomes = [];
23
24
  /**
25
   * Chances for outcome to roll
26
   *
27
   * @var int[] $chances
28
   */
29
  protected $chances = [];
30
31
32
  public function __construct() {
33
  }
34
35
  /**
36
   * Roll element from predefined array
37
   *
38
   * @param iterable $iterable - [P_CHANCE => (int), ...(payload)]
39
   *
40
   * @return mixed|null
41
   */
42
  public static function rollArray($iterable) {
43
    $manager = new static();
44
    if (!is_iterable($iterable) || empty($iterable)) {
45
      return null;
46
    }
47
48
    foreach ($iterable as $element) {
49
      if (!is_array($element) || empty($element[P_CHANCE])) {
50
        continue;
51
      }
52
      $manager->add($element, $element[P_CHANCE]);
53
    }
54
55
    return $manager->rollOutcome();
56
  }
57
58
  /**
59
   * Adds outcome to internal array
60
   *
61
   * @param mixed $outcome - Outcome which can be selected
62
   * @param int   $chance  - Chance of this particular outcome. Should be integer. Sum of all chances can be above mt_getrandmax()
63
   */
64
  public function add($outcome, $chance) {
65
    $this->outcomes[] = $outcome;
66
    $this->chances[] = $chance;
67
  }
68
69
  /**
70
   * Removed outcome from list
71
   *
72
   * @param mixed     $outcome - Outcome to be removed
73
   * @param bool|null $strict  - Strict search flag
74
   */
75
  public function remove($outcome, $strict = null) {
76
    if (($index = array_search($outcome, $this->outcomes, $strict)) !== false) {
77
      unset($this->outcomes[$index]);
78
      unset($this->chances[$index]);
79
    }
80
  }
81
82
83
  /**
84
   * Get max range of all current outcomes to use as maximum in mt_rand()
85
   *
86
   * @return float|int
87
   */
88
  public function getMaxRange() {
89
    return array_sum($this->chances);
90
  }
91
92
  /**
93
   * Get outcome by rolled chance
94
   *
95
   * @param int $rolled - Rolled chance
96
   *
97
   * @return mixed|null - (null) if no outcomes
98
   */
99
  public function getOutcome($rolled) {
100
    foreach ($this->chances as $index => $chance) {
101
      if ($chance <= $rolled) {
102
        break;
103
      }
104
      $rolled -= $chance;
105
    }
106
107
    return array_key_exists($index, $this->outcomes) ? $this->outcomes[$index] : null;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $index seems to be defined by a foreach iteration on line 100. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
108
  }
109
110
  /**
111
   * All-in-one function
112
   *
113
   * Code can use this function if it don't want to know what number was rolled
114
   *
115
   * @return mixed|null
116
   */
117
  public function rollOutcome() {
118
    return $this->getOutcome(mt_rand(1, $this->getMaxRange()));
119
  }
120
121
  /**
122
   * Count elements of an object
123
   * @link  http://php.net/manual/en/countable.count.php
124
   * @return int The custom count as an integer.
125
   * </p>
126
   * <p>
127
   * The return value is cast to an integer.
128
   * @since 5.1.0
129
   */
130
  public function count() {
131
    return count($this->outcomes);
132
  }
133
134
}
135