PlayerService { public void nextStepForAllGames() { lock.writeLock().lock(); try { for (int i = 0; i < games.size(); i++) { TetrisAdvancedGame game = games.get(i); game.tick(); logger.debug("Next step. {} - {} ({},{})", new Object[]{players.get(i).getName(), game.getCurrentFigureType(), game.getCurrentFigureX(), game.getCurrentFigureY()}); } HashMap<Player, PlayerData> map = new HashMap<>(); HashMap<Player, List<Plot>> droppedPlotsMap = new HashMap<>(); for (int i = 0; i < glasses.size(); i++) { Glass glass = glasses.get(i); ArrayList<Plot> allPlots = new ArrayList<>(); allPlots.addAll(glass.getCurrentFigurePlots()); List<Plot> droppedPlots = glass.getDroppedPlots(); allPlots.addAll(droppedPlots); Player player = players.get(i); map.put(player, new PlayerData(allPlots, player.getScore(), player.getTotalRemovedLines(), player.getNextLevelIngoingCriteria(), player.getCurrentLevelNumber() + 1, player.getMessage())); droppedPlotsMap.put(player, droppedPlots); } if (sendScreenUpdates && screenSender != null && !map.isEmpty()) { screenSender.sendUpdates(map); } for (int i = 0; i < players.size(); i++) { Player player = players.get(i); TetrisAdvancedGame game = games.get(i); try { if (game.getCurrentFigureType() == null) { continue; } playerControllers.get(i).requestControl(player, game.getCurrentFigureType(), game.getCurrentFigureX(), game.getCurrentFigureY(), game, droppedPlotsMap.get(player), game.getFutureFigures()); } catch (IOException e) { logger.error("Unable to send control request to player " + player.getName() + " URL: " + player.getCallbackUrl(), e); } } LinkedList<TContext> contextsCopy = new LinkedList<>(playerContexts); LinkedList<Player> playersCopy = new LinkedList<>(players); Iterator<TContext> it = contextsCopy.iterator(); for (Player player : playersCopy) { afterStep(player, it.next()); } } catch (Throwable t) { logger.error("Unexpected exception in PlayerService.nextStepForAllGames", t); } finally { lock.writeLock().unlock(); } }  void savePlayerGame(String name); void loadPlayerGame(String name); Player addNewPlayer(final String name, final String callbackUrl, TContext context); void nextStepForAllGames(); void setSendScreenUpdates(boolean sendScreenUpdates); List<Player> getPlayers(); boolean alreadyRegistered(String playerName); Player findPlayer(String playerName); void updatePlayer(Player player); void updatePlayers(List<PlayerInfo> players); void clear(); Player findPlayerByIp(String ip); void removePlayerByIp(String ip); void removePlayerByName(String name); List<PlayerInfo> getPlayersGames();  }
@Test public void shouldSendCoordinatesToPlayerBoard() throws IOException { Player vasya = createPlayer("vasya"); playerService.nextStepForAllGames(); assertSentToPlayers(vasya); List<Plot> plots = getPlotsFor(vasya); assertContainsPlot(4, 19, plots); }
@Test public void shouldReturnPlotsOfCurrentAndDroppedFigures() { Player vasya = createPlayer("vasya"); forceDropFigureInGlass(3, HEIGHT, new TetrisFigure()); playerService.nextStepForAllGames(); assertSentToPlayers(vasya); List<Plot> plots = getPlotsFor(vasya); assertContainsPlot(3, 0, PlotColor.BLUE, plots); }
@Test public void shouldRequestControlFromAllPlayers() throws IOException { Player vasya = createPlayer("vasya"); Player petya = createPlayer("petya"); playerService.nextStepForAllGames(); assertSentToPlayers(vasya, petya); verify(playerController, times(2)).requestControl(playerCaptor.capture(), figureCaptor.capture(), xCaptor.capture(), yCaptor.capture(), Matchers.<TetrisJoystik>any(), plotsCaptor.capture(), futureCaptor.capture()); assertHostsCaptured("http: }
@Test public void shouldRequestControlFromAllPlayersWithGlassState() throws IOException { createPlayer("vasya"); forceDropFigureInGlass(0, HEIGHT, new TetrisFigure()); playerService.nextStepForAllGames(); verify(playerController).requestControl(playerCaptor.capture(), figureCaptor.capture(), xCaptor.capture(), yCaptor.capture(), Matchers.<TetrisJoystik>any(), plotsCaptor.capture(), futureCaptor.capture()); List<Plot> sentPlots = plotsCaptor.getValue(); assertEquals(1, sentPlots.size()); assertContainsPlot(0, 0, PlotColor.BLUE, sentPlots); List<Figure.Type> futureFigures = futureCaptor.getValue(); assertEquals(PlayerFigures.DEFAULT_FUTURE_COUNT, futureFigures.size()); }
@Test public void shouldSendAdditionalInfoToAllPlayers() throws IOException { Player vasya = createPlayer("vasya"); Player petya = createPlayer("petya"); playerService.nextStepForAllGames(); verify(screenSender).sendUpdates(screenSendCaptor.capture()); Map<Player, PlayerData> data = screenSendCaptor.getValue(); Map<String, String> expected = new HashMap<>(); expected.put("vasya", "PlayerData[Plots:[Plot{x=4, y=19, color=BLUE}, Plot{x=4, y=18, color=BLUE}, Plot{x=4, y=17, color=BLUE}, Plot{x=4, y=16, color=BLUE}], " + "Score:0, LinesRemoved:0, NextLevelIngoingCriteria:'Remove 4 lines together', CurrentLevel:1, Info:'Level 1']"); expected.put("petya", "PlayerData[Plots:[Plot{x=4, y=19, color=BLUE}, Plot{x=4, y=18, color=BLUE}, Plot{x=4, y=17, color=BLUE}, Plot{x=4, y=16, color=BLUE}], " + "Score:0, LinesRemoved:0, NextLevelIngoingCriteria:'Remove 4 lines together', CurrentLevel:1, Info:'Level 1']"); assertEquals(2, data.size()); for (Map.Entry<Player, PlayerData> entry : data.entrySet()) { assertEquals(expected.get(entry.getKey().getName()), entry.getValue().toString()); } }
@Test public void shouldNewUserHasMinimumPlayersScoresWhenLastLoggedAfterNextStep() { Player vasya = createPlayer("vasya"); forceDropFigureInAllPlayerGlasses(); Player petya = createPlayer("petya"); forceEmptyAllPlayerGlasses(); Player katya = createPlayer("katya"); playerService.nextStepForAllGames(); Player olia = createPlayer("olia"); assertEquals(olia.getScore(), katya.getScore()); assertEquals(olia.getScore(), petya.getScore()); }
@Test public void shouldSkipSendScreensWhenNoPlayers() throws IOException { playerService.nextStepForAllGames(); verify(screenSender, never()).sendUpdates(screenSendCaptor.capture()); }