fromArrayAndStartAndGoal()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 3
dl 0
loc 6
rs 10
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\PuzzleSolver\Puzzle\NetworkNavigation;
4
5
use Stratadox\PuzzleSolver\Move;
6
use Stratadox\PuzzleSolver\Puzzle;
7
use Stratadox\PuzzleSolver\Moves;
8
use function json_decode;
9
10
final class NetworkNavigationPuzzle implements Puzzle
11
{
12
    /** @var string */
13
    private $heroLocation;
14
    /** @var string */
15
    private $goalLocation;
16
    /** @var float[][] */
17
    private $network;
18
    /** @var Moves */
19
    private $moves;
20
21
    private function __construct(
22
        string $heroLocation,
23
        string $goalLocation,
24
        array $network,
25
        Moves $moves
26
    ) {
27
        $this->heroLocation = $heroLocation;
28
        $this->goalLocation = $goalLocation;
29
        $this->network = $network;
30
        $this->moves = $moves;
31
    }
32
33
    public static function fromJsonAndStartAndGoal(
34
        string $json,
35
        string $start,
36
        string $goal
37
    ): Puzzle {
38
        $network = [];
39
        foreach (json_decode($json, true) as $edge) {
40
            $network[$edge['from']][$edge['to']] = $edge['cost'];
41
        }
42
        return self::fromArrayAndStartAndGoal($network, $start, $goal);
43
    }
44
45
    public static function fromArrayAndStartAndGoal(
46
        array $network,
47
        string $start,
48
        string $goal
49
    ): Puzzle {
50
        return new self($start, $goal, $network, Moves::none());
51
    }
52
53
    public function representation(): string
54
    {
55
        return $this->heroLocation;
56
    }
57
58
    public function afterMaking(Move ...$moves): Puzzle
59
    {
60
        $move = end($moves);
61
        if (!$move instanceof Jump) {
62
            return $this;
63
        }
64
        $new = clone $this;
65
        $new->heroLocation = $move->target();
66
        $new->moves = $this->moves->add(...$moves);
67
        return $new;
68
    }
69
70
    public function isSolved(): bool
71
    {
72
        return $this->heroLocation === $this->goalLocation;
73
    }
74
75
    public function movesSoFar(): Moves
76
    {
77
        return $this->moves;
78
    }
79
80
    public function possibleMoves(): Moves
81
    {
82
        $moves = [];
83
        foreach ($this->network[$this->heroLocation] as $neighbour => $cost) {
84
            $moves[] = Jump::to($neighbour, $cost);
85
        }
86
        return new Moves(...$moves);
87
    }
88
}
89