Passed
Pull Request — master (#14)
by Jose
04:13
created

Algorithm   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 7
Bugs 0 Features 0
Metric Value
wmc 16
eloc 45
c 7
b 0
f 0
dl 0
loc 137
ccs 51
cts 51
cp 1
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getOpenList() 0 3 1
A clear() 0 4 1
A computeAdjacentNodes() 0 10 2
A __construct() 0 4 1
A generatePathFromStartNodeTo() 0 13 2
A getClosedList() 0 3 1
B run() 0 49 8
1
<?php
2
3
namespace JMGQ\AStar;
4
5
abstract class Algorithm
6
{
7
    private $openList;
8
    private $closedList;
9
10 21
    public function __construct()
11
    {
12 21
        $this->openList = new NodeList();
13 21
        $this->closedList = new NodeList();
14 21
    }
15
16
    /**
17
     * @param Node $node
18
     * @return Node[]
19
     */
20
    abstract public function generateAdjacentNodes(Node $node);
21
22
    /**
23
     * @param Node $node
24
     * @param Node $adjacent
25
     * @return integer | float
26
     */
27
    abstract public function calculateRealCost(Node $node, Node $adjacent);
28
29
    /**
30
     * @param Node $start
31
     * @param Node $end
32
     * @return integer | float
33
     */
34
    abstract public function calculateEstimatedCost(Node $start, Node $end);
35
36
    /**
37
     * @return NodeList
38
     */
39 17
    public function getOpenList()
40
    {
41 17
        return $this->openList;
42
    }
43
44
    /**
45
     * @return NodeList
46
     */
47 17
    public function getClosedList()
48
    {
49 17
        return $this->closedList;
50
    }
51
52
    /**
53
     * Sets the algorithm to its initial state
54
     */
55 16
    public function clear()
56
    {
57 16
        $this->getOpenList()->clear();
58 16
        $this->getClosedList()->clear();
59 16
    }
60
61
    /**
62
     * @param Node $start
63
     * @param Node $goal
64
     * @return Node[]
65
     */
66 15
    public function run(Node $start, Node $goal)
67
    {
68 15
        $path = array();
69
70 15
        $this->clear();
71
72 15
        $start->setG(0);
73 15
        $start->setH($this->calculateEstimatedCost($start, $goal));
74
75 15
        $this->getOpenList()->add($start);
76
77 15
        while (!$this->getOpenList()->isEmpty()) {
78 15
            $currentNode = $this->getOpenList()->extractBest();
79
80 15
            $this->getClosedList()->add($currentNode);
0 ignored issues
show
Bug introduced by
It seems like $currentNode can also be of type null; however, parameter $node of JMGQ\AStar\NodeList::add() does only seem to accept JMGQ\AStar\Node, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

80
            $this->getClosedList()->add(/** @scrutinizer ignore-type */ $currentNode);
Loading history...
81
82 15
            if ($currentNode->getID() === $goal->getID()) {
83 13
                $path = $this->generatePathFromStartNodeTo($currentNode);
0 ignored issues
show
Bug introduced by
It seems like $currentNode can also be of type null; however, parameter $node of JMGQ\AStar\Algorithm::ge...tePathFromStartNodeTo() does only seem to accept JMGQ\AStar\Node, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

83
                $path = $this->generatePathFromStartNodeTo(/** @scrutinizer ignore-type */ $currentNode);
Loading history...
84 13
                break;
85
            }
86
87 12
            $successors = $this->computeAdjacentNodes($currentNode, $goal);
0 ignored issues
show
Bug introduced by
It seems like $currentNode can also be of type null; however, parameter $node of JMGQ\AStar\Algorithm::computeAdjacentNodes() does only seem to accept JMGQ\AStar\Node, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

87
            $successors = $this->computeAdjacentNodes(/** @scrutinizer ignore-type */ $currentNode, $goal);
Loading history...
88
89 12
            foreach ($successors as $successor) {
90 10
                if ($this->getOpenList()->contains($successor)) {
91 7
                    $successorInOpenList = $this->getOpenList()->get($successor);
92
93 7
                    if ($successor->getG() >= $successorInOpenList->getG()) {
94 6
                        continue;
95
                    }
96
                }
97
98 10
                if ($this->getClosedList()->contains($successor)) {
99 7
                    $successorInClosedList = $this->getClosedList()->get($successor);
100
101 7
                    if ($successor->getG() >= $successorInClosedList->getG()) {
102 7
                        continue;
103
                    }
104
                }
105
106 10
                $successor->setParent($currentNode);
0 ignored issues
show
Bug introduced by
It seems like $currentNode can also be of type null; however, parameter $parent of JMGQ\AStar\Node::setParent() does only seem to accept JMGQ\AStar\Node, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

106
                $successor->setParent(/** @scrutinizer ignore-type */ $currentNode);
Loading history...
107
108 10
                $this->getClosedList()->remove($successor);
109
110 10
                $this->getOpenList()->add($successor);
111
            }
112
        }
113
114 15
        return $path;
115
    }
116
117 13
    private function generatePathFromStartNodeTo(Node $node)
118
    {
119 13
        $path = array();
120
121 13
        $currentNode = $node;
122
123 13
        while ($currentNode !== null) {
124 13
            array_unshift($path, $currentNode);
125
126 13
            $currentNode = $currentNode->getParent();
127
        }
128
129 13
        return $path;
130
    }
131
132 12
    private function computeAdjacentNodes(Node $node, Node $goal)
133
    {
134 12
        $nodes = $this->generateAdjacentNodes($node);
135
136 12
        foreach ($nodes as $adjacentNode) {
137 10
            $adjacentNode->setG($node->getG() + $this->calculateRealCost($node, $adjacentNode));
138 10
            $adjacentNode->setH($this->calculateEstimatedCost($adjacentNode, $goal));
139
        }
140
141 12
        return $nodes;
142
    }
143
}
144