/** * @param Ship $ship * @param Hole $hole * @param Position $position * * @return Grid * * @throws ShipAlreadyPlacedException */ public function placeShip(Ship $ship, Hole $hole, Position $position) { $grid = static::fromGrid($this); $shipId = $ship->id(); if (isset($grid->ships[$shipId])) { throw new ShipAlreadyPlacedException(); } for ($i = 0; $i < $ship->size(); ++$i) { $x = Hole::letterToNumber($hole->letter()) + ($position->equals(Position::fromVertical()) ? $i : 0) - 1; $y = $hole->number() + ($position->equals(Position::fromHorizontal()) ? $i : 0) - 1; if (!isset($grid->grid[$x][$y])) { throw new \OutOfBoundsException('Ship does not fit into the grid with such a hole and position'); } if ($grid->grid[$x][$y] > 0) { throw new \InvalidArgumentException('Ship overlaps with another one, please choose another space.'); } $grid->grid[$x][$y] = $ship->id(); $grid->ships[$shipId] = $ship; } return $grid; }
public function gridsAndTheirRenderingDataProvider() { return [['1111100000' . '2222000000' . '3330000000' . '4440000000' . '5500000000' . '0000000000' . '0000000000' . '0000000000' . '0000000000' . '0000000000', (new Grid())->placeShip(new Carrier(), new Hole('A', 1), Position::fromHorizontal())->placeShip(new Battleship(), new Hole('B', 1), Position::fromHorizontal())->placeShip(new Cruiser(), new Hole('C', 1), Position::fromHorizontal())->placeShip(new Submarine(), new Hole('D', 1), Position::fromHorizontal())->placeShip(new Destroyer(), new Hole('E', 1), Position::fromHorizontal())], ['4000000002' . '4000000002' . '4000000002' . '0000000002' . '0000000000' . '0000000000' . '0000000000' . '3000000005' . '3000000005' . '3000011111', (new Grid())->placeShip(new Carrier(), new Hole('J', 6), Position::fromHorizontal())->placeShip(new Battleship(), new Hole('A', 10), Position::fromVertical())->placeShip(new Cruiser(), new Hole('H', 1), Position::fromVertical())->placeShip(new Submarine(), new Hole('A', 1), Position::fromVertical())->placeShip(new Destroyer(), new Hole('H', 10), Position::fromVertical())]]; }