/** * should: * initiate game for player and opponent(s) with specific size * each battlefield should have ships * should have at least one AI controlled opponent * * @see GameBuilder::buildGame * @test */ public function buildGame() { $request = new GameInitiationRequest($this->getSharedFixtureContent('game-initiation-requests/valid/2-players-7x7.json')); $game = static::$gameBuilder->buildGame($request); $this->assertCount(2, $game->getBattlefields()); foreach ($game->getBattlefields() as $battlefield) { $this->assertCount(49, $battlefield->getCells()); $this->assertTrue(BattlefieldModel::hasUnfinishedShips($battlefield)); } }
/** * @param Battlefield $battlefield * * @return Cell * @throws AIException * @throws CellException */ public function processCPUTurn(Battlefield $battlefield) : Cell { $cells = $this->strategyService->chooseCells($battlefield); try { return self::pickCellToAttack($cells); } catch (CellException $e) { $cells = BattlefieldModel::getLiveCells($battlefield); return self::pickCellToAttack($cells); } }
/** * @see BattlefieldModel::flagWaterAroundShip * @test */ public function flagWaterAroundShipOnA1AlreadyDead() { $battlefield = MockFactory::getBattlefieldMock(); $battlefield->getCellByCoordinate('A1')->setFlags(CellModel::FLAG_DEAD); $cell = $battlefield->getCellByCoordinate('B2')->setFlags(CellModel::FLAG_SHIP); BattlefieldModel::flagWaterAroundShip($cell); foreach (['A2', 'A3', 'B1', 'B3', 'C1', 'C2', 'C3'] as $coordinate) { $this->assertTrue($battlefield->getCellByCoordinate($coordinate)->hasFlag(CellModel::FLAG_SKIP)); } }
public function buildGame(GameInitiationRequest $request) : Game { $game = new Game(); $this->attachAIBattlefields($game, $request->getOpponents(), $request->getSize()); $player = $this->playerModel->createOnRequestHumanControlled($request->getPlayerName()); $battlefield = BattlefieldModel::generate($request->getSize(), $request->getCoordinates()); $battlefield->setPlayer($player); $game->addBattlefield($battlefield); /** for test purposes only - mark player cells as damaged */ $battlefield->getCellByCoordinate('A2')->setFlags(CellModel::FLAG_DEAD_SHIP); $battlefield->getCellByCoordinate('A1')->setFlags(CellModel::FLAG_DEAD_SHIP); return $game; }
public static function getBattlefieldMock(int $size = 7) : Battlefield { $battlefield = BattlefieldModel::generate($size)->setPlayer(static::getPlayerMock('')); return $battlefield; }
}); it('should return 48 cells from 7x7 battlefield 48 of them not flagged with CellModel::FLAG_DEAD', function () { $this->battlefield->getCellByCoordinate('A1')->addFlag(CellModel::FLAG_DEAD); $cells = BattlefieldModel::getLiveCells($this->battlefield); expect($cells)->toBeA('array')->toHaveLength(48); $this->iterateRecievedCells($cells); }); it('should return empty array from 7x7 battlefield all of them flagged with CellModel::FLAG_DEAD', function () { /** @var Cell $cell */ foreach ($this->battlefield->getCells() as $cell) { $cell->addFlag(CellModel::FLAG_DEAD); } $cells = BattlefieldModel::getLiveCells($this->battlefield); expect($cells)->toBeA('array')->toHaveLength(0); }); }); /** * @see BattlefieldModel::hasUnfinishedShips */ describe('::hasUnfinishedShips - should return true if Battlefield contains cells flagged with CellModel::FLAG_SHIP and not flagged with CellModel::FLAG_DEAD', function () { it('should return false', function () { $battlefield = MockFactory::getBattlefieldMock(); expect(BattlefieldModel::hasUnfinishedShips($battlefield))->toBe(false); }); it('should return true', function () { $battlefield = MockFactory::getBattlefieldMock(); $battlefield->getCellByCoordinate('A1')->addFlag(CellModel::FLAG_SHIP); expect(BattlefieldModel::hasUnfinishedShips($battlefield))->toBe(true); }); }); });
/** * invoke game processing method on Unfinished Game * * @see GameProcessor::processTurn * @test * * @depends processTurnOnFinishedGame */ public function processTurnToNotWin() { $game = MockFactory::getGameMock(); $aiBattlefield = $game->getBattlefields()[0]; $aiBattlefield->setPlayer(MockFactory::getAIPlayerMock('')); foreach ($game->getBattlefields() as $battlefield) { $battlefield->getCellByCoordinate('A1')->addFlag(CellModel::FLAG_SHIP); $battlefield->getCellByCoordinate('A2')->addFlag(CellModel::FLAG_SHIP); } $game = static::$gameProcessor->processTurn($aiBattlefield->getCellByCoordinate('A1')); foreach ($game->getBattlefields() as $battlefield) { $this->assertCount(48, BattlefieldModel::getLiveCells($battlefield)); /** as one cell should be dead */ $this->assertTrue(BattlefieldModel::hasUnfinishedShips($battlefield)); } $this->assertTrue($aiBattlefield->getCellByCoordinate('A1')->hasFlag(CellModel::FLAG_DEAD_SHIP)); $this->assertNull($game->getResult()); }
/** * @since 21.0 * * @param Battlefield $battlefield * @param Player $attacker * @param Cell $cell * * @return bool - true if target battlefield do not have any life ships, otherwise false * @throws GameProcessorException */ protected function processPlayerTurnOnBattlefield(Battlefield $battlefield, Player $attacker, Cell $cell) : bool { /** do not process turn on itself */ if ($battlefield->getPlayer() === $attacker) { throw new GameProcessorException('player attacked itself'); } $cell = $this->processPlayerTurn($battlefield, $cell); if (CellModel::isShipDead($cell)) { BattlefieldModel::flagWaterAroundShip($cell); return !BattlefieldModel::hasUnfinishedShips($battlefield); } return false; }