Esempio n. 1
0
  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();
  }
Esempio n. 2
0
 public synchronized boolean doMove(JSONObject o) {
   // TODO verify that this is all exactly right
   try {
     String direction = o.getString("direction");
     if (direction.equals("up")) {
       if (position.up != null && position.up.isAccessible()) {
         if (position.up.playerOnTile != null) {
           throw new ProtocolException(
               "Player " + position.up.playerOnTile.username + " is already on this tile.");
         }
         position.playerOnTile = null;
         position = position.up;
         position.playerOnTile = this;
         return true;
       } else {
         throw Util.throwInaccessibleTileException("up", position.up);
       }
     } else if (direction.equals("down")) {
       if (position.down != null && position.down.isAccessible()) {
         if (position.down.playerOnTile != null) {
           throw new ProtocolException(
               "Player " + position.down.playerOnTile.username + " is already on this tile.");
         }
         position.playerOnTile = null;
         position = position.down;
         position.playerOnTile = this;
         return true;
       } else {
         throw Util.throwInaccessibleTileException("down", position.down);
       }
     } else if (direction.equals("left-down")) {
       if (position.leftDown != null && position.leftDown.isAccessible()) {
         if (position.leftDown.playerOnTile != null) {
           throw new ProtocolException(
               "Player " + position.leftDown.playerOnTile.username + " is already on this tile.");
         }
         position.playerOnTile = null;
         position = position.leftDown;
         position.playerOnTile = this;
         return true;
       } else {
         throw Util.throwInaccessibleTileException("left-down", position.leftDown);
       }
     } else if (direction.equals("left-up")) {
       if (position.leftUp != null && position.leftUp.isAccessible()) {
         if (position.leftUp.playerOnTile != null) {
           throw new ProtocolException(
               "Player " + position.leftUp.playerOnTile.username + " is already on this tile.");
         }
         position.playerOnTile = null;
         position = position.leftUp;
         position.playerOnTile = this;
         return true;
       } else {
         throw Util.throwInaccessibleTileException("left-up", position.leftUp);
       }
     } else if (direction.equals("right-down")) {
       if (position.rightDown != null && position.rightDown.isAccessible()) {
         if (position.rightDown.playerOnTile != null) {
           throw new ProtocolException(
               "Player " + position.rightDown.playerOnTile.username + " is already on this tile.");
         }
         position.playerOnTile = null;
         position = position.rightDown;
         position.playerOnTile = this;
         return true;
       } else {
         throw Util.throwInaccessibleTileException("right-down", position.rightDown);
       }
     } else if (direction.equals("right-up")) {
       if (position.rightUp != null && position.rightUp.isAccessible()) {
         if (position.rightUp.playerOnTile != null) {
           throw new ProtocolException(
               "Player " + position.rightUp.playerOnTile.username + " is already on this tile.");
         }
         position.playerOnTile = null;
         position = position.rightUp;
         position.playerOnTile = this;
         return true;
       } else {
         throw Util.throwInaccessibleTileException("right-up", position.rightUp);
       }
     } else {
       throw new ProtocolException("Invalid direction: '" + direction + "'");
     }
   } catch (JSONException e) {
     try {
       JSONObject errorMessage =
           new JSONObject().put("error", "Invalid move packet: " + e.getMessage());
       sendMessage(errorMessage);
     } catch (JSONException f) {
     } catch (IOException g) {
     }
     return false;
   } catch (ProtocolException e) {
     try {
       JSONObject errorMessage =
           new JSONObject().put("error", "Invalid move packet: " + e.getMessage());
       sendMessage(errorMessage);
     } catch (JSONException f) {
     } catch (IOException g) {
     }
     return false;
   }
 }