Completed
Push — master ( 04d11f...130a84 )
by Jose
03:40
created

Algorithm   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 98.25%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 16
lcom 1
cbo 2
dl 0
loc 139
ccs 56
cts 57
cp 0.9825
rs 10
c 1
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
generateAdjacentNodes() 0 1 ?
calculateRealCost() 0 1 ?
calculateEstimatedCost() 0 1 ?
A getOpenList() 0 4 1
A getClosedList() 0 4 1
A clear() 0 5 1
C run() 0 50 8
A generatePathFromStartNodeTo() 0 14 2
A computeAdjacentNodes() 0 11 2
1
<?php
2
3
namespace JMGQ\AStar;
4
5
abstract class Algorithm
6
{
7
    private $openList;
8
    private $closedList;
9
10 19
    public function __construct()
11
    {
12 19
        $this->openList = new NodeList();
13 19
        $this->closedList = new NodeList();
14 19
    }
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 15
    public function getOpenList()
40
    {
41 15
        return $this->openList;
42
    }
43
44
    /**
45
     * @return NodeList
46
     */
47 15
    public function getClosedList()
48
    {
49 15
        return $this->closedList;
50
    }
51
52
    /**
53
     * Sets the algorithm to its initial state
54
     */
55 14
    public function clear()
56
    {
57 14
        $this->getOpenList()->clear();
58 14
        $this->getClosedList()->clear();
59 14
    }
60
61
    /**
62
     * @param Node $start
63
     * @param Node $goal
64
     * @return Node[]
65
     */
66 13
    public function run(Node $start, Node $goal)
67
    {
68 13
        $path = array();
69
70 13
        $this->clear();
71
72 13
        $start->setG(0);
73 13
        $start->setH($this->calculateEstimatedCost($start, $goal));
74
75 13
        $this->getOpenList()->add($start);
76
77 13
        while (!$this->getOpenList()->isEmpty()) {
78 13
            $currentNode = $this->getOpenList()->extractBest();
79
80 13
            $this->getClosedList()->add($currentNode);
81
82 13
            if ($currentNode->getID() === $goal->getID()) {
83 11
                $path = $this->generatePathFromStartNodeTo($currentNode);
84 11
                break;
85
            }
86
87 11
            $successors = $this->computeAdjacentNodes($currentNode, $goal);
88
89 11
            foreach ($successors as $successor) {
90 9
                if ($this->getOpenList()->contains($successor)) {
91 6
                    $successorInOpenList = $this->getOpenList()->get($successor);
92
93 6
                    if ($successor->getG() >= $successorInOpenList->getG()) {
94 5
                        continue;
95
                    }
96 3
                }
97
98 9
                if ($this->getClosedList()->contains($successor)) {
99 6
                    $successorInClosedList = $this->getClosedList()->get($successor);
100
101 6
                    if ($successor->getG() >= $successorInClosedList->getG()) {
102 6
                        continue;
103
                    }
104
                }
105
106 9
                $successor->setParent($currentNode);
107
108 9
                $this->getClosedList()->remove($successor);
109
110 9
                $this->getOpenList()->add($successor);
111 11
            }
112 11
        }
113
114 13
        return $path;
115
    }
116
117 11
    private function generatePathFromStartNodeTo(Node $node)
118
    {
119 11
        $path = array();
120
121 11
        $currentNode = $node;
122
123 11
        while ($currentNode !== null) {
124 11
            array_unshift($path, $currentNode);
125
126 11
            $currentNode = $currentNode->getParent();
127 11
        }
128
129 11
        return $path;
130
    }
131
132 11
    private function computeAdjacentNodes(Node $node, Node $goal)
133
    {
134 11
        $nodes = $this->generateAdjacentNodes($node);
135
136 11
        foreach ($nodes as $adjacentNode) {
137 9
            $adjacentNode->setG($node->getG() + $this->calculateRealCost($node, $adjacentNode));
138 9
            $adjacentNode->setH($this->calculateEstimatedCost($adjacentNode, $goal));
139 11
        }
140
141 11
        return $nodes;
142
    }
143
}
144