Passed
Push — master ( f388d7...367320 )
by Paweł
03:15
created

LevelProgress::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 5
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 2
crap 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\Talent\TalentPoints;
9
use AardsGerds\Game\Player\Player;
10
11
final class LevelProgress
12
{
13
    private Experience $experienceNeededForNextLevel;
14
15 4
    public function __construct(
16
        private Level $level,
17
        private Experience $currentExperience,
18
    ) {
19 4
        $this->calculateExperienceNeededForNextLevel();
20 4
    }
21
22
    /**
23
     * @example
24
     * level: 1
25
     * current experience: 500
26
     * experience needed for next level: 1000
27
     * increase experience by 600
28
     *
29
     * expected:
30
     * level: 2
31
     * current experience: 1100
32
     * experience needed for next level: 2000
33
     */
34 4
    public function increase(Experience $experience, Player $player): void
35
    {
36 4
        $this->currentExperience->increaseBy($experience);
37
38 4
        while ($this->currentExperience->isGreaterThanOrEqual($this->experienceNeededForNextLevel)) {
39 4
            $this->levelUp($player);
40
        }
41 4
    }
42
43 4
    public function getLevel(): Level
44
    {
45 4
        return $this->level;
46
    }
47
48 4
    public function getCurrentExperience(): Experience
49
    {
50 4
        return $this->currentExperience;
51
    }
52
53 4
    private function levelUp(Player $player): void
54
    {
55 4
        $this->level->increment();
56 4
        $this->calculateExperienceNeededForNextLevel();
57
58 4
        $player->getAttributePoints()->increaseBy(new AttributePoints(5));
59 4
        $player->getTalentPoints()->increaseBy(new TalentPoints(3));
60 4
    }
61
62 4
    private function calculateExperienceNeededForNextLevel(): void
63
    {
64 4
        $this->experienceNeededForNextLevel = new Experience(0);
65
66 4
        for ($level = 2; $level <= $this->level->get() + 1; $level++) {
67 4
            $this->experienceNeededForNextLevel->increaseBy($this->getExperienceNeededFor(new Level($level)));
68
        }
69 4
    }
70
71 4
    private function getExperienceNeededFor(Level $level): Experience
72
    {
73
        return match (true) {
74 4
            $level->isGreaterThan(new Level(20)) => new Experience(3000),
75 4
            $level->isGreaterThan(new Level(10)) => new Experience(2000),
76 4
            default => new Experience(1000),
77
        };
78
    }
79
}
80