Completed
Push — master ( fd525f...545ab6 )
by Eugene
54s queued 11s
created

GameProcessor::processTurn()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 12
cts 12
cp 1
rs 9.0534
c 0
b 0
f 0
cc 4
eloc 12
nc 4
nop 1
crap 4
1
<?php
2
3
namespace EM\GameBundle\Service\GameSystem;
4
5
use EM\GameBundle\Entity\Battlefield;
6
use EM\GameBundle\Entity\Cell;
7
use EM\GameBundle\Entity\Game;
8
use EM\GameBundle\Entity\GameResult;
9
use EM\GameBundle\Entity\Player;
10
use EM\GameBundle\Exception\GameProcessorException;
11
use EM\GameBundle\Model\BattlefieldModel;
12
use EM\GameBundle\Model\CellModel;
13
use EM\GameBundle\Model\PlayerModel;
14
use EM\GameBundle\Service\AI\AIService;
15
16
/**
17
 * @see   GameProcessorTest
18
 *
19
 * @since 10.0
20
 */
21
class GameProcessor
22
{
23
    /**
24
     * @var AIService
25
     */
26
    private $ai;
27
28 1
    public function __construct(AIService $ai)
29
    {
30 1
        $this->ai = $ai;
31 1
    }
32
33
    /**
34
     * @param Cell $cell
35
     *
36
     * @return Game
37
     * @throws GameProcessorException
38
     */
39 4
    public function processTurn(Cell $cell) : Game
40
    {
41 4
        $game = $cell->getBattlefield()->getGame();
42
43 4
        if (null !== $game->getResult()) {
44 1
            throw new GameProcessorException("game: {$game->getId()} already has result");
45
        }
46
47 3
        foreach ($game->getBattlefields() as $battlefield) {
48 3
            $attacker = $battlefield->getPlayer();
49 3
            if ($this->processPlayerTurnOnBattlefields($game, $attacker, $cell)) {
50 2
                $result = (new GameResult())
51 2
                    ->setPlayer($attacker);
52 2
                $game->setResult($result);
53
54 3
                break;
55
            }
56
        }
57
58 3
        return $game;
59
    }
60
61
    /**
62
     * @since 21.1
63
     *
64
     * @param Game   $game
65
     * @param Player $attacker
66
     * @param Cell   $cell
67
     *
68
     * @return bool - true if game been won, otherwise false
69
     */
70 3
    protected function processPlayerTurnOnBattlefields(Game $game, Player $attacker, Cell $cell) : bool
71
    {
72 3
        foreach ($game->getBattlefields() as $battlefield) {
73
            try {
74 3
                if ($this->processPlayerTurnOnBattlefield($battlefield, $attacker, $cell)) {
75 3
                    return true;
76
                }
77 3
            } catch (GameProcessorException $e) {
78 3
                continue;
79
            }
80
        }
81
82 2
        return false;
83
    }
84
85
    /**
86
     * @since 21.0
87
     *
88
     * @param Battlefield $battlefield
89
     * @param Player      $attacker
90
     * @param Cell        $cell
91
     *
92
     * @return bool - true if target battlefield do not have any life ships, otherwise false
93
     * @throws GameProcessorException
94
     */
95 6
    protected function processPlayerTurnOnBattlefield(Battlefield $battlefield, Player $attacker, Cell $cell) : bool
96
    {
97
        /** do not process turn on itself */
98 6
        if ($battlefield->getPlayer() === $attacker) {
99 4
            throw new GameProcessorException('player attacked itself');
100
        }
101
102 5
        $cell = $this->processPlayerTurn($battlefield, $cell);
103 5
        if (CellModel::isShipDead($cell)) {
104 3
            BattlefieldModel::flagWaterAroundShip($cell);
105
106 3
            return !BattlefieldModel::hasUnfinishedShips($battlefield);
107
        }
108
109 3
        return false;
110
    }
111
112
    /**
113
     * @param Battlefield $battlefield
114
     * @param Cell        $cell - this cell will be attacked if attacker is human
115
     *
116
     * @return Cell
117
     */
118 5
    protected function processPlayerTurn(Battlefield $battlefield, Cell $cell) : Cell
119
    {
120 5
        return PlayerModel::isAIControlled($battlefield->getPlayer())
121 5
            ? CellModel::switchPhase($cell)
122 5
            : $this->ai->processCPUTurn($battlefield);
123
    }
124
}
125