Passed
Push — master ( 05198c...c56a1e )
by Craig
03:33
created

HasWordCollection   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 29
c 1
b 1
f 0
dl 0
loc 69
rs 10
wmc 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A markWordUsed() 0 4 1
A getWordLike() 0 15 2
A getRandomWord() 0 9 1
A setWordsCollection() 0 8 2
A getRandomWordLength() 0 15 4
1
<?php
2
3
namespace CustomD\WordFinder\Traits;
4
5
use RuntimeException;
6
use Illuminate\Support\Collection;
7
8
trait HasWordCollection
9
{
10
11
    /**
12
     * Database of words to choose from
13
     */
14
    protected Collection $wordsCollection;
15
16
17
    protected function setWordsCollection(Collection $wordsCollection): self
18
    {
19
        $this->wordsCollection = $wordsCollection->filter(
20
            fn ($word) =>  strlen($word) >= $this->minWordLen && strlen($word) <= $this->maxWordLen
21
        )
22
        ->map(fn($word) => strtoupper($word));
23
24
        return $this;
25
    }
26
27
    protected function getRandomWordLength(array $exclude = []): int
28
    {
29
        if (count($exclude) >= ($this->maxWordLen - $this->minWordLen)) {
30
            throw new RuntimeException("Failed to generate a starting word . please add some additional words to your system");
31
        }
32
33
        do {
34
            $len = rand($this->minWordLen, $this->gridSize);
35
        } while (in_array($len, $exclude));
36
37
        $available = $this->wordsCollection->filter(fn ($word) => strlen($word) === $len)->count();
38
39
        $exclude[] = $len;
40
41
        return $available > 0 ? $len : $this->getRandomWordLength($exclude);
42
    }
43
44
    protected function markWordUsed($word): void
45
    {
46
        $this->wordsCollection = $this->wordsCollection->reject(function ($current) use ($word) {
47
            return $current === $word;
48
        });
49
    }
50
51
    protected function getRandomWord(int $len): string
52
    {
53
        $word = $this->wordsCollection->filter(function ($word) use ($len) {
54
            return strlen($word) === $len;
55
        })->random(1)->first();
56
57
        $this->markWordUsed($word);
58
59
        return $word;
60
    }
61
62
    protected function getWordLike(string $pattern): ?string
63
    {
64
        $pattern = str_replace("_", ".", $pattern);
65
        $words = $this->wordsCollection->filter(function ($word) use ($pattern) {
66
            return preg_match("/^$pattern\$/i", $word);
67
        });
68
69
        if ($words->count() === 0) {
70
            return null;
71
        }
72
73
        $word = $words->random(1)->first();
74
75
        $this->markWordUsed($word);
76
        return $word;
77
    }
78
}
79