public function __toString() { if ($this->hasSunkenShip()) { return '🔥 '; } if ($this->hit()) { return '💣 '; } if ($this->miss()) { return '💦 '; } if ($this->occupied() && $this->ship->startPoint()->equals($this->coords())) { if ($this->ship->startPoint()->x() == $this->ship->endPoint()->x()) { return '^ '; } return '< '; } if ($this->occupied() && $this->ship->endPoint()->equals($this->coords())) { if ($this->ship->startPoint()->x() == $this->ship->endPoint()->x()) { return 'v '; } return '> '; } if ($this->occupied()) { if ($this->ship->startPoint()->x() == $this->ship->endPoint()->x()) { return 'ǁ '; } return '= '; } return ' '; }
/** * @param int $width * @param int $height * @param array $shipSizes * @return Fields */ public static function generate($width, $height, array $shipSizes) { Assertion::integer($width); Assertion::integer($height); Assertion::allInteger($shipSizes); $elements = []; for ($y = 0; $y < $height; $y++) { for ($x = 0; $x < $width; $x++) { $elements[] = Field::generate($x, $y); } } $fields = Fields::create($elements); foreach ($shipSizes as $shipSize) { $attempts = 0; while (true) { if ($attempts == static::MAX_ATTEMPTS) { throw new CannotPlaceShipOnGridException(); } $direction = mt_rand(0, 1) == 0 ? 'right' : 'below'; $spot = Coords::create(mt_rand(0, $width - 1), mt_rand(0, $height - 1)); $endPoint = static::validEndpoint($fields, $spot, $shipSize, $direction); if ($endPoint === null) { $attempts++; continue; } // If we end up here the ship can fit at the determined spot $fields->place(Ship::create($spot, $endPoint)); break; } } return $fields; }
/** * @param Ship $ship */ public function place(Ship $ship) { foreach ($this->elements as $field) { if ($ship->on($field->coords())) { $field->place($ship); } } $this->ships[] = $ship; }