/** * @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'); }