Completed
Push — master ( fbabbd...8184b0 )
by Douglas
01:43
created

Robot::left()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 3
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * (c) 2018 Douglas Reith.
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
declare(strict_types=1);
10
11
namespace Reith\ToyRobot\Domain\Robot;
12
13
use MathPHP\LinearAlgebra\Vector;
14
use Assert\Assert;
15
use Assert\Assertion;
16
use Reith\ToyRobot\Domain\Space\SpaceInterface;
17
use Reith\ToyRobot\Domain\Robot\Exception\NotPlacedInSpaceException;
18
19
class Robot
20
{
21
    /**
22
     * Purchased by Rupert, then tanked :).
23
     *
24
     * @var SpaceInterface
25
     */
26
    private $mySpace;
27
28
    private $position;
29
30
    private $facingDirection;
31
32 8
    private function __construct(
33
        SpaceInterface $space,
34
        Vector $position,
35
        Direction $facingDirection
36
    ) {
37 8
        $this->mySpace = $space;
38 8
        $this->position = $position;
39 8
        $this->facingDirection = $facingDirection;
40 8
    }
41
42
    /**
43
     * @param SpaceInterface $space
44
     * @param Vector         $position
45
     * @param string|null    $facingDirection
46
     *
47
     * @return Robot
48
     *
49
     * @throws Assert\AssertionFailedException
50
     */
51 9
    public static function create(
52
        SpaceInterface $space,
53
        Vector $position,
54
        ?string $facingDirection = 'E'
55
    ): Robot {
56 9
        return new static(
57 9
            $space,
58 9
            $position,
59 9
            new Direction($facingDirection)
60
        );
61
    }
62
63
    public function move(): Robot
64
    {
65
        $this->validateCanMove();
66
67
        $this->position = $this->mySpace->move(
68
            $this->position,
69
            $this->facingDirection->getDirectionAsVector()
70
        );
71
72
        return $this;
73
    }
74
75
    public function left(): Robot
76
    {
77
        $this->facingDirection->rotateLeft();
78
79
        return $this;
80
    }
81
82
    public function right(): Robot
83
    {
84
        $this->facingDirection->rotateRight();
85
86
        return $this;
87
    }
88
89 2
    public function moveNorthward(): Robot
90
    {
91 2
        $this->validateCanMove();
92
93 2
        $this->position = $this->mySpace->move(
94 2
            $this->position,
95 2
            $this->facingDirection->northward()
96
        );
97
98 2
        return $this;
99
    }
100
101 1
    public function moveEastward(): Robot
102
    {
103 1
        $this->validateCanMove();
104
105 1
        $this->position = $this->mySpace->move(
106 1
            $this->position,
107 1
            $this->facingDirection->eastward()
108
        );
109
110 1
        return $this;
111
    }
112
113 2
    public function moveSouthward(): Robot
114
    {
115 2
        $this->validateCanMove();
116
117 2
        $this->position = $this->mySpace->move(
118 2
            $this->position,
119 2
            $this->facingDirection->southward()
120
        );
121
122 1
        return $this;
123
    }
124
125 2
    public function moveWestward(): Robot
126
    {
127 2
        $this->validateCanMove();
128
129 2
        $this->position = $this->mySpace->move(
130 2
            $this->position,
131 2
            $this->facingDirection->westward()
132
        );
133
134 1
        return $this;
135
    }
136
137 1
    public function getPosition(): Vector
138
    {
139 1
        return $this->position;
140
    }
141
142
    /**
143
     * validateCanMove.
144
     *
145
     * The robot requires a space during construction, however,
146
     * this is extra precautionary in case the space is removed
147
     *
148
     * @throws NotPlacedInSpaceException
149
     */
150 4
    private function validateCanMove(): void
151
    {
152 4
        if (!$this->mySpace) {
153
            throw new NotPlacedInSpaceException(
154
                'I cannot move until placed in space'
155
            );
156
        }
157 4
    }
158
}
159