Test Setup Failed
Push — master ( a63fa0...36623d )
by Jesse
04:59
created

TurnPhase   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 36
c 1
b 0
f 0
dl 0
loc 111
rs 10
wmc 22

15 Methods

Rating   Name   Duplication   Size   Complexity  
A prohibitsCombat() 0 3 1
A prohibitsAttacking() 0 3 2
A startPlay() 0 3 1
A prohibitsPlaying() 0 3 2
A hasExpired() 0 5 1
A isTooFarApart() 0 3 1
A defendOrPlay() 0 8 2
A __construct() 0 8 1
A startAttack() 0 3 1
A play() 0 3 1
A isAfterCombat() 0 4 2
A defend() 0 3 1
A events() 0 3 1
A prohibitsDefending() 0 3 2
A next() 0 6 3
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\CardGame\Match;
4
5
use DateTimeInterface;
6
use Stratadox\CardGame\DomainEvent;
7
use Stratadox\CardGame\Match\Event\AttackPhaseStarted;
8
use Stratadox\CardGame\Match\Event\DefendPhaseStarted;
9
use Stratadox\CardGame\Match\Event\PlayPhaseStarted;
10
11
final class TurnPhase
12
{
13
    private const DEFEND = 0;
14
    private const PLAY = 1;
15
    private const ATTACK = 2;
16
    private const ALLOWED_TIME_FOR = [
17
        self::DEFEND => 20,
18
        self::PLAY => 20,
19
        self::ATTACK => 10,
20
    ];
21
22
    /** @var int */
23
    private $phase;
24
    /** @var DateTimeInterface */
25
    private $since;
26
    /** @var DomainEvent[] */
27
    private $events;
28
29
    private function __construct(
30
        int $phase,
31
        DateTimeInterface $since,
32
        DomainEvent ...$events
33
    ) {
34
        $this->phase = $phase;
35
        $this->since = $since;
36
        $this->events = $events;
37
    }
38
39
    public static function defendOrPlay(
40
        bool $shouldWeDefend,
41
        DateTimeInterface $now,
42
        MatchId $match
43
    ): self {
44
        return $shouldWeDefend ?
45
            self::defend($now, $match) :
46
            self::play($now, $match);
47
    }
48
49
    public static function play(DateTimeInterface $now, MatchId $match): self
50
    {
51
        return new self(TurnPhase::PLAY, $now, new PlayPhaseStarted($match));
52
    }
53
54
    private static function defend(DateTimeInterface $now, MatchId $match): self
55
    {
56
        return new self(TurnPhase::DEFEND, $now, new DefendPhaseStarted($match));
57
    }
58
59
60
    public function prohibitsDefending(DateTimeInterface $now): bool
61
    {
62
        return $this->phase !== TurnPhase::DEFEND || $this->hasExpired($now);
63
    }
64
65
    public function prohibitsPlaying(DateTimeInterface $now): bool
66
    {
67
        return $this->phase !== TurnPhase::PLAY || $this->hasExpired($now);
68
    }
69
70
    public function prohibitsAttacking(DateTimeInterface $now): bool
71
    {
72
        return $this->phase !== TurnPhase::ATTACK || $this->hasExpired($now);
73
    }
74
75
    public function prohibitsCombat(): bool
76
    {
77
        return $this->phase !== TurnPhase::DEFEND;
78
    }
79
80
    public function isAfterCombat(): bool
81
    {
82
        return $this->phase === TurnPhase::PLAY
83
            || $this->phase === TurnPhase::ATTACK;
84
    }
85
86
    public function hasExpired(DateTimeInterface $now): bool
87
    {
88
        return $this->isTooFarApart(
89
            $now->getTimestamp(),
90
            $this->since->getTimestamp()
91
        );
92
    }
93
94
    public function startPlay(DateTimeInterface $now, MatchId $match): TurnPhase
95
    {
96
        return new self(TurnPhase::PLAY, $now, new PlayPhaseStarted($match));
97
    }
98
99
    public function startAttack(DateTimeInterface $now, MatchId $match): TurnPhase
100
    {
101
        return new self(TurnPhase::ATTACK, $now, new AttackPhaseStarted($match));
102
    }
103
104
    /** @throws NoNextPhase|NeedCombatFirst */
105
    public function next(DateTimeInterface $now, MatchId $match): TurnPhase
106
    {
107
        switch ($this->phase) {
108
            case self::DEFEND:  throw NeedCombatFirst::cannotJustSwitchPhase();
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
109
            case self::PLAY: return $this->startAttack($now, $match);
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
110
            default: throw NoNextPhase::available();
0 ignored issues
show
Coding Style introduced by
The default body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a default statement must start on the line immediately following the statement.

switch ($expr) {
    default:
        doSomething(); //right
        break;
}


switch ($expr) {
    default:

        doSomething(); //wrong
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
111
        }
112
    }
113
114
    public function events(): array
115
    {
116
        return $this->events;
117
    }
118
119
    private function isTooFarApart(int $nowTime, int $backThenTime): bool
120
    {
121
        return $nowTime - $backThenTime >= self::ALLOWED_TIME_FOR[$this->phase];
122
    }
123
}
124