Issues (11)

puzzles/SlidingCrates/Room.php (1 issue)

1
<?php declare(strict_types=1);
2
3
namespace Stratadox\PuzzleSolver\Puzzle\SlidingCrates;
4
5
use Stratadox\PuzzleSolver\Moves;
6
use function array_fill;
7
use function implode;
8
use function str_repeat;
9
use const PHP_EOL;
10
11
final class Room
12
{
13
    /** @var Crates */
14
    private $crates;
15
    /** @var int */
16
    private $width;
17
    /** @var int */
18
    private $height;
19
    /** @var Push */
20
    private $winningPush;
21
22
    private function __construct(
23
        Crates $crates,
24
        int $width,
25
        int $height,
26
        Push $winningPush
27
    ) {
28
        $this->crates = $crates;
29
        $this->width = $width;
30
        $this->height = $height;
31
        $this->winningPush = $winningPush;
32
    }
33
34
    public static function withCrates(
35
        Crates $crates,
36
        int $width,
37
        int $height,
38
        Push $winningPush
39
    ): self {
40
        return new self($crates, $width, $height, $winningPush);
41
    }
42
43
    public function afterPushing(Push ...$pushes): self
44
    {
45
        $new = clone $this;
46
        foreach ($pushes as $push) {
47
            $new->crates = $new->crates->after($push);
48
        }
49
        return $new;
50
    }
51
52
    public function isSolvedFor(string $target): bool
53
    {
54
        return $this->crates->withId($target)->wouldMoveOutOfBounds(
55
            $this->winningPush,
56
            $this->width,
57
            $this->height
58
        );
59
    }
60
61
    public function minimumDistanceToGoalFor(string $target): int
62
    {
63
        return $this->crates->withId($target)->movesUntilOutOfBounds(
64
            $this->winningPush,
65
            $this->width,
66
            $this->height
67
        );
68
    }
69
70
    public function possiblePushes(): Moves
71
    {
72
        return Push::allFor($this->crates)
0 ignored issues
show
Bug Best Practice introduced by
The expression return Stratadox\PuzzleS...ion(...) { /* ... */ }) returns the type Stratadox\Collection\Collection which includes types incompatible with the type-hinted return Stratadox\PuzzleSolver\Moves.
Loading history...
73
            ->filterWith(function (Push $push): bool {
74
                return $this->crates->withId($push->crateId())->canPush(
75
                    $push,
76
                    $this->crates,
77
                    $this->width,
78
                    $this->height
79
                );
80
            });
81
    }
82
83
    public function __toString(): string
84
    {
85
        $lines = array_fill(0, $this->height, str_repeat('. ', $this->width));
86
        foreach ($this->crates as $crate) {
87
            foreach ($crate->coordinates() as [$x, $y]) {
88
                $lines[$y][$x * 2] = $crate->id();
89
            }
90
        }
91
        return implode(PHP_EOL, $lines);
92
    }
93
}
94