/**
  * @param string $mast
  * @param CoordsCollection $allShips
  * @param CoordsCollection $allShots
  * @param string $offset
  * @return bool
  */
 private function remainingMastInDirectionExists($mast, CoordsCollection $allShips, CoordsCollection $allShots, $offset)
 {
     while ($allShips->contains($mast)) {
         if (!$allShots->contains($mast)) {
             return true;
         }
         $mast = $this->coordsManager->getByOffset($mast, $offset);
     }
     return false;
 }
 /**
  * @inheritdoc
  */
 public function validate($value, Constraint $constraint)
 {
     if (!$constraint instanceof EventValue) {
         throw new UnexpectedTypeException($constraint, sprintf('%s\\EventValue', __NAMESPACE__));
     }
     if (!$value instanceof Event) {
         throw new UnexpectedTypeException($value, 'AppBundle\\Entity\\Event');
     }
     switch ($value->getType()) {
         case Event::TYPE_SHOT:
             $this->coordsManager->validateCoords($value->getValue());
             break;
         default:
             break;
     }
 }
 /**
  * @param CoordsCollection $shipsCollection
  * @throws InvalidShipsException
  */
 private function validateShipsTypes(CoordsCollection $shipsCollection)
 {
     // sizes of ships to be count
     $shipsTypes = [1 => 0, 2 => 0, 3 => 0, 4 => 0];
     // B3 (index 12), going 2 down and 3 left is D6 (index 35), so 12 + (2 * 10) + (3 * 1) = 35
     $directionOffsets = [CoordsManager::OFFSET_RIGHT, CoordsManager::OFFSET_BOTTOM];
     $checkedCoordsCollection = new CoordsCollection();
     foreach ($shipsCollection as $shipCoords) {
         // we ignore masts which have already been marked as a part of a ship
         if ($checkedCoordsCollection->contains($shipCoords)) {
             continue;
         }
         $shipLength = 1;
         foreach ($directionOffsets as $offset) {
             $checkCoords = $this->coordsManager->getByOffset($shipCoords, $offset);
             // check for masts until the battleground border is reached
             while ($shipsCollection->contains($checkCoords)) {
                 // ship is too long
                 if (++$shipLength > self::MAX_SHIP_LENGTH) {
                     throw new InvalidShipsException(sprintf('Ships can\'t have more than %d masts', self::MAX_SHIP_LENGTH));
                 }
                 // mark the mast as already checked
                 $checkedCoordsCollection->append($checkCoords);
                 $checkCoords = $this->coordsManager->getByOffset($checkCoords, $offset);
             }
             // masts found so don't look for more
             if ($shipLength > 1) {
                 break;
             }
         }
         $shipsTypes[$shipLength]++;
     }
     // whether the number of different ship types is correct
     $diff = array_diff_assoc($shipsTypes, [1 => 4, 2 => 3, 3 => 2, 4 => 1]);
     if (!empty($diff)) {
         throw new InvalidShipsException('Number of ships\' types is incorrect');
     }
 }
 /**
  * @expectedException \AppBundle\Exception\InvalidOffsetException
  * @expectedExceptionMessage Invalid offset provided: invalidOffset
  */
 public function testGetByOffsetThrowsExceptionOnIncorrectOffset()
 {
     $this->coordsManager->getByOffset('coords', 'invalidOffset');
 }