/**
  * @param Cell $cell
  *
  * @return Cell
  * @throws AIException
  */
 private static function attackCell(Cell $cell) : Cell
 {
     if ($cell->hasFlag(CellModel::FLAG_DEAD)) {
         throw new AIException("cell: {$cell->getId()} already flagged as *DEAD*");
     }
     return CellModel::switchPhase($cell);
 }
 /**
  * @param Battlefield $battlefield
  *
  * @return Cell[]
  */
 public function chooseCells(Battlefield $battlefield) : array
 {
     foreach ($battlefield->getCells() as $cell) {
         if (!$cell->hasFlag(CellModel::FLAG_DEAD_SHIP) || CellModel::isShipDead($cell)) {
             continue;
         }
         return $this->processor->process($cell, $this->chooseStrategy($cell));
     }
     return [];
 }
 public static function flagWaterAroundShip(Cell $cell)
 {
     $processor = new PathProcessor($cell->getCoordinate());
     $battlefield = $cell->getBattlefield();
     $cells = $processor->getAdjacentCells($cell->getBattlefield(), 4, CellModel::FLAG_SHIP);
     $cells[$cell->getCoordinate()] = $cell;
     foreach ($cells as $cell) {
         foreach ($processor->reset($cell->getCoordinate())->getAdjacentCells($battlefield, 1, 0, CellModel::FLAG_SHIP) as $waterCell) {
             CellModel::switchPhase($waterCell, CellModel::FLAG_SKIP);
         }
     }
 }
 /**
  * @see     CellModel::getChangedCells
  * @test
  *
  * @depends switchPhase
  * @depends switchPhaseWithAdditionalFlag
  */
 public function getChangedCells()
 {
     $this->assertContainsOnlyInstancesOf(Cell::class, CellModel::getChangedCells());
     $this->assertGreaterThanOrEqual(1, count(CellModel::getChangedCells()));
 }
 /**
  * @see GameControllerTest::successfulTurnAction
  * @see GameControllerTest::unsuccessfulTurnActionOnDeadCell
  *
  * @ApiDoc(
  *      section = "Game:: Mechanics",
  *      description = "process game turn by cellId",
  *      output = "EM\GameBundle\Response\GameTurnResponse",
  *      statusCodes = {
  *          200 = "successful turn",
  *          404 = "cell do not exists",
  *          422 = "cell already flagged as DEAD"
  *      }
  * )
  *
  * @param int $cellId
  *
  * @return Response
  * @throws CellException
  * @throws GameProcessorException
  */
 public function turnAction(int $cellId) : Response
 {
     if (null === ($cell = $this->getDoctrine()->getRepository('GameBundle:Cell')->find($cellId))) {
         throw new CellException(Response::HTTP_NOT_FOUND, "cell: {$cellId} do not exist");
     }
     if ($cell->hasFlag(CellModel::FLAG_DEAD)) {
         throw new CellException(Response::HTTP_UNPROCESSABLE_ENTITY, "cell: {$cellId} already flagged as *DEAD*");
     }
     $game = $this->get('battleship_game.service.game_processor')->processTurn($cell);
     $om = $this->getDoctrine()->getManager();
     foreach (CellModel::getChangedCells() as $cell) {
         $om->persist($cell);
     }
     $om->flush();
     return $this->prepareSerializedResponse(new GameTurnResponse($game, CellModel::getChangedCells()));
 }
 /**
  * @param Battlefield $battlefield
  * @param Cell        $cell - this cell will be attacked if attacker is human
  *
  * @return Cell
  */
 protected function processPlayerTurn(Battlefield $battlefield, Cell $cell) : Cell
 {
     return PlayerModel::isAIControlled($battlefield->getPlayer()) ? CellModel::switchPhase($cell) : $this->ai->processCPUTurn($battlefield);
 }