1 | <?php declare(strict_types=1); |
||
2 | |||
3 | namespace Stratadox\PuzzleSolver\Puzzle\Maze; |
||
4 | |||
5 | use Stratadox\PuzzleSolver\Move; |
||
6 | use Stratadox\PuzzleSolver\Puzzle; |
||
7 | use Stratadox\PuzzleSolver\Moves; |
||
8 | use function assert; |
||
9 | use function explode; |
||
10 | use function implode; |
||
11 | use const PHP_EOL; |
||
12 | |||
13 | final class MazePuzzle implements Puzzle |
||
14 | { |
||
15 | /** @var Maze */ |
||
16 | private $maze; |
||
17 | /** @var Hero */ |
||
18 | private $hero; |
||
19 | /** @var Moves */ |
||
20 | private $actionsSoFar; |
||
21 | |||
22 | public function __construct(Maze $maze, Hero $hero, Moves $actionsSoFar) |
||
23 | { |
||
24 | $this->maze = $maze; |
||
25 | $this->hero = $hero; |
||
26 | $this->actionsSoFar = $actionsSoFar; |
||
27 | } |
||
28 | |||
29 | public static function withHeroAndMaze(Hero $hero, Maze $maze): Puzzle |
||
30 | { |
||
31 | return new self($maze, $hero, Moves::none()); |
||
32 | } |
||
33 | |||
34 | public function isSolved(): bool |
||
35 | { |
||
36 | return $this->maze->isCompletedBy($this->hero); |
||
37 | } |
||
38 | |||
39 | public function movesSoFar(): Moves |
||
40 | { |
||
41 | return $this->actionsSoFar; |
||
42 | } |
||
43 | |||
44 | public function representation(): string |
||
45 | { |
||
46 | $maze = explode(PHP_EOL, (string) $this->maze); |
||
47 | $maze[$this->hero->y()][$this->hero->x()] = 'H'; |
||
48 | return implode(PHP_EOL, $maze); |
||
49 | } |
||
50 | |||
51 | public function possibleMoves(): Moves |
||
52 | { |
||
53 | return Action::all()->filterWith(function (Action $action) { |
||
0 ignored issues
–
show
Bug
Best Practice
introduced
by
![]() |
|||
54 | return $this->maze->isValidPosition($this->hero->after($action)); |
||
55 | }); |
||
56 | } |
||
57 | |||
58 | public function afterMaking(Move ...$moves): Puzzle |
||
59 | { |
||
60 | $new = clone $this; |
||
61 | foreach ($moves as $move) { |
||
62 | assert($move instanceof Action); |
||
63 | $new->hero = $new->hero->after($move); |
||
64 | $new->actionsSoFar = $new->actionsSoFar->add($move); |
||
65 | } |
||
66 | return $new; |
||
67 | } |
||
68 | |||
69 | public function hero(): Hero |
||
70 | { |
||
71 | return $this->hero; |
||
72 | } |
||
73 | } |
||
74 |