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

AbstractSymmetricSpace::validateDimensionality()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 14
cts 14
cp 1
rs 9.2
c 0
b 0
f 0
cc 2
eloc 12
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 15
    protected function __construct(int $dimensions, int $boundarySize)
30
    {
31 15
        $this->dimensions = $dimensions;
32 15
        $this->boundarySize = $boundarySize;
33 15
        $this->boundaryCondition = BoundaryCondition::create($boundarySize);
34 15
    }
35
36
    /**
37
     * @return Vector
38
     */
39 9
    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 9
        return new Vector(array_fill(0, $this->dimensions, 0));
43
    }
44
45
    /**
46
     * @param Vector $position
47
     *
48
     * @return Robot
49
     */
50 8
    public function placeRobot(?Vector $position = null): Robot
51
    {
52 8
        $position = $position ?: $this->defaultPosition();
53
54 8
        if ($this->isAGoodPosition($position)) {
55
            // A robot is in a space with a place
56 8
            return Robot::create($this, $position);
57
        }
58
    }
59
60
    /**
61
     * @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...
62
     *
63
     * @return bool
64
     *
65
     * @throws \Reith\ToyRobot\Domain\Space\Exception\BoundaryTestException
66
     */
67 8
    public function isAGoodPosition(Vector $position): bool
68
    {
69 8
        $condition = $this->boundaryCondition;
70
71
        // Get raw array
72 8
        $coords = $position->getVector();
73
74 8
        array_walk(
75 8
            $coords,
76 8
            function (int $value) use ($condition) {
77 8
                $condition->test($value);
78 8
            }
79
        );
80
81 8
        return true;
82
    }
83
84
    /**
85
     * @param Vector      $from
86
     * @param Vector|null $to   If not supplied, origin is $from
87
     *
88
     * @throws PlaceDimensionsDoNotMatchSpaceException
89
     * @throws \Reith\ToyRobot\Domain\Space\Exception\BoundaryTestException
90
     */
91 7
    public function move(Vector $from, ?Vector $to = null): Vector
92
    {
93 7
        if (!$to) {
94 3
            $to = $from;
95
            // Origin
96 3
            $from = $this->defaultPosition();
97
        }
98
99
        // Ensure the movement is of the same dimension as the
100
        // space
101 7
        $this->validateDimensionality($from, $to);
102
103
        // Add the vectors to get the new position
104 4
        $final = $from->add($to);
105
106 4
        if ($this->isAGoodPosition($final)) {
107 2
            return $final;
108
        }
109
    }
110
111
    /**
112
     * For all the places passed, ensure they are of the same
113
     * dimensionality.
114
     *
115
     * @param Vector $vectors ... Vectors to check
116
     *
117
     * @throws PlaceDimensionsDoNotMatchSpaceException
118
     */
119 7
    private function validateDimensionality(Vector ...$vectors): void
120
    {
121 7
        $spaceDimensions = $this->dimensions;
122
123 7
        array_walk(
124 7
            $vectors,
125 7
            function (Vector $vector) use ($spaceDimensions) {
126
                // Ensure the dimensions are the same
127 7
                if ($vector->getN() !== $spaceDimensions) {
128 3
                    $errorMsg = sprintf(
129 3
                        'There is a position that has [%d] dimensions but space has [%d] dimensions',
130 3
                        $vector->getN(),
131 3
                        $spaceDimensions
132
                    );
133
134 3
                    throw new PlaceDimensionsDoNotMatchSpaceException(
135 3
                        $errorMsg
136
                    );
137
                }
138 7
            }
139
        );
140 4
    }
141
}
142