@Test public void millisBetween() { assertThat( MILLIS.between( PlainTimestamp.of(2012, 1, 31, 11, 43, 59).with(MILLI_OF_SECOND, 3), PlainTimestamp.of(2012, 2, 29, 11, 43, 59).with(MILLI_OF_SECOND, 4)), is(29 * 86400L * 1000 + 1)); assertThat( MILLIS.between( PlainTimestamp.of(2012, 1, 31, 11, 43, 59).with(MILLI_OF_SECOND, 4), PlainTimestamp.of(2012, 2, 29, 11, 43, 59).with(MILLI_OF_SECOND, 4)), is(29 * 86400L * 1000)); assertThat( MILLIS.between( PlainTimestamp.of(2012, 1, 31, 11, 43, 59).with(MILLI_OF_SECOND, 5), PlainTimestamp.of(2012, 2, 29, 11, 43, 59).with(MILLI_OF_SECOND, 4)), is(29 * 86400L * 1000 - 1)); assertThat( MILLIS.between( PlainTimestamp.of(2012, 1, 31, 11, 43, 59).with(MICRO_OF_SECOND, 3018), PlainTimestamp.of(2012, 2, 29, 11, 43, 59).with(MICRO_OF_SECOND, 3018)), is(29 * 86400L * 1000)); assertThat( MILLIS.between( PlainTimestamp.of(2012, 1, 31, 11, 43, 59).with(MICRO_OF_SECOND, 3019), PlainTimestamp.of(2012, 2, 29, 11, 43, 59).with(MICRO_OF_SECOND, 3018)), is(29 * 86400L * 1000 - 1)); assertThat( MILLIS.between( PlainTimestamp.of(2012, 1, 31, 11, 43, 59).with(MICRO_OF_SECOND, 4019), PlainTimestamp.of(2012, 2, 29, 11, 43, 59).with(MICRO_OF_SECOND, 3018)), is(29 * 86400L * 1000 - 2)); }
public static void runGame(String filename, int port, int rounds, int time) throws IOException, InterruptedException, ExecutionException { final World world; int users = 0; try { WorldParser wp = new WorldParser(); world = wp.parse(filename); users = world.getNumberOfSpawnpoints(); } catch (FileNotFoundException e) { logger.error("Map file not found: '" + filename + "'."); return; } Message info = new InfoMessage(time, rounds, filename, users); logger.info("Starting graphics server."); GraphicsServer graphics = new GraphicsServer(info, port + 10); graphics.start(); logger.info("Waiting for clients to connect."); ServerSocket socket = new ServerSocket(port); List<Player> players = new ArrayList<>(); for (int i = 0; i < users; i++) { Socket client = socket.accept(); Connection conn = new Connection(client); new Thread(conn).start(); conn.sendMessage(info); players.add(new Player(conn)); } logger.info("All clients connected."); logger.info("Setting spawnpoints."); Collections.shuffle(players); Queue<Vector2d> spawnpoints = world.getSpawnpoints(); for (Player player : players) { player.setSpawn(spawnpoints.poll()); } logger.info("Sending initial game state."); Message state0 = new GameStateMessage(0, world, players); players.stream().peek(p -> p.send(state0)); graphics.sendToAll(state0); logger.info("Recieved loadout from all."); logger.info("Starting game."); for (int round = 1; round <= rounds; round++) { for (Player player : players) { logger.info("Starting player '" + player.getName() + "' turn."); logger.info("Clearing all messages from player queue."); player.clear(); logger.info("Sending first round to all."); Message state = new GameStateMessage(round, world, players); players.stream().forEach(p -> p.send(state)); graphics.sendToAll(state); if (player.isDead()) { logger.info(player.getName() + " is dead. Respawning..."); player.respawn(); } else { List<ActionMessage> actions = new ArrayList<>(); Instant stop = Instant.now().plus(time, MILLIS); for (int a = 0; a < 3; a++) { logger.info("Waiting for action " + a + "."); long timeout = Math.max(0, MILLIS.between(Instant.now(), stop)); ActionMessage action = player.next(timeout, MILLISECONDS); if (action == null) { logger.debug( "==> Player '" + player.getName() + "' timed out in round " + round + "."); break; } try { logger.info("Performing action."); action.performAction(player, world); actions.add(action); logger.info("Successful message: " + action.toString()); players.stream().forEach(p -> p.send(action)); } catch (ProtocolException e) { logger.debug(e.getMessage()); player.send(new ErrorMessage(e)); } } logger.info("Waiting to complete round."); Thread.sleep(Math.max(0, MILLIS.between(Instant.now(), stop))); player.send(new EndTurnMessage()); logger.info("Sending actions to graphics."); for (Message m : actions) { graphics.sendToAll(m); } } } Collections.rotate(players, 1); } players.sort(comparing(Player::score)); Collections.reverse(players); players.removeIf(p -> p.score() < players.get(0).score()); String winner; if (players.size() > 1) { winner = String.format( "A %d-way tie between: %s", players.size(), String.join(", ", players.toArray(new String[players.size()]))); } else { winner = String.format("The winner is ", players.get(0)); } logger.info("Winner: " + winner); Message message = new GameFinishedMessage(winner); players.stream().forEach(p -> p.send(message)); graphics.sendToAll(message); socket.close(); }