Турбазная игра - Threading java - (ходите и go спите?) - PullRequest
0 голосов
/ 27 января 2020

Я пишу настоящую игру, основанную на турне (упрощенная версия любовного письма), и я написал простой клиент, сервер и полный логик карточек и т. Д. c. Но теперь возникает проблема, как принимать входные данные только от одного многопоточного клиента и не принимать сообщения от других (итого будет 5 подключенных клиентов) - и после завершения его тура, как уведомить следующего игрока (его поток), чтобы войти data ...

Вот код моего клиента:

import ...;

public class Console_client {


    final static int ServerPort = XXXX;
    final static String ServerAddress = "";
    BufferedReader in;
    PrintWriter out;
    Scanner sc = new Scanner(System.in);

    /** Runs the client as an application with a closeable frame.*/
    public static void main(String[] args) throws Exception {
        Console_client client = new Console_client();
        client.run();
    }

    /** Connects to the server then enters the processing loop.*/
    private void run() throws IOException {

        Socket socket = new Socket(ServerAddress, ServerPort);
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new PrintWriter(socket.getOutputStream(), true);

        Thread sendMessage = new Thread(() -> {
            while (true) {
                out.println(sc.nextLine());
            }
        });

        Thread readMessage = new Thread(() -> {
            while (true) {
                try {
                    System.out.println(in.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        sendMessage.start();
        readMessage.start();
    }
}

Мой класс сервера выглядит так:

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

        System.out.println("The chat server is running.");
        ServerSocket listener = new ServerSocket(PORT);
        try {
            while (true) {
                new Handler(listener.accept()).start();
            }
        } finally {
            listener.close();
        }
    }

И обработчик:

    private static class Handler extends Thread {
        private String name;
        private Socket socket;
        private BufferedReader in;
        private PrintWriter out;

        public Handler(Socket socket) {
            this.socket = socket;
        }

        public void run() {
            try {
                // Create character streams for the socket.
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out = new PrintWriter(socket.getOutputStream(), true);
                out.println("CONNECT");


                while (true) {
                    name = in.readLine();
                    if (name == null || !name.startsWith("LOGIN ")) {
                        out.println("LOGIN ERROR");
                    } else {
                        synchronized (names) {
                            if (!names.contains(name.substring(6))) {
                                name = name.substring(6);
                                names.add(name);
                                out.println("OK");
                                writers.add(out);
                                readers.add(in);
                                Thread.currentThread().setName(name);
                                break;
                            } else {
                                out.println("NAME ERROR");
                            }
                        }
                    }
                }

                clientsConnected++;
                if (clientsConnected == 5) {
                    GameLogic.start();
                }

                /* Accept messages from this client and broadcast them.
                Ignore other clients that cannot be broadcasted to. */

                while (true) {
                    String input = in.readLine();
                    synchronized (playersInput) {
                        synchronized (GameLogic) {
                            playersInput.add(input);
                            GameLogic.notify();
                        }
                    }
                }

            } catch (IOException e) {
                System.out.println(e);
            } finally {
                /* This client is going down!  Remove its name and its print
                writer from the sets, and close its socket. */
                if (name != null) {
                    names.remove(name);
                }
                if (out != null) {
                    writers.remove(out);
                }
                try {
                    socket.close();
                } catch (IOException e) {
                    System.out.println(e);
                }
            }
        }
    }

1 Ответ

0 голосов
/ 27 января 2020

Я предполагаю, что вы создаете отдельный поток для каждого клиента, потому что у клиента может быть другой разговор с компьютером, когда это не его очередь? Возможно, он спрашивает, чья это очередь, или участвуете в чате с другими игроками или что-то в этом роде? Я точно не понимаю, почему вы создаете отдельную ветку для sendMessage и readMessage. Как правило, система читает с клиента, а затем делает ответ в том же потоке. Это его l oop: readMessage, сформулировать ответ, sendMessage, повторить.

Предполагая, что мое понимание выше верно, вам все еще понадобится центральный агент, LoveLetterGame, к которому принадлежат эти ConsoleClients, из которых только один для любого активного LoveLetterGame. (LoveLetterGame должен быть тем, который создает экземпляры ConsoleClient. Он должен включать в себя AtomicInteger с номером его очереди. AtomicInteger включает в себя поточно-ориентированные методы для тестирования и изменения значения, плюс у вас должно быть правило, что только поток для Текущий игрок может изменить значение.

PS Я большой поклонник игры Love Letter.
PPS Используйте CamelCase для Java, а не Underscore_separation.

...