1 | <?php |
||
17 | class DecisionNode |
||
18 | { |
||
19 | /** |
||
20 | * @var Player The player to optimize for. |
||
21 | */ |
||
22 | private $objectivePlayer; |
||
23 | |||
24 | /** |
||
25 | * @var GameState The current GameState to base future decisions on. |
||
26 | */ |
||
27 | private $state; |
||
28 | |||
29 | /** |
||
30 | * @var int Limit on how deep we can continue to search, recursion limiter. |
||
31 | */ |
||
32 | private $depthLeft; |
||
33 | |||
34 | /** |
||
35 | * @var NodeType Whether we are a min-node or a max-node. This enables the |
||
36 | * caller to select either the most favorable or the least favorable |
||
37 | * outcome. |
||
38 | */ |
||
39 | private $type; |
||
40 | |||
41 | /** |
||
42 | * @var AlphaBeta Constraints for alpha-beta pruning |
||
43 | */ |
||
44 | private $alphaBeta; |
||
45 | |||
46 | /** |
||
47 | * @param Player $objectivePlayer The Player to optimize for |
||
48 | * @param GameState $state Current GameState to base decisions on |
||
49 | * @param int $depthLeft Recursion limiter |
||
50 | * @param NodeType $type Signifies whether to minimize or maximize the score |
||
51 | * @param AlphaBeta $alphaBeta Range of potential scores to check |
||
52 | */ |
||
53 | 14 | public function __construct(Player $objectivePlayer, GameState $state, int $depthLeft, NodeType $type, AlphaBeta $alphaBeta) |
|
61 | |||
62 | /** |
||
63 | * Determine the ideal move for this node |
||
64 | * |
||
65 | * This means either the best or the worst possible outcome for the |
||
66 | * objective player, based on who is actually playing. (If the objective |
||
67 | * player is currently playing, we take the best outcome, otherwise we take |
||
68 | * the worst. This reflects that the opponent also plays optimally.) |
||
69 | */ |
||
70 | 14 | public function traverseGameTree(): TraversalResult |
|
101 | |||
102 | /** |
||
103 | * Formulate the evaluation, this node being a leaf node |
||
104 | */ |
||
105 | 14 | private function makeLeafEvaluation(): Evaluation |
|
112 | |||
113 | /** |
||
114 | * Recursively evaluate a child decision |
||
115 | * |
||
116 | * Apply a move and evaluate the outcome |
||
117 | * |
||
118 | * @param GameState $stateAfterMove The GameState that was created as a |
||
119 | * result of a possible move. |
||
120 | */ |
||
121 | 13 | private function getChildResult(GameState $stateAfterMove): TraversalResult |
|
133 | |||
134 | /** |
||
135 | * Compare two evaluations |
||
136 | * |
||
137 | * The meaning of "best" is decided by the "ideal" member variable |
||
138 | * comparator |
||
139 | */ |
||
140 | 12 | private function isIdealOver(Evaluation $a, Evaluation $b): bool |
|
148 | } |
||
149 |
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: