VisitedNodeCostChecker::isOngoing()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\PuzzleSolver\SearchStrategy;
4
5
use Stratadox\PuzzleSolver\Puzzle;
6
use const INF;
7
8
/**
9
 * Visited Node Cost Checker
10
 *
11
 * The Visited Node Cost Checker keeps a record of the cost of reaching each
12
 * considered candidate. When a candidate is encountered that already has a
13
 * recorded cost, the cost of the newly discovered path to reach the same state
14
 * as before is compared with the previously recorded cost. If the cost is lower
15
 * than before, the record gets updated and the new candidate is considered. In
16
 * case the cost is equal or higher than previous paths to the same goal, the
17
 * candidate is discarded.
18
 *
19
 * Decorator for other search strategies.
20
 *
21
 * @author Stratadox
22
 */
23
final class VisitedNodeCostChecker implements SearchStrategy
24
{
25
    /** @var float[] */
26
    private $costTowards = [];
27
    /** @var SearchStrategy */
28
    private $search;
29
30
    private function __construct(SearchStrategy $search)
31
    {
32
        $this->search = $search;
33
    }
34
35
    public static function forThe(SearchStrategy $search): self
36
    {
37
        return new self($search);
38
    }
39
40
    public function isOngoing(): bool
41
    {
42
        return $this->search->isOngoing();
43
    }
44
45
    public function consider(Puzzle $puzzle): bool
46
    {
47
        $cost = $puzzle->movesSoFar()->cost();
48
        if ($cost < ($this->costTowards[$puzzle->representation()] ?? INF)) {
49
            $this->costTowards[$puzzle->representation()] = $cost;
50
            return $this->search->consider($puzzle);
51
        }
52
        return false;
53
    }
54
55
    public function nextCandidate(): Puzzle
56
    {
57
        return $this->search->nextCandidate();
58
    }
59
}
60