/**
  * should:
  *      initiate game for player and opponent(s) with specific size
  *      each battlefield should have ships
  *      should have at least one AI controlled opponent
  *
  * @see GameBuilder::buildGame
  * @test
  */
 public function buildGame()
 {
     $request = new GameInitiationRequest($this->getSharedFixtureContent('game-initiation-requests/valid/2-players-7x7.json'));
     $game = static::$gameBuilder->buildGame($request);
     $this->assertCount(2, $game->getBattlefields());
     foreach ($game->getBattlefields() as $battlefield) {
         $this->assertCount(49, $battlefield->getCells());
         $this->assertTrue(BattlefieldModel::hasUnfinishedShips($battlefield));
     }
 }
 /**
  * @see BattlefieldModel::hasUnfinishedShips
  * @test
  */
 public function hasUnfinishedShips()
 {
     $battlefield = MockFactory::getBattlefieldMock();
     /** by default all cells are mocked as 'live water' */
     $this->assertFalse(BattlefieldModel::hasUnfinishedShips($battlefield));
     $battlefield->getCellByCoordinate('A1')->setFlags(CellModel::FLAG_SHIP);
     $this->assertTrue(BattlefieldModel::hasUnfinishedShips($battlefield));
     $battlefield->getCellByCoordinate('A1')->setFlags(CellModel::FLAG_DEAD_SHIP);
     $this->assertFalse(BattlefieldModel::hasUnfinishedShips($battlefield));
 }
        });
        it('should return 48 cells from 7x7 battlefield 48 of them not flagged with CellModel::FLAG_DEAD', function () {
            $this->battlefield->getCellByCoordinate('A1')->addFlag(CellModel::FLAG_DEAD);
            $cells = BattlefieldModel::getLiveCells($this->battlefield);
            expect($cells)->toBeA('array')->toHaveLength(48);
            $this->iterateRecievedCells($cells);
        });
        it('should return empty array from 7x7 battlefield all of them flagged with CellModel::FLAG_DEAD', function () {
            /** @var Cell $cell */
            foreach ($this->battlefield->getCells() as $cell) {
                $cell->addFlag(CellModel::FLAG_DEAD);
            }
            $cells = BattlefieldModel::getLiveCells($this->battlefield);
            expect($cells)->toBeA('array')->toHaveLength(0);
        });
    });
    /**
     * @see BattlefieldModel::hasUnfinishedShips
     */
    describe('::hasUnfinishedShips - should return true if Battlefield contains cells flagged with CellModel::FLAG_SHIP and not flagged with CellModel::FLAG_DEAD', function () {
        it('should return false', function () {
            $battlefield = MockFactory::getBattlefieldMock();
            expect(BattlefieldModel::hasUnfinishedShips($battlefield))->toBe(false);
        });
        it('should return true', function () {
            $battlefield = MockFactory::getBattlefieldMock();
            $battlefield->getCellByCoordinate('A1')->addFlag(CellModel::FLAG_SHIP);
            expect(BattlefieldModel::hasUnfinishedShips($battlefield))->toBe(true);
        });
    });
});
 /**
  * invoke game processing method on Unfinished Game
  *
  * @see     GameProcessor::processTurn
  * @test
  *
  * @depends processTurnOnFinishedGame
  */
 public function processTurnToNotWin()
 {
     $game = MockFactory::getGameMock();
     $aiBattlefield = $game->getBattlefields()[0];
     $aiBattlefield->setPlayer(MockFactory::getAIPlayerMock(''));
     foreach ($game->getBattlefields() as $battlefield) {
         $battlefield->getCellByCoordinate('A1')->addFlag(CellModel::FLAG_SHIP);
         $battlefield->getCellByCoordinate('A2')->addFlag(CellModel::FLAG_SHIP);
     }
     $game = static::$gameProcessor->processTurn($aiBattlefield->getCellByCoordinate('A1'));
     foreach ($game->getBattlefields() as $battlefield) {
         $this->assertCount(48, BattlefieldModel::getLiveCells($battlefield));
         /** as one cell should be dead */
         $this->assertTrue(BattlefieldModel::hasUnfinishedShips($battlefield));
     }
     $this->assertTrue($aiBattlefield->getCellByCoordinate('A1')->hasFlag(CellModel::FLAG_DEAD_SHIP));
     $this->assertNull($game->getResult());
 }
 /**
  * @since 21.0
  *
  * @param Battlefield $battlefield
  * @param Player      $attacker
  * @param Cell        $cell
  *
  * @return bool - true if target battlefield do not have any life ships, otherwise false
  * @throws GameProcessorException
  */
 protected function processPlayerTurnOnBattlefield(Battlefield $battlefield, Player $attacker, Cell $cell) : bool
 {
     /** do not process turn on itself */
     if ($battlefield->getPlayer() === $attacker) {
         throw new GameProcessorException('player attacked itself');
     }
     $cell = $this->processPlayerTurn($battlefield, $cell);
     if (CellModel::isShipDead($cell)) {
         BattlefieldModel::flagWaterAroundShip($cell);
         return !BattlefieldModel::hasUnfinishedShips($battlefield);
     }
     return false;
 }