AbstractSymmetricSpace::validateDimensionality()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 13
cts 13
cp 1
rs 9.568
c 0
b 0
f 0
cc 2
nc 1
nop 1
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\Space;
12
13
use MathPHP\LinearAlgebra\Vector;
14
use Reith\ToyRobot\Domain\Space\Exception\PlaceDimensionsDoNotMatchSpaceException;
15
use Reith\ToyRobot\Domain\Robot\Robot;
16
17
abstract class AbstractSymmetricSpace implements SpaceInterface
18
{
19
    private $dimensions;
20
21
    private $boundarySize;
22
23
    private $boundaryCondition;
24
25
    /**
26
     * @param int $dimensions
27
     * @param int $boundarySize
28
     */
29 21
    protected function __construct(int $dimensions, int $boundarySize)
30
    {
31 21
        $this->dimensions = $dimensions;
32 21
        $this->boundarySize = $boundarySize;
33 21
        $this->boundaryCondition = BoundaryCondition::create($boundarySize);
34 21
    }
35
36
    /**
37
     * @return Vector
38
     */
39 10
    protected function defaultPosition(): Vector
40
    {
41
        // Create a default position [0,0,..n]
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
42 10
        return new Vector(array_fill(0, $this->dimensions, 0));
43
    }
44
45
    /**
46
     * @param Vector|null $position
47
     * @param string|null $startingDirection
48
     *
49
     * @return Robot
50
     */
51 13
    public function placeRobot(?Vector $position = null, ?string $startingDirection = null): Robot
52
    {
53 13
        $position = $position ?: $this->defaultPosition();
54
55 13
        if ($this->isAGoodPosition($position)) {
56
            // A robot is in a space with a place
57 13
            return Robot::create($this, $position, $startingDirection);
58
        }
59
    }
60
61
    /**
62
     * @param Vector $place
0 ignored issues
show
Bug introduced by
There is no parameter named $place. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
63
     *
64
     * @return bool
65
     *
66
     * @throws \Reith\ToyRobot\Domain\Space\Exception\BoundaryTestException
67
     */
68 13
    public function isAGoodPosition(Vector $position): bool
69
    {
70 13
        $condition = $this->boundaryCondition;
71
72
        // Get raw array
73 13
        $coords = $position->getVector();
74
75 13
        array_walk(
76 13
            $coords,
77
            function (int $value) use ($condition) {
78 13
                $condition->test($value);
79 13
            }
80
        );
81
82 13
        return true;
83
    }
84
85
    /**
86
     * @param Vector      $from
87
     * @param Vector|null $to   If not supplied, origin is $from
88
     *
89
     * @throws PlaceDimensionsDoNotMatchSpaceException
90
     * @throws \Reith\ToyRobot\Domain\Space\Exception\BoundaryTestException
91
     */
92 8
    public function move(Vector $from, ?Vector $to = null): Vector
93
    {
94 8
        if (!$to) {
95 3
            $to = $from;
96
            // Origin
97 3
            $from = $this->defaultPosition();
98
        }
99
100
        // Ensure the movement is of the same dimension as the
101
        // space
102 8
        $this->validateDimensionality($from, $to);
103
104
        // Add the vectors to get the new position
105 5
        $final = $from->add($to);
106
107 5
        if ($this->isAGoodPosition($final)) {
108 3
            return $final;
109
        }
110
    }
111
112
    /**
113
     * For all the places passed, ensure they are of the same
114
     * dimensionality.
115
     *
116
     * @param Vector $vectors ... Vectors to check
117
     *
118
     * @throws PlaceDimensionsDoNotMatchSpaceException
119
     */
120 8
    private function validateDimensionality(Vector ...$vectors): void
121
    {
122 8
        $spaceDimensions = $this->dimensions;
123
124 8
        array_walk(
125 8
            $vectors,
126
            function (Vector $vector) use ($spaceDimensions) {
127
                // Ensure the dimensions are the same
128 8
                if ($vector->getN() !== $spaceDimensions) {
129 3
                    $errorMsg = sprintf(
130 3
                        'There is a position that has [%d] dimensions but space has [%d] dimensions',
131 3
                        $vector->getN(),
132 3
                        $spaceDimensions
133
                    );
134
135 3
                    throw new PlaceDimensionsDoNotMatchSpaceException(
136 3
                        $errorMsg
137
                    );
138
                }
139 8
            }
140
        );
141 5
    }
142
}
143