Passed
Push — master ( 1fb483...35eebd )
by Roman
04:31
created

Grid::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 6
ccs 0
cts 4
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Crossword\Features\Constructor\Scanner\Grid;
6
7
use ArrayIterator;
8
use IteratorAggregate;
9
10
final class Grid implements IteratorAggregate
11
{
12
    /**
13
     * @var Cell[]
14
     */
15
    private array $cells;
16
17
    public function __construct(Line ...$lines)
18
    {
19
        $this->cells = [];
20
21
        foreach ($lines as $line) {
22
            $this->fillLine($line);
23
        }
24
    }
25
26
    public function getIterator(): ArrayIterator
27
    {
28
        return new ArrayIterator($this->cells);
29
    }
30
31 1
    public function isEmpty(): bool
32
    {
33 1
        return 0 === count(array_filter($this->cells, static fn (Cell $cell) => null !== $cell->letter()));
34
    }
35
36 3
    public function shiftCell(Coordinate $coordinate): Cell
37
    {
38 3
        if ($coordinate->inFrame() && $this->exist($coordinate)) {
39 2
            return $this->cells[(string) $coordinate];
40
        }
41
42 3
        return new Cell($coordinate, null);
0 ignored issues
show
Bug introduced by
null of type null is incompatible with the type App\Crossword\Features\C...canner\Grid\null|string expected by parameter $letter of App\Crossword\Features\C...rid\Cell::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

42
        return new Cell($coordinate, /** @scrutinizer ignore-type */ null);
Loading history...
43
    }
44
45 1
    public function fillLine(Line $line): void
46
    {
47
        /** @var Cell $cell */
48 1
        foreach ($line as $cell) {
49 1
            if ($cell->isLetter()) {
50 1
                $this->cells[(string) $cell->coordinate()] = $cell;
51
            }
52
        }
53
54 1
        array_map([$this, 'fillBlackSquare'], $this->cells);
55 1
    }
56
57 4
    private function fillBlackSquare(Cell $cell): void
58
    {
59 4
        if ($cell->isLetter()) {
60 4
            $this->searchBlackSquareByYRow($cell->coordinate());
61 4
            $this->searchBlackSquareByXRow($cell->coordinate());
62
        }
63 4
    }
64
65
    private function searchBlackSquareByYRow(Coordinate $coordinate): void
66
    {
67
        $topCell = $this->shiftCell($coordinate->top());
68
        $downCell = $this->shiftCell($coordinate->down());
69
70
        $topCoordinate = $coordinate->top();
71
        if ($topCoordinate->inFrame() && !$topCell->letter() && $downCell->letter()) {
72
            $this->fillCellBlack($coordinate->top());
73
        }
74
75
        if ($topCell->letter() && !$downCell->letter()) {
76
            $this->fillCellBlack($coordinate->down());
77
        }
78
    }
79
80
    private function searchBlackSquareByXRow(Coordinate $coordinate): void
81
    {
82
        $leftCell = $this->shiftCell($coordinate->left());
83
        $rightCell = $this->shiftCell($coordinate->right());
84
85
        $leftCoordinate = $coordinate->left();
86
        if ($leftCoordinate->inFrame() && !$leftCell->letter() && $rightCell->letter()) {
87
            $this->fillCellBlack($coordinate->left());
88
        }
89
90
        if ($leftCell->letter() && !$rightCell->letter()) {
91
            $this->fillCellBlack($coordinate->right());
92
        }
93
    }
94
95
    private function fillCellBlack(Coordinate $coordinate): void
96
    {
97
        $this->cells[(string) $coordinate] = new Cell($coordinate, '');
98
    }
99
100
    private function exist(Coordinate $coordinate): bool
101
    {
102
        return array_key_exists((string) $coordinate, $this->cells);
103
    }
104
}
105