LevelProgress   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 9
eloc 23
c 1
b 0
f 0
dl 0
loc 70
ccs 31
cts 31
cp 1
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getCurrentExperience() 0 3 1
A getLevel() 0 3 1
A increase() 0 8 2
A __construct() 0 5 1
A levelUp() 0 9 1
A calculateExperienceNeededForNextLevel() 0 6 2
A getRequiredExperience() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AardsGerds\Game\Build;
6
7
use AardsGerds\Game\Build\Attribute\AttributePoints;
8
use AardsGerds\Game\Build\Attribute\Health;
9
use AardsGerds\Game\Build\Talent\TalentPoints;
10
use AardsGerds\Game\Player\Player;
11
use AardsGerds\Game\Player\PlayerAction;
12
13
final class LevelProgress
14
{
15
    private Experience $experienceNeededForNextLevel;
16
17 6
    public function __construct(
18
        private Level $level,
19
        private Experience $currentExperience,
20
    ) {
21 6
        $this->calculateExperienceNeededForNextLevel();
22 6
    }
23
24
    /**
25
     * @example
26
     * level: 1
27
     * current experience: 500
28
     * experience needed for next level: 1000
29
     * increase experience by 600
30
     *
31
     * expected:
32
     * level: 2
33
     * current experience: 1100
34
     * experience needed for next level: 2000
35
     */
36 4
    public function increase(Experience $experience, Player $player, PlayerAction $playerAction): void
37
    {
38 4
        $this->currentExperience->increaseBy($experience);
39 4
        $playerAction->tell("You have gained {$experience} experience!");
40
41 4
        while ($this->currentExperience->isGreaterThanOrEqual($this->experienceNeededForNextLevel)) {
42 4
            $this->levelUp($player);
43 4
            $playerAction->tell("You have gained new level!");
44
        }
45 4
    }
46
47 5
    public function getLevel(): Level
48
    {
49 5
        return $this->level;
50
    }
51
52 5
    public function getCurrentExperience(): Experience
53
    {
54 5
        return $this->currentExperience;
55
    }
56
57 4
    private function levelUp(Player $player): void
58
    {
59 4
        $this->level->increment();
60 4
        $this->calculateExperienceNeededForNextLevel();
61
62 4
        $player->getMaximumHealth()->increaseBy(new Health(20));
63 4
        $player->getAttributePoints()->increaseBy(new AttributePoints(5));
64 4
        $player->getTalentPoints()->increaseBy(new TalentPoints(3));
65 4
        $player->healCompletely();
66 4
    }
67
68 8
    private function calculateExperienceNeededForNextLevel(): void
69
    {
70 8
        $this->experienceNeededForNextLevel = new Experience(0);
71
72 8
        for ($level = 2; $level <= $this->level->get() + 1; $level++) {
73 8
            $this->experienceNeededForNextLevel->increaseBy(self::getRequiredExperience(new Level($level)));
74
        }
75 8
    }
76
77 8
    private static function getRequiredExperience(Level $level): Experience
78
    {
79
        return match (true) {
80 8
            $level->isGreaterThan(new Level(10)) => new Experience(2000),
81 8
            $level->isGreaterThan(new Level(20)) => new Experience(3000),
82 8
            default => new Experience(1000),
83
        };
84
    }
85
}
86