0

I am trying to do checkers using java sockets. However, when I run a client, it gets stuck in a loop and stops responding.

So far my app has methods to draw a board, move checkers and create connection between a server and clients. The connection is created correctly.

The problem is with play() which is responsible for handle server messages.

Pls help me to modify play() to have it working.


Client App


public class CheckersApp extends Application {

public static final int TILE_SIZE = 100;
public static final int WIDTH = 8;
public static final int HEIGHT = 8;

private Tile[][] board = new Tile[WIDTH][HEIGHT];

private Group tileGroup = new Group();
private Group pieceGroup = new Group();
private Label text = new Label();

private static int PORT = 8901;
private Socket socket;
private BufferedReader in;
private PrintWriter out;

// method to draw a board with checkers

private Parent createContent() {
        ...
}

// method to check if moving checkers is possbile
private MoveResult tryMove(Piece piece, int newX, int newY) {
      ...
}

@Override
public void start(Stage primaryStage) throws Exception {
    Scene scene = new Scene(createContent());
    primaryStage.setTitle("CheckersApp");
    primaryStage.setScene(scene);
    primaryStage.show();

    // Setup networking
    socket = new Socket("LAP00132", PORT);
    in = new BufferedReader(new InputStreamReader(
        socket.getInputStream()));
    out = new PrintWriter(socket.getOutputStream(), true);

    play();
}

// method to move checkers
private Piece makePiece(PieceType type, int x, int y) {
  ...
}

// method to get responses from Server
public void play() throws Exception {
    String response;
    try {
        response = in.readLine();
        if (response.startsWith("WELCOME")) {
           // char mark = response.charAt(8);
        }
        while (true) {
            response = in.readLine();
            if (response.startsWith("VALID_MOVE")) {
                text.setText("Valid move, please wait");

            } else if (response.startsWith("OPPONENT_MOVED")) {

                text.setText("Opponent moved, your turn");
            } else if (response.startsWith("VICTORY")) {
                text.setText("You win");
                break;
            } else if (response.startsWith("DEFEAT")) {
                text.setText("You lose");
                break;
            } else if (response.startsWith("TIE")) {
                text.setText("You tied");
                break;
            } else if (response.startsWith("MESSAGE")) {
                text.setText(response.substring(8));
            }
        }
        out.println("QUIT");
    }
    finally {
        socket.close();
    }
}

public static void main(String[] args) {
    launch(args);}

Server App


 public class Server {

/**
 * Runs the application. Pairs up clients that connect.
 */
public static void main(String[] args) throws Exception {
    ServerSocket listener = new ServerSocket(8901);
    System.out.println("Server is Running");
    try {
        while (true) {
            Game game = new Game();
            Game.Player playerX = game.new Player(listener.accept(), 'X');
            System.out.println("Połączony X");
            Game.Player playerO = game.new Player(listener.accept(), 'O');
            System.out.println("Połączony O");
            playerX.setOpponent(playerO);
            playerO.setOpponent(playerX);
            game.currentPlayer = playerX;
            playerX.start();
            playerO.start();
        }
    } finally {
        listener.close();}}}


class Game {

public static final int WIDTH = 8;
public static final int HEIGHT = 8;
//private Tile[][] board = new Tile[WIDTH][HEIGHT];

Player currentPlayer;

/**
 * Called by the player threads when a player tries to make a
 * move.  This method checks to see if the move is legal: that
 * is, the player requesting the move must be the current player
 */
public synchronized boolean legalMove(Player player) {
    if (player == currentPlayer) {
        currentPlayer = currentPlayer.opponent;
        currentPlayer.otherPlayerMoved();
        return true;
    }
    return false;
}



class Player extends Thread {
    char mark;
    Player opponent;
    Socket socket;
    BufferedReader input;
    PrintWriter output;

    /**
     * Constructs a handler thread for a given socket and mark
     * initializes the stream fields, displays the first two
     * welcoming messages.
     */
    public Player(Socket socket, char mark) {
        this.socket = socket;
        this.mark = mark;
        try {
            input = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
            output = new PrintWriter(socket.getOutputStream(), true);
            output.println("WELCOME " + mark);
            System.out.println("Welcome ");
            output.println("MESSAGE Waiting for opponent to connect");
        } catch (IOException e) {
            System.out.println("Player died: " + e);
        }
    }

    /**
     * Accepts notification of who the opponent is.
     */
    public void setOpponent(Player opponent) {
        this.opponent = opponent;
    }

    /**
     * Handles the otherPlayerMoved message.
     */
    public void otherPlayerMoved() {
        output.println("OPPONENT_MOVED ");
        System.out.println("OPPONENT_MOVED");
    }



    /**
     * The run method of this thread.
     */
    public void run() {
        try {
            // The thread is only started after everyone connects.
            output.println("MESSAGE All players connected");

            // Tell the first player that it is her turn.
            if (mark == 'X') {
                output.println("MESSAGE Your move");
            }

            // Repeatedly get commands from the client and process them.
            while (true) {
                String command = input.readLine();
                if (command.startsWith("MOVE")) {
                    if (legalMove(this)) {
                        output.println("VALID_MOVE");
                        System.out.println("VALID MOVE");
                    } else {
                        output.println("MESSAGE ?");
                    }
                } else if (command.startsWith("QUIT")) {
                    return;
                }
            }
        } catch (IOException e) {
            System.out.println("Player died: " + e);
        } finally {
            try {socket.close();} catch (IOException e) {}
        }
    }
}}
ndmeiri
  • 4,979
  • 12
  • 37
  • 45
Elik123
  • 11
  • 1
  • 1
    Check this [brilliantly written answer](https://stackoverflow.com/a/30250308/1759128) to understand how background tasks work in JavaFX and how you can use it in your use-case. If things don't work out, edit your question and tell us what went wrong :) – ItachiUchiha Jun 01 '18 at 22:11

1 Answers1

0

Your while(true) loop just waits for a line. It blocks the ability to perform any actions on the UI.

Spawn a separate thread to handle server communications. Obviously you need to be aware of the dangers of multi-threading and multi-thread access of model and UI data.

corsiKa
  • 81,495
  • 25
  • 153
  • 204