Passed
Push — main ( 12f820...22e7dc )
by Karl
05:52
created

DeckOfCards   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Test Coverage

Coverage 97.37%

Importance

Changes 4
Bugs 1 Features 0
Metric Value
eloc 53
c 4
b 1
f 0
dl 0
loc 158
ccs 37
cts 38
cp 0.9737
rs 10
wmc 18

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getObservers() 0 3 1
A attach() 0 3 1
A __construct() 0 6 2
A notify() 0 4 2
A detach() 0 3 1
A shuffle() 0 6 1
A getNumberOfCards() 0 3 1
A drawCards() 0 11 3
A dealCards() 0 14 3
A addCard() 0 4 1
A getDeck() 0 3 1
A hasCards() 0 3 1
1
<?php
2
3
namespace App\Model;
4
5
use Random\Randomizer;
0 ignored issues
show
Bug introduced by
The type Random\Randomizer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use SplSubject;
7
use SplObjectStorage;
8
use SplObserver;
9
use Exception;
10
11
abstract class DeckOfCards implements SplSubject
12
{
13
    /**
14
     * @var array<string> The suits of the cards in a deck.
15
     */
16
    public static $suitsOfCards = ['Spade', 'Diamond', 'Heart', 'Club'];
17
18
    public static $namesOfCards = [
19
        'Ace' => [1, 14],
20
        '2' => [2],
21
        '3' => [3],
22
        '4' => [4],
23
        '5' => [5],
24
        '6' => [6],
25
        '7' => [7],
26
        '8' => [8],
27
        '9' => [9],
28
        '10' => [10],
29
        'Jack' => [11],
30
        'Queen' => [12],
31
        'King' => [13],
32
    ];
33
    /**
34
     * @var array<Card> The array of cards in the deck.
35
     **/
36
    public array $cards = [];
37
38
    protected SplObjectStorage $observers;
39
40
    protected bool $isShuffled = false;
41
42
    protected Randomizer $randomizer;
43
44
    /**
45
     * Constructor for the DeckOfCards class.
46
     *
47
     * @param Randomizer $randomizer The randomizer object used for shuffling the deck.
48
     * @param array $observers An optional array of observer objects to attach to the deck.
49
     */
50 17
    public function __construct(Randomizer $randomizer, array $observers = [])
51
    {
52 17
        $this->randomizer = $randomizer;
53 17
        $this->observers = new SplObjectStorage();
54 17
        foreach ($observers as $observer) {
55 1
            $this->attach($observer);
56
        }
57
    }
58
59 1
    public function getObservers(): SplObjectStorage
60
    {
61 1
        return $this->observers;
62
    }
63
64 2
    public function attach(SplObserver $observer): void
65
    {
66 2
        $this->observers->attach($observer);
67
    }
68 1
    public function detach(SplObserver $observer): void
69
    {
70 1
        $this->observers->detach($observer);
71
    }
72 16
    public function notify(): void
73
    {
74 16
        foreach ($this->observers as $observer) {
75
            $observer->update($this->getDeck());
76
        }
77
    }
78
79
    abstract public static function create(Randomizer $randomizer, array $observers = []): DeckOfCards;
80
81
    abstract public function sort(): void;
82
83
    public function addCard(Card $card): void
84
    {
85
        $this->cards[] = $card;
86
        $this->notify();
87
    }
88
89
    public function shuffle(): void
90
    {
91
        // shuffle as many time as one likes today...
92
        $this->isShuffled = true;
93
        $this->cards = $this->randomizer->shuffleArray($this->cards);
94
        $this->notify();
95
    }
96
97
    /**
98
     * Get the deck of cards.
99
     *
100
     * @return array<Card> The array representing the deck of cards.
101
     */
102
    public function getDeck(): array
103
    {
104
        return $this->cards;
105 16
    }
106
107 16
    public function hasCards(): bool
108 16
    {
109
        return count($this->cards) > 0;
110
    }
111 3
112
    public function getNumberOfCards(): int
113
    {
114 3
        return count($this->cards);
115 3
    }
116 3
117
118
119
    // private function drawCard(): Card
120
    // {
121
    //     if (!$this->hasCards()) {
122
    //         throw new Exception('No cards left in the deck');
123
    //     }
124 3
    //     $card = array_pop($this->cards);
125
    //     $this->notify();
126 3
    //     return $card;
127
    // }
128
129 3
    /**
130
     * Draws a specified number of cards from the deck.
131 3
     *
132
     * @param int $numberOfCards The number of cards to draw.
133
     * @return array<Card> An array of drawn cards.
134 1
     */
135
    public function drawCards(int $numberOfCards): array
136 1
    {
137
        if (!$this->hasCards()) {
138
            throw new Exception('No cards left in the deck');
139
        }
140
        $cards = [];
141 3
        for ($i = 0; $i < $numberOfCards; $i++) {
142
            $cards[] = array_pop($this->cards);
143 3
            $this->notify();
144 1
        }
145
        return $cards;
146 3
    }
147 3
148 3
    /**
149
     * Deals a specified number of cards to a specified number of players.
150
     *
151
     * @param int $numberOfPlayers The number of players to deal cards to.
152
     * @param int $numberOfCards The number of cards to deal to each player.
153
     * @return array<CardHand> An array of CardHand objects representing the hands of each player.
154
     */
155
    public function dealCards(int $numberOfPlayers, int $numberOfCards): array
156
    {
157 2
        $hands = [];
158
        for ($i = 0; $i < $numberOfPlayers; $i++) {
159 2
            $hand = new CardHand();
160 2
            for ($j = 0; $j < $numberOfCards; $j++) {
161 2
                $card = $this->drawCards(1)[0];
162
                $hand->addCard($card);
163 1
            }
164
            $hands[] = $hand;
165
        }
166
167
        $this->notify();
168
        return $hands;
169
    }
170
}
171