Почему мой GUI не обновляется после получения ход оппозиции - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь создать игру Client, Server Connect4. Сторона подключения, кажется, работает. Все данные, которые отправлены, похоже, получены. Проблема возникает на стороне клиента, GUI не обновляется до тех пор, пока не нажата мышь, поэтому вы не можете видеть движение своих противников, пока не сделаете свое.

public class Connect4Server extends Application implements VariablesForGame {

    /** Session numbers */
    private int sessionNo = 1;

    /** TextArea */
    TextArea taLog;

    /**
    * Launches JavaFX
     */
    @Override
    public void start(Stage primaryStage) throws Exception {

        taLog = new TextArea();

        Scene scene = new Scene(new ScrollPane(taLog), 450, 200);
        primaryStage.setTitle("Connect4 Server");
        primaryStage.setScene(scene);
        primaryStage.show();

        new Thread( () -> {
            try {
                ServerSocket serverSocket = new ServerSocket(8004);

                Platform.runLater(() -> taLog.appendText(new Date() +
                  ": Server started at socket 8004\n"));

                while(true) {
                    Platform.runLater(() -> taLog.appendText(new Date() +
                        ": Wait for players to join session " +
                        sessionNo + '\n' ));

                    // Connect player 1
                    Socket player1 = serverSocket.accept();

                    Platform.runLater(() -> { 
                        taLog.appendText(new Date() + ": Player 1 joined session " 
                            + sessionNo + '\n');
                        taLog.appendText("Player 1's IP address" + 
                            player1.getInetAddress().getHostAddress() + '\n');
                    });

                    // Notify that the player is Player 1
                    new DataOutputStream(
                       player1.getOutputStream()).writeInt(PLAYER1); // Should be Player

                    // Connect player 2
                    Socket player2 = serverSocket.accept();

                    System.out.println("player 2 joined");

                    Platform.runLater(() -> { 
                        taLog.appendText(new Date() + ": Player 2 joined session " 
                            + sessionNo + '\n');
                        taLog.appendText("Player 2's IP address" + 
                            player2.getInetAddress().getHostAddress() + '\n');
                    });

                    // Notify that the player is Player 1
                    new DataOutputStream(
                        player2.getOutputStream()).writeInt(PLAYER2); // Should be Player

                    // Display this session and increment session number
                    Platform.runLater(() ->
                        taLog.appendText(new Date() + 
                        ": Start a thread for the game session " + sessionNo++ + '\n'));

                    new Thread(new HandleGameSession(player1, player2)).start();

                }

            }
            catch(IOException ex) {
                ex.printStackTrace();
            }
        }).start();

    }
    /**
     * Handles the game session between to players
     */
    class HandleGameSession implements Runnable {
        /** Socket for player1 */
        private Socket player1;
        /** Socket for player2 */
        private Socket player2;
        //private Connect4 game;

        private boolean player1Turn = false;
        private boolean player2Turn = false;

        /** game won or not */
        public boolean won = false;

        /** Data Input Stream player 1 */
        private DataInputStream fromPlayer1;
        /** DataOutput Stream player 1 */
        private DataOutputStream toPlayer1;
        /** Data Input Stream player 2*/
        private DataInputStream fromPlayer2;
        /** Data Input Stream player 2 */
        private DataOutputStream toPlayer2;


        // Create gameBoard
        private char[][] gameBoard = new char[6][7];

        /**
         * Constructor, sets up socket and creates a board.
         */
        public HandleGameSession(Socket player1, Socket player2) {
            this.player1 = player1;
            this.player2 = player2;

            // Initialises the board
            for (int y = 0; y < 6; y++) {
                for (int x = 0; x < 7; x++)
                    gameBoard[y][x] = ' ';
            }
        }
        /**
         * run the thread for the game.
         */
        @Override
        public void run() {
            try {
                fromPlayer1 = new DataInputStream( 
                    player1.getInputStream());
                toPlayer1 = new DataOutputStream(
                    player1.getOutputStream());
                fromPlayer2 = new DataInputStream(
                    player2.getInputStream());
                toPlayer2 = new DataOutputStream(
                    player2.getOutputStream());

                toPlayer1.writeInt(PLAYER1);

                while (true) {

                    int row = fromPlayer1.readInt();        
                    int column = fromPlayer1.readInt();

                    gameBoard[row][column] = 'X';

                    player1Turn = false;


                    player2Turn = true;

                    // Receive a move from Player 2
                    row = fromPlayer2.readInt();
                    column = fromPlayer2.readInt();

                    gameBoard[row][column] = 'O';

                    toPlayer1.writeInt(CONTINUE);
                    sendMove(toPlayer1, row, column);

                    player2Turn = false;
                    player1Turn = true; 
                }        
            }
            catch(IOException ex) {
                ex.printStackTrace();
            }   
        }

        /** 
         * Send the move to other player 
         * */
        private void sendMove(DataOutputStream out, int row, int column) throws IOException {
            out.writeInt(row); // Send row index
            out.writeInt(column); // Send column index

        }

        public boolean checkIfWon(int row, int col, char p) {... }

        public static void main(String[] args) {


            launch(args);
        }
  }

А теперь для класса клиента

public class Connect4Client extends Application implements VariablesForGame {

    GridPane gridPane;

    /** Variable containing the connect4 game logic*/
    private Connect4 game;

    /** Continue to play */
    private boolean continueToPlay = true;

    /** Wait for the player to mark a cell */
    private boolean waiting = true;

    /** Which players turn */
    private boolean myTurn = false;

    /** Indicate the token for the player */
    private char myToken = ' ';

    /** Indicate selected row */
    private int rowSelected;

    /** Indicate the slelected column */
    private int columnSelected;

    /** The players number **/
    int player = 0;

    /** Indicate the token for the other player */
    private char otherToken = ' ';

    /** Text area for display */
    private TextArea taLog;

    /** Create and initialiSe a title label */
    private Label lblTitle = new Label();

    /** Input streams from/to server */
    private DataInputStream fromServer;

    /** Output streams from/to server */
    private DataOutputStream toServer;

    /** Host name or ip */
    private String host = "localhost";

    /**
     * Launch FX
     */
    @Override
    public void start(Stage primaryStage) throws Exception {

        game = new Connect4();

        char gameType = 'P';

        game.addPlayer(gameType);

        primaryStage.setTitle("Connect4 Game");

        BorderPane rootPaneBorder = new BorderPane();

        GridPane gridPane = createGrid();

        rootPaneBorder.setCenter(gridPane);

        taLog = new TextArea();

        Button button1 = new Button();

        rootPaneBorder.setBottom(taLog);

        rootPaneBorder.setRight(button1);

        rootPaneBorder.setTop(lblTitle);

        Scene scene = new Scene(rootPaneBorder, 475, 475);

        scene.setFill(Color.SILVER);

        primaryStage.setScene(scene);

        primaryStage.show();

        connectToServer();
    }
    /**
     * Connect to server
     */
    private void connectToServer() {
        try {
            // Create a socket to connect to the server
            Socket socket = new Socket(host, 8004);

            // Create an input stream to receive data from the server
            fromServer = new DataInputStream(socket.getInputStream());

            // Create an output stream to send data to the server
            toServer = new DataOutputStream(socket.getOutputStream());
        }

        catch (Exception ex) {
            System.out.println("Failed to connect");
            ex.printStackTrace();
        }

        new Thread(() -> {
            try {
                // Notify what player number they are
                player = fromServer.readInt();


                while (continueToPlay) {      
                    if (player == PLAYER1) {    

                        waitForPlayerAction();

                        sendMove();

                        receiveInfoFromServer();

                    }
                    else if (player == PLAYER2) {

                        receiveInfoFromServer();

                        waitForPlayerAction();

                        sendMove();

                    }
                }
            }

            catch(Exception ex) {
                ex.printStackTrace();
            }
        }).start();
    }
    /**
     * Wait for player move
     * @throws InterruptedException
     */
    private void waitForPlayerAction() throws InterruptedException {
        while (waiting) {
            Thread.sleep(1000);
        }

        waiting = true;
    }
    /**
     * Send players move
     * @throws IOException
     */
    private void sendMove() throws IOException {

        toServer.writeInt(columnSelected);
        toServer.writeInt(rowSelected);

    }
    /**
     * Receive info from server
     * @throws IOException
     */
    private void receiveInfoFromServer() throws IOException {
        // Receive game status
        int status = fromServer.readInt();
        receiveMove();
        myTurn = true; // It is my turn
    }
    /**
     * Receive actual players position
     * @throws IOException
     */
    private void receiveMove() throws IOException {
        int row = fromServer.readInt();

        int column = fromServer.readInt();

        System.out.println("row"+ row + " column " + column);

        new Thread(() -> {

            //myTurn = false;   
            int newRow = row+2; // change from +2
            int newCol = column+2;// change from +2

            Circle cir = new Circle(30);

            GridPane.setColumnIndex(cir, newRow);
            GridPane.setRowIndex(cir, newCol);
            cir.setFill(Color.BLACK);

            Platform.runLater(() -> {
                gridPane.add(cir, newCol, newRow);
            });

            taLog.appendText("Just received, row: " + row + " column " + column);

            System.out.println("Placed items");
            game.printBoard();
            game.board[row][column] = 'O';

            }).start();
    }

    /**
     * Create a grid for the board
     * @return, the grid
     */
    public GridPane createGrid() {

        gridPane = new GridPane();

        for (int y = 2; y < 9; y++) {       
            for (int x = 2; x < 8; x++) {

                gridPane.setHgap(5);
                gridPane.setVgap(5);
                Circle cir = new Circle(30);

                GridPane.setColumnIndex(cir, y);
                GridPane.setRowIndex(cir, x);

                gridPane.add(cir, y, x);

                cir.setFill(Color.LIGHTSTEELBLUE);

                cir.setOnMouseClicked(e -> {

                    boolean pieceAdded = false;
                    boolean played = false;
                    boolean acceptMove = false;

                    int colIndex = GridPane.getColumnIndex(cir)-2;
                    int rowIndex = GridPane.getRowIndex(cir)-2;

                    if (myTurn) {
                        acceptMove = addPieceGUI(colIndex, rowIndex);

                        while(!played) {
                            if(acceptMove) {
                                while(!pieceAdded) {

                                    if(player  == PLAYER1) {
                                        pieceAdded = game.addPiece(colIndex, game.listOfplayers[0]);
                                        //gameBoard[rowIndex][colIndex] = 'X';
                                    }
                                    else {
                                        pieceAdded = game.addPiece(colIndex, game.listOfplayers[1]);

                                    }
                                }
                                cir.setFill(Color.RED);
                                played = true;
                                myTurn = false;
                                waiting = false;
                         }
                    }
                    game.board[rowIndex][colIndex] = 'X';
                    game.printBoard();
                    try {
                        rowSelected = colIndex;
                        columnSelected = rowIndex;
                        sendMove();

                    } catch (IOException e1) {

                        e1.printStackTrace();
                    }
                }
            });
        }
        return gridPane;
    }

    public static void main(String[] args) {

        launch(args);

    }
...