Server Side Client Side JAVA game moves

358 Views Asked by At

I'm new to server-client coding. I have a project making a 3 stones game, I am supposed to make a connection between the client and the server. I connect the client to the server but I don't know how can I pass the client's moves (Point's coordinates) to the server and then return the proper message from the server to the client. and I don't know what is byte[] data does also the BUFFSize Can you please explain why I have to use byte[] also BUFFSIZE? and how can I hell server where the client placed the stone on the board? CilentSide :

public class ThreeStonesGameClientSide {

    private static final int BUFSIZE = 32;
    private final static org.slf4j.Logger LOG = LoggerFactory.getLogger(ThreeStonesGameClientSide.class);
    private String ip;
    private int port;

    public ThreeStonesGameClientSide(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }
    public void connectToServer() throws IOException {
        Socket socket = new Socket(this.ip, this.port);  
        LOG.info("Connected to the server");
        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();

       Point recivedPoint = new Point();
       int x = (int) recivedPoint.getX();
       int y = (int) recivedPoint.getY();

       byte[] data = new byte[BUFSIZE];
        // Receive the same string back from the server
        int totalBytesRcvd = 0;  // Total bytes received so far
        int bytesRcvd;           // Bytes received in last read
        while (totalBytesRcvd < data.length) {
            if ((bytesRcvd = in.read(data, totalBytesRcvd,
                    data.length - totalBytesRcvd)) == -1) {
                throw new SocketException("Connection closed prematurely");
            }
            totalBytesRcvd += bytesRcvd;
        }  // data array is full

        System.out.println("Received: " + new String(data));

        socket.close();  // Close the socket and its streams 

    }

}

and this is the Server-side

public class ThreeStonesGameClientSide {

    private static final int BUFSIZE = 32;
    private final static org.slf4j.Logger LOG = LoggerFactory.getLogger(ThreeStonesGameClientSide.class);
    private String ip;
    private int port;

    public ThreeStonesGameClientSide(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }
    public void connectToServer() throws IOException {
        Socket socket = new Socket(this.ip, this.port);  
        LOG.info("Connected to the server");
        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();

       Point recivedPoint = new Point();
       int x = (int) recivedPoint.getX();
       int y = (int) recivedPoint.getY();

       byte[] data = new byte[BUFSIZE];
        // Receive the same string back from the server
        int totalBytesRcvd = 0;  // Total bytes received so far
        int bytesRcvd;           // Bytes received in last read
        while (totalBytesRcvd < data.length) {
            if ((bytesRcvd = in.read(data, totalBytesRcvd,
                    data.length - totalBytesRcvd)) == -1) {
                throw new SocketException("Connection closed prematurely");
            }
            totalBytesRcvd += bytesRcvd;
        }  // data array is full

        System.out.println("Received: " + new String(data));

        socket.close();  // Close the socket and its streams 

    }

}

this is the Board class

public class Board implements Serializable {

    public final IntegerProperty numOfWhiteStones;
    public final IntegerProperty numOfBlackStones;
    public final ObjectProperty<Stone[][]> board;

    private Point lastPoint;

    public Board(Player p1, Player p2) {
        this.numOfBlackStones = new SimpleIntegerProperty();
        this.numOfWhiteStones = new SimpleIntegerProperty();
        this.board = new SimpleObjectProperty<Stone[][]>(new Stone[11][11]);
    }

    /**
     * Checks if chosen point is along the same x and y axis as the last placed point.
     * @param placementPoint
     * @return 
     */
    public boolean checkSlot(Point placement) {
        Stone[][] board = getBoard();
        int x = placement.x;
        int y = placement.y;
        // Check if placement is within the limits of the inner arry
        if ((x < 0 || x > board.length - 1) && (y < 0 || y > board.length - 1)) {
            return false;
        }
        // Check if place on board is empty
        if (board[x][y] != Stone.EMPTY) {
            return false;
        }
        if (lastPoint == null){
            return true;
        }
        // Check if placement is within the same colum or row as the last played stone
        return (x == lastPoint.x ^ y == lastPoint.y);

    }

    public void placeStone(Point placement, Stone stone) {
        Stone[][] board = getBoard();
        int x = placement.x;
        int y = placement.y;
        board[x][y] = stone;
        if (stone == Stone.BLACK) {
            numOfBlackStones.add(1);
        } else {
            numOfWhiteStones.add(1);
        }
        lastPoint = placement;
    }

    public int calculatePointsFor(Stone stone) {
        Stone[][] board = this.board.get();
        int counter = 0;
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board.length; j++) {
                for (int k = 0; k < 4; k++) {
                    if (directionCheck(stone, new Point(i, j), k)){
                        counter++;
                    }
                }
            }
        }
        return counter;
    }

    boolean directionCheck(Stone stone, Point coord, int direction) {
        Stone[][] board = getBoard();
        int x = coord.x;
        int y = coord.y;
        switch (direction) {
            case 0:
                if (coord.x + 2 < board.length) {
                    return (board[x][y] == board[x + 1][y] && board[x + 1][y] == board[x + 2][y]);
                }
                break;
            case 1:
                if ((coord.x + 2 < board.length) && (coord.y + 2 < board.length)) {
                    return (board[x][y] == board[x + 1][y + 1] && board[x + 1][y + 1] == board[x + 2][y + 2]);
                }
                break;
            case 2:
                if (coord.y + 2 < board.length) {
                    return (board[x][y] == board[x][y + 1] && board[x][y + 1] == board[x][y + 2]);
                }
                break;
            case 3:
                if ((coord.x - 2 >= 0) && (coord.y + 2 < board.length)) {
                    return (board[x][y] == board[x - 1][y + 1] && board[x - 1][y + 1] == board[x - 2][y + 2]);
                }
                break;

        }
        return false;
    }

    public final Stone[][] getBoard() {
        return board.get();
    }

    public void setBoard(final Stone[][] isbn) {
        this.board.set(isbn);
    }

    public final ObjectProperty boardProperty() {
        return board;
    }

    public final int getNumOfWhiteStones() {

        return numOfWhiteStones.get();
    }

    public final IntegerProperty numOfWhiteStonesProperty() {
        return numOfWhiteStones;
    }

    public final int getNumOfBlackStones() {
        return numOfBlackStones.get();
    }

    public final IntegerProperty numOfBlackStonesProperty() {
        return numOfBlackStones;
    }

    public final Point getLastPoint() {
        return lastPoint;
    }

}
1

There are 1 best solutions below

0
On

for your questions, IMHO:

  1. All the data sent over the network should be in bytes array, it concerns the byte orders (Endianness) and you can check more definitions in Wiki. And if it in byte array you can do some tricks to make it as small as possible. In the network, it can a lot of problems occur, so with less data transfer, the harder it is to lose. For the byte data transfer, you can check out my small functions here: Pack data with Msgpack libraries Endianness converting

  2. The server you created should handle all logic in-game, and the client-side is only for viewing. For example: When a client makes a moving, he only sends his action (ID of the moving object, the new object's target, ...). After that, the server must confirm that the message's information, take the calculation itself and return the results to all corresponding clients. I wrote a small project, so you can check out the examples for more detail: NIO java server game framework with examples