Многопоточность в java-score список неизвестного количества игроков

Я работаю над простой серверно-клиентской игрой в кости для университетского проекта. Ограничение игры заключается в том, что может быть бесконечное количество игроков. Я пытаюсь создать список их баллов, но я понятия не имею, как передать количество игроков, так как каждый раз, когда следующий игрок подключается, сервер принимает новое соединение, поэтому я не могу предотвратить запуск следующего потока.

Я думал о чем-то вроде кнопки «PLAY»/булевой переменной во время ожидания игроков, и сразу после запуска игры следующий поток будет недоступен для запуска.Однако я понятия не имею, как это осуществить. Есть предложения? Другая идея также была бы хорошим предложением 🙂

Вот фрагмент кода с сервера:

 public void initializeResultList(int amountOfPlayers){
    final ArrayList<Object> resultDescription = new ArrayList();
    ArrayList<Object> zeros = new ArrayList(); 
    resultDescription.add("Player");
    resultDescription.add("One Pair");
    resultDescription.add("Two Pairs");
    resultDescription.add("Three of a kind");
    resultDescription.add("Full House");
    resultDescription.add("Four of a kind");
    resultDescription.add("Five of a kind");
    for (int j = 0; j < resultDescription.size(); j++){
        zeros.add(null);
    }
    resultList.add(resultDescription);
    //fill with nulls, then there will be player Scores
    for (int i = 1; i <= amountOfPlayers; i++){
        resultList.add(zeros);
    }

}

 public static void main(String args[]) throws IOException {


    int portNumber = 444;

    ServerSocket serverSocket = null;


    try {
        serverSocket = new ServerSocket(portNumber);
    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("Error finding port");
        System.exit(1);
    }

    // program loop
    do {
        Server server = new Server(serverSocket.accept());

        //HERE IS THE PROBLEM!
        server.initializeResultList(2); // here should be passed the amount
        server.start();
    } while (true);

}

@Override
public void run(){
    System.out.println("Connection accepted");
    System.out.println("Client has successfully connected");
}

Вот код из класса игрока (это не проблема прямо сейчас, но, возможно, вы хотели бы знать, как сервер и игрок общается):

  public static void main (String args[]) throws IOException {
    //Connect to the server
    Socket socket = null;
    int portNumber = 444;
    String str;
    BufferedReader br = null;
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter out = null;

    try {
        socket = new Socket(InetAddress.getLocalHost(), portNumber);
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new PrintWriter(socket.getOutputStream(), true);
    } catch (UnknownHostException uhe) {
        System.out.println("Unknown Host");
        System.exit(0);
    }


    boolean quit = false;

    while (!quit) {

        str = input.readLine();
        out.println(str);
    }


}

1 ответ

  1. для этого существует несколько возможных реализаций. Тот, что приходит на ум, включает в себя очередь игроков. Таким образом, каждый раз, когда новый игрок подключается, он сидит в очереди, пока приложение не заберет его. Размер очереди может быть добавлен к локальному счетчику, чтобы получить общее количество игроков. После того, как вы вытащили игрока, он ушел из очереди.
    Например, вы можете инициализировать очередь следующим образом:

    Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>();
    

    Мы выбираем параллельную связанную очередь из-за ее свойств, которые вы можете проверить здесь . При добавлении нового пользователя можно поставить плеер в очередь с:

    queue.offer(myObject);
    

    находясь в сервлете, например в конце каждого раунда или когда вам нужен новый игрок, вы можете вызвать:

    YourObject myObject = queue.poll();
    

    или вы можете получить количество новых игроков вызова:

    int nrNewPlayers = queue.size();

    Если вам нужен объект игрока, содержащий также информацию и статистику о самом игроке, это хорошее решение. Однако если вам действительно нужно только общее количество игроков, то очередь избыточна, и вы можете просто использовать целое число tomic следующим образом:

    //Initialize the integer in constructor
    public static AtomicInteger userCounter = new AtomicInteger(0);
    
    //Increment number of users when a new user is added ()
    userCounter.incrementAndGet();
    
    //Decrement the number of users when a user disconnects
    userCounter.decrementAndGet();
    
    //Get number of users from within your code
    int counter = userCounter.intValue();
    

    таким образом, ваш серверный код будет:

    //HERE IS THE PROBLEM!
    int counter = userCounter.intValue();
    server.initializeResultList(counter); // here should be passed the amount
    

    Это лучшее, что я могу сделать с кодом, который вы предоставили. Если вам нужна дополнительная помощь, пожалуйста, создайте новый вопрос и предоставьте больше кода вместо фрагментов и лучшее объяснение того, что вам нужно. Надеюсь,что это поможет вам.