/**
  * @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 function addBattlefield(Battlefield $battlefield) : self
 {
     $this->battlefields[] = $battlefield;
     if (PlayerModel::isAIControlled($battlefield->getPlayer())) {
         foreach ($battlefield->getCells() as $cell) {
             $cell->setFlags(CellModel::FLAG_NONE);
         }
     }
     return $this;
 }
 public static function generate(int $size, array $coordinates = []) : Battlefield
 {
     $battlefield = new Battlefield();
     for ($x = 0, $letter = static::INDEX_START; $x < $size; $letter++, $x++) {
         for ($digit = 0; $digit < $size;) {
             $coordinate = $letter . ++$digit;
             $cell = (new Cell())->setCoordinate($coordinate)->setFlags(in_array($coordinate, $coordinates) ? CellModel::FLAG_SHIP : CellModel::FLAG_NONE);
             $battlefield->addCell($cell);
         }
     }
     return $battlefield;
 }
 /**
  * @param Battlefield $battlefield
  * @param int         $path
  * @param string      $coordinate
  *
  * @return Cell
  * @throws CellException
  */
 protected function processPath(Battlefield $battlefield, int $path, string $coordinate) : Cell
 {
     $processor = (new PathProcessor($coordinate))->setPath($path);
     while (null !== ($cell = $battlefield->getCellByCoordinate($processor->calculateNextCoordinate()))) {
         if ($cell->hasFlag(CellModel::FLAG_DEAD)) {
             if ($cell->hasFlag(CellModel::FLAG_SHIP)) {
                 continue;
             }
             /** if it is not dead ship - terminate processing */
             throw new CellException("cell: {$cell->getId()} already dead and is not ship");
         }
         return $cell;
     }
     throw new CellException("unable to find cell using path: {$path} from coordinate: {$coordinate}");
 }
 /**
  * @see GameProcessor::processPlayerTurnOnBattlefield
  *
  * @param Battlefield $battlefield
  * @param Player      $attacker
  *
  * @return bool
  * @throws GameProcessorException
  */
 private function processPlayerTurnOnBattlefield(Battlefield $battlefield, Player $attacker)
 {
     return $this->invokeMethod(static::$gameProcessor, 'processPlayerTurnOnBattlefield', [$battlefield, $attacker, $battlefield->getCellByCoordinate('A1')]);
 }
 /**
  * @since 19.0
  *
  * @param Battlefield $battlefield
  *
  * @return Cell
  * @throws CellException
  */
 protected function findCellByCurrentCoordinate(Battlefield $battlefield) : Cell
 {
     if (null !== ($cell = $battlefield->getCellByCoordinate($this->currentCoordinate))) {
         return $cell;
     }
     throw new CellException("{$battlefield->getId()} do not contain cell with coordinate: {$this->currentCoordinate}");
 }
 public function addBattlefield(Battlefield $battlefield) : self
 {
     $battlefield->setGame($this);
     $this->battlefields->add($battlefield);
     return $this;
 }
 /**
  * @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);
 }