NormalConstructor   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 42
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 21
dl 0
loc 42
ccs 0
cts 21
cp 0
rs 10
c 0
b 0
f 0
wmc 6

3 Methods

Rating   Name   Duplication   Size   Complexity  
A build() 0 12 2
A newLine() 0 14 3
A __construct() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Crossword\Features\Constructor\Normal;
6
7
use App\Crossword\Features\Constructor\ConstructorInterface;
8
use App\Crossword\Features\Constructor\CrosswordDto;
9
use App\Crossword\Features\Constructor\LineDto;
10
use App\Crossword\Features\Constructor\Scanner\Exception\SearchMaskIsShortException;
11
use App\Crossword\Features\Constructor\Scanner\Exception\WordNotFitException;
12
use App\Crossword\Features\Constructor\Scanner\Grid\Grid;
13
use App\Crossword\Features\Constructor\Scanner\Grid\Line;
14
use App\Crossword\Features\Constructor\Scanner\Grid\Row;
15
use App\Crossword\Features\Constructor\Scanner\GridScanner;
16
use App\Crossword\Features\Constructor\WordFoundException;
17
18
final class NormalConstructor implements ConstructorInterface
19
{
20
    private GridScanner $gridScanner;
21
    private AttemptWordFinder $attemptWordFinder;
22
23
    public function __construct(AttemptWordFinder $attemptWordFinder, GridScanner $gridScanner)
24
    {
25
        $this->attemptWordFinder = $attemptWordFinder;
26
        $this->gridScanner = $gridScanner;
27
    }
28
29
    public function build(string $language, int $wordCount): CrosswordDto
30
    {
31
        $crosswordDto = new CrosswordDto();
32
        $grid = new Grid(Line::withLetter(Row::withRandomRow(), chr(random_int(97, 122))));
33
        for ($counter = 1; $counter <= $wordCount; $counter++) {
34
            $rows = $this->gridScanner->scan($grid);
35
            $lineDto = $this->newLine($rows, $language);
36
            $grid->fillLine($lineDto->line());
37
            $crosswordDto = $crosswordDto->withLine($lineDto);
38
        }
39
40
        return $crosswordDto;
41
    }
42
43
    /**
44
     * @throws NextLineFoundException
45
     */
46
    private function newLine(array $rows, string $language): LineDto
47
    {
48
        foreach ($rows as $row) {
49
            try {
50
                $word = $this->attemptWordFinder->find($language, $row->mask());
51
                $line = Line::withWord($row, $word->value());
52
53
                return new LineDto($line, $word);
54
            } catch (WordFoundException | WordNotFitException | SearchMaskIsShortException) {
55
                continue;
56
            }
57
        }
58
59
        throw new NextLineFoundException();
60
    }
61
}
62