Robot::getReportAsString()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
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 implements \Serializable
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 13
    private function __construct(
33
        SpaceInterface $space,
34
        Vector $position,
35
        Direction $facingDirection
36
    ) {
37 13
        $this->mySpace = $space;
38 13
        $this->position = $position;
39 13
        $this->facingDirection = $facingDirection;
40 13
    }
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 14
    public static function create(
52
        SpaceInterface $space,
53
        Vector $position,
54
        ?string $facingDirection = 'E'
55
    ): Robot {
56
57 14
        $facingDirection = $facingDirection ?: 'E';
58
59 14
        return new static(
60 14
            $space,
61 14
            $position,
62 14
            new Direction($facingDirection)
63
        );
64
    }
65
66
    /**
67
     * @return Robot
68
     */
69 1
    public function move(): Robot
70
    {
71 1
        $this->validateCanMove();
72
73 1
        $this->position = $this->mySpace->move(
74 1
            $this->position,
75 1
            $this->facingDirection->getDirectionAsVector()
76
        );
77
78 1
        return $this;
79
    }
80
81
    /**
82
     * @return Robot
83
     */
84 1
    public function left(): Robot
85
    {
86 1
        $this->facingDirection->rotateLeft();
87
88 1
        return $this;
89
    }
90
91
    /**
92
     * @return Robot
93
     */
94 1
    public function right(): Robot
95
    {
96 1
        $this->facingDirection->rotateRight();
97
98 1
        return $this;
99
    }
100
101
    /**
102
     * @return Robot
103
     */
104 2
    public function moveNorthward(): Robot
105
    {
106 2
        $this->validateCanMove();
107
108 2
        $this->position = $this->mySpace->move(
109 2
            $this->position,
110 2
            $this->facingDirection->northward()
111
        );
112
113 2
        return $this;
114
    }
115
116
    /**
117
     * @return Robot
118
     */
119 1
    public function moveEastward(): Robot
120
    {
121 1
        $this->validateCanMove();
122
123 1
        $this->position = $this->mySpace->move(
124 1
            $this->position,
125 1
            $this->facingDirection->eastward()
126
        );
127
128 1
        return $this;
129
    }
130
131
    /**
132
     * @return Robot
133
     */
134 2
    public function moveSouthward(): Robot
135
    {
136 2
        $this->validateCanMove();
137
138 2
        $this->position = $this->mySpace->move(
139 2
            $this->position,
140 2
            $this->facingDirection->southward()
141
        );
142
143 1
        return $this;
144
    }
145
146
    /**
147
     * @return Robot
148
     */
149 2
    public function moveWestward(): Robot
150
    {
151 2
        $this->validateCanMove();
152
153 2
        $this->position = $this->mySpace->move(
154 2
            $this->position,
155 2
            $this->facingDirection->westward()
156
        );
157
158 1
        return $this;
159
    }
160
161
    /**
162
     * @return Vector
163
     */
164 1
    public function getPosition(): Vector
165
    {
166 1
        return $this->position;
167
    }
168
169
    /**
170
     * @return string In the form 'X,Y,F'
171
     */
172 8
    public function getReportAsString(): string
173
    {
174 8
        $positionAsString = implode(',', $this->position->getVector());
175
176 8
        return $positionAsString . ',' . $this->getFacingDirectionAsString();
177
    }
178
179
    /**
180
     * Simplify the serialization of the Robot to
181
     * scalars
182
     *
183
     * @return string
184
     */
185
    public function serialize(): string
186
    {
187
        return serialize([
188
            $this->mySpace,
189
            $this->position->getVector(),
190
            $this->getFacingDirectionAsString()
191
        ]);
192
    }
193
194
    /**
195
     * Re-hydrate the Robot
196
     *
197
     * @param string $data
198
     */
199
    public function unserialize($data)
200
    {
201
        [$this->mySpace, $positionArr, $facingString] = unserialize($data);
0 ignored issues
show
Bug introduced by
The variable $positionArr does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $facingString does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
202
203
        $this->position = new Vector($positionArr);
204
        $this->facingDirection = new Direction($facingString);
205
    }
206
207
    /**
208
     * @return string
209
     */
210 8
    private function getFacingDirectionAsString(): string
211
    {
212 8
        return $this->facingDirection->getDirectionAsString();
213
    }
214
215
    /**
216
     * validateCanMove.
217
     *
218
     * The robot requires a space during construction, however,
219
     * this is extra precautionary in case the space is removed
220
     *
221
     * @throws NotPlacedInSpaceException
222
     */
223 5
    private function validateCanMove(): void
224
    {
225 5
        if (!$this->mySpace) {
226
            throw new NotPlacedInSpaceException(
227
                'I cannot move until placed in space'
228
            );
229
        }
230 5
    }
231
}
232