Связь между розетками перестает работать после одного сообщения. BattleShipGame Swing - PullRequest
0 голосов
/ 22 января 2019

В начале я отправляю строку таблиц с указанием места расположения вражеских кораблей. Затем в цикле (пока бесконечном) я пытаюсь отправить одно сообщение и прослушать одно в зависимости от того, какой ход. После одного сообщения отправленные и полученные циклы перестают работать. Я подозреваю, что это может быть связано с потоком, но я не знаю, как подойти к этому. Я не ожидаю, что кто-нибудь перебирает весь этот код, но я думаю, что лучше включать больше кода, чем меньше. Я в основном ищу какое-то руководство. Код ниже и спасибо за вашу помощь.

Основной класс (я думаю, что основными виновниками могут быть customMousePressed & actionPerformed)

открытый класс BattleShipGame расширяет JFrame, реализует ActionListener {

//this 268, Draw 112 /////////////////////////////////////
private Optional<Ship> newShip;
private int logicPosX;
private int logicPosY;
private Coordinates start;
static String coordinatesInput = "", coordinatesOutput = "";
static boolean myturn = false;
private static int counter = 0;
static boolean connected = false;
Captain player = new Captain();

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> new BattleShipGame());
}

private BattleShipGame()
{
    this.setTitle("Battleship Game");
    this.setSize(1100, 500);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.setResizable(false);

    JPanel panel = new JPanel();
    player.initializeShips();

    Timer timer = new Timer(20, this);

    DrawBoardAndShips boardAndShips = new DrawBoardAndShips(player);

    timer.start();
    //create player
    //set your ships (one map & ships to drag from place to place)
    //when READY button clicked and all ships are on board ->
    //->search for player (Connection - sockets)
    //draw 2 maps (one with ships, one to shoot)
    //receive  coordinates (hit or miss - draw changes to 1 map) - win condition checker (send info to another player about shoot result)
    //send coordinates

    JButton reset = new JButton("RESET");
    reset.addActionListener(e -> {
        //set to default position of ships
        player.resetPositions();
        player.getShips().forEach(ship -> ship.setShipOnBoard(false));
    });
    JButton ready = new JButton("READY!");
    ready.addActionListener((ActionEvent e) -> { //set logic when button ready pressed
        //check if all ships are on board
        //set ready = true

        if (player.getShips().stream().filter(Ship::isShipOnBoard).count() == 10 && e.getSource() == ready) {

            //set logic
            for (Ship ship : player.getShips()) {
                player.setMyBoard(ship);
            }

            //establish network connection
            boolean outcome = serverOrClientDecision(JOptionPane.YES_OPTION, player);

            if(outcome) {
                panel.remove(reset);
                panel.remove(ready);
            }
            revalidate();
            repaint();
        }
    });
    panel.add(reset);
    panel.add(ready);
    this.add(panel, BorderLayout.SOUTH);
    this.add(boardAndShips, BorderLayout.CENTER);


    boardAndShips.addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            customMouseDragged(player, e);
        }
    });

    boardAndShips.addMouseListener(new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent e) {
            customMouseClicked(e, player);

        }

        @Override
        public void mousePressed(MouseEvent e) {
            customMousePressed(e, player);
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            customMouseReleased(player);
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }
    });
    this.setVisible(true);
}

@Override
public void actionPerformed(ActionEvent e) {
    if(!coordinatesInput.isEmpty() && !player.isMyTurn()){
        String[] parts = coordinatesInput.split("\\."); //////////////////
        logicPosX = Integer.parseInt(parts[0]);
        logicPosY = Integer.parseInt(parts[1]);
        if (player.getMyBoard()[logicPosX][logicPosY] == 1) {
            player.getMyBoard()[logicPosX][logicPosY] = 2;
            isSunk(player.getMyBoard());
        }
        else if(player.getMyBoard()[logicPosX][logicPosY] == 0)
            player.getMyBoard()[logicPosX][logicPosY] = -1;

        coordinatesInput = "";
        player.setMyTurn(true);
    }

    repaint();
}

public boolean serverOrClientDecision(int decision, Captain player) {

    Object[] options = {"CREATE", "JOIN", "EXIT"};
    Object[] options2 = {"BACK", "TRY AGAIN", "EXIT"};
    if (decision == JOptionPane.YES_OPTION) {

        decision = JOptionPane.showOptionDialog(this, "Create game or join one?", "Battleship Game",
                JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, null);
    }

    //
    if(decision == JOptionPane.CANCEL_OPTION)
        return false;

    if (decision == JOptionPane.YES_OPTION) {
        //create server

        SwingWorker<Void, Void> worker = new SwingWorker<>() {
            @Override
            protected Void doInBackground() throws Exception {
                Server server = new Server(player);
                return null;
            }
        };
        worker.execute();

    } else if (decision == JOptionPane.NO_OPTION) {
        //getting IP
        String serversIP = JOptionPane.showInputDialog("Type server's IP");

        //creating client
        SwingWorker<Void, Boolean> worker1 = new SwingWorker<>() {
            @Override
            protected Void doInBackground() throws IOException {
                Client client = new Client(serversIP, player);
                return null;
            }
        };
        worker1.execute();

        while (!worker1.isDone()) {
            if (connected == true)
                break;
        }

        if (!connected) {
            decision = JOptionPane.showOptionDialog(this, "Host not responding", "Join Game",
                    JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options2, null);
            serverOrClientDecision(decision, player);
        }
    }
    return true;
}

public void customMouseDragged(Captain player, MouseEvent e) {
    if (player.getReady() == 0) {
        newShip.filter(Ship::isHorizontal)
                .ifPresent(ship -> ship.setCoordinates(new Coordinates(e.getX() - ship.getSize() * 16, e.getY() - 16)));
        newShip.filter(ship -> !ship.isHorizontal())
                .ifPresent(ship -> ship.setCoordinates(new Coordinates(e.getX() - 16, e.getY() - ship.getSize() * 16)));
    }
}

public void customMouseClicked(MouseEvent e, Captain player) {
    if (player.getReady() == 0) {
        //ship is in bounds of the BOARD after rotating
        player.getShips().stream()
                .filter(ship -> ship.getBounds().contains(e.getPoint()))
                .filter(ship -> (logicPosX < 11 && logicPosY + ship.getSize() < 11 && ship.isHorizontal())
                        || (logicPosX + ship.getSize() < 11 && logicPosY < 11 && !ship.isHorizontal()))
                .forEach(ship -> ship.setHorizontal(!ship.isHorizontal()));

        //ship don't overlap space of other ship, if does revert rotation to previous state
        if(newShip.isPresent()) {
            player.getShips().stream()
                    .filter(ship -> ship.getId() != newShip.get().getId())
                    .filter(ship -> ship.getBigBounds().intersects(newShip.get().getBounds()))
                    .forEach(ship -> {
                        newShip.get().setHorizontal(!newShip.get().isHorizontal());
                    });
        }

    }
}

public void customMousePressed(MouseEvent e, Captain player) {
    if (player.getReady() == 0) {
        logicPosX = logicPosY = -1;

        //picking up ship
        newShip = player.getShips().stream().
                filter(ship -> ship.getBounds().contains(e.getPoint()))
                .findAny();

        newShip.ifPresent(newShip -> start = newShip.getCoordinates());
    } else if (player.getReady() == 2 && player.isMyTurn()) {
        //System.out.println(e.getPoint().toString());

        //-1 - uncovered (miss)
        // 0 - covered (miss)
        // 1 - covered (hit)
        // 2 - uncovered (hit)
        // 3 - uncovered (hit and sunk)

        // is shoot in bounds of the enemy BOARD
        if ((e.getX() > 600 && e.getX() < 920) && (e.getY() > 50 && e.getY() < 370)){
            logicPosX = (e.getX() - 600) / 32;
            logicPosY = (e.getY() - 50) / 32;

            if (player.getEnemyBoard()[logicPosX][logicPosY] == 1) { // if covered (hit)
                player.getEnemyBoard()[logicPosX][logicPosY] = 2;// set as uncovered (hit)
                //check if ship sunk
                isSunk(player.getEnemyBoard());
                coordinatesOutput = Integer.toString(logicPosX) + "." + Integer.toString(logicPosY);
                player.setMyTurn(false);
                coordinatesOutput = "";
            }
            else if (player.getEnemyBoard()[logicPosX][logicPosY] == 0) { //if covered (miss)
                player.getEnemyBoard()[logicPosX][logicPosY] = -1; // set as uncovered (miss)
                coordinatesOutput = Integer.toString(logicPosX) + "." + Integer.toString(logicPosY);
                player.setMyTurn(false);
                coordinatesOutput = "";
            }
        }
    }
}
public void customMouseReleased(Captain player) {
    if (player.getReady() == 0) {
        if (newShip.isPresent()) {
            logicPosX = (newShip.get().getCoordinates().getX() - 150) / 32;
            logicPosY = (newShip.get().getCoordinates().getY() - 50) / 32;

            //ship placed on board
            if (((logicPosX + newShip.get().getSize() < 11) && (logicPosY < 11) && newShip.get().isHorizontal() && logicPosX > -1 && logicPosY > -1)
                    || ((logicPosX < 11) && (logicPosY + newShip.get().getSize() < 11) && !newShip.get().isHorizontal() && logicPosX > -1 && logicPosY > -1)) {
                //adjust to grid
                newShip.get().getCoordinates().setX(150 + logicPosX * 32);
                newShip.get().getCoordinates().setY(50 + logicPosY * 32);

                newShip.ifPresent(newShip -> newShip.setShipOnBoard(true));

                //ship don't overlap space of other ship, if does revert move
                player.getShips().stream()
                        .filter(ship -> ship.getId() != newShip.get().getId())
                        .filter(ship -> ship.getBigBounds().intersects(newShip.get().getBounds()))
                        .forEach(ship -> {
                            newShip.get().setCoordinates(start);
                            newShip.get().setShipOnBoard(false);
                        });
            } else {
                newShip.get().setHorizontal(true);
                newShip.get().setCoordinates(start);
            }
        }
    }
}

private void isSunk(int[][] board) {

    int struck = 0;
    int notStruck = 0;
    Point[] struckPositions = new Point[4];

    //checking every direction for not struck poles in ship
    for (int n = 0; n < 4; n++) {
        if (logicPosY - n > 0){
            if (board[logicPosX][logicPosY - n] == 2) {
                struckPositions[struck] = new Point(logicPosX, logicPosY);
                struck++;
            }
            else if(board[logicPosX][logicPosY - n] == 1)
                notStruck++;
            else if(board[logicPosX][logicPosY - n] == 0)
                break;
        }
        else
            break;
    }
    for (int s = 1; s < 4; s++) {
        if (logicPosY + s  < 10){
            if (board[logicPosX][logicPosY + s] == 2) {
                struckPositions[struck] = new Point(logicPosX, logicPosY);
                struck++;
            }
            else if(board[logicPosX][logicPosY + s] == 1)
                notStruck++;
            else if(board[logicPosX][logicPosY + s] == 0)
                break;
        }
        else
            break;
    }
    for (int e = 1; e < 4; e++) {
        if (logicPosX + e < 10){
            if (board[logicPosX + e][logicPosY] == 2) {
                struckPositions[struck] = new Point(logicPosX, logicPosY);
                struck++;
            }
            else if(board[logicPosX + e][logicPosY] == 1)
                notStruck++;
            else if(board[logicPosX + e][logicPosY] == 0)
                break;
        }
        else
            break;
    }
    for (int w = 1; w < 4; w++) {
        if (logicPosX - w > 0){
            if (board[logicPosX - w][logicPosY] == 2) {
                struckPositions[struck] = new Point(logicPosX, logicPosY);
                struck++;
            }
            else if(board[logicPosX - w][logicPosY] == 1)
                notStruck++;
            else if(board[logicPosX - w][logicPosY] == 0)
                break;
        }
        else
            break;
    }

    // if sunk change it in logical table
    if (notStruck == 0){
        for (Point p : struckPositions){
            board[p.x][p.y] = 3;
            //return int = struck

        }
    }
    //else return -1; - in future to display sunk ships as small squares next to tables


}

}

Сервер

Сервер класса расширяет поток {

ServerSocket serverSocket;
Socket socket;
DataInputStream dataInputStream;
DataOutputStream dataOutputStream;

String sendMessage = "", message1 = "", receivedMessage = "";

public Server(Captain player) throws IOException {

    System.out.println("SERVER");

    int asd = 0;

    player.setReady(1);
    serverSocket = new ServerSocket(6666);


    socket = serverSocket.accept();
    player.setReady(2);
    dataInputStream = new DataInputStream(socket.getInputStream());
    dataOutputStream = new DataOutputStream(socket.getOutputStream());

    //send logic table at the beginning of the game
    for(int i1 = 0; i1 < player.getMyBoard().length; i1++){
        for (int j = 0; j < player.getMyBoard()[i1].length; j++){
            if(player.getMyBoard()[j][i1] == 1) /////////////////////
                sendMessage += "1";
            else
                sendMessage += "0";
        }
    }
    dataOutputStream.writeUTF(sendMessage);
    sendMessage = "";
    /*System.out.println("Sever get from Client: " + dataInputStream.readUTF());
    System.out.println("Server send: " + start);*/

    //receive String and convert it to enemy logic table
    receivedMessage = dataInputStream.readUTF();
    player.setEnemyBoard(receivedMessage);
    receivedMessage = "";
    player.setMyTurn(true);

    while(!message1.equals("WIN") || !message1.equals("LOOSE")){

      dataOutputStream.writeUTF(BattleShipGame.coordinatesOutput);
            BattleShipGame.coordinatesOutput = "";


        System.out.println("__");
        if(!player.isMyTurn()) {
            receivedMessage = dataInputStream.readUTF();

            System.out.println("server NOT my turn");

            if(!receivedMessage.isEmpty()) {
                BattleShipGame.coordinatesInput = receivedMessage;
                receivedMessage = "";
                //player.setMyTurn(true);
            }
        } else {
            sendMessage = BattleShipGame.coordinatesOutput;

            System.out.print(asd++);

            if(!sendMessage.isEmpty()) {
                dataOutputStream.writeUTF(sendMessage);
                sendMessage = "";
                //player.setMyTurn(false);
            }
        }




        dataOutputStream.flush();
    }

    dataInputStream.close();
    socket.close();
    serverSocket.close();
}

}

Клиент

Клиент публичного класса {

Socket socket;
DataInputStream dataInputStream;
DataOutputStream dataOutputStream;
BufferedReader bufferedReader;

String sendMessage = "", message1 = "", receivedMessage = "";

public Client(String host, Captain player) throws IOException {

    System.out.println("CLIENT");
    socket = new Socket(host, 6666);
    player.setReady(2);

    BattleShipGame.connected = socket.isConnected();

    dataInputStream = new DataInputStream(socket.getInputStream());
    dataOutputStream = new DataOutputStream(socket.getOutputStream());
    bufferedReader = new BufferedReader(new InputStreamReader(System.in));

    //send logic table at the beginning of the game
    for(int i1 = 0; i1 < player.getMyBoard().length; i1++){
        for (int j = 0; j < player.getMyBoard()[i1].length; j++){
            if(player.getMyBoard()[j][i1] == 1)
                sendMessage += "1";
            else
                sendMessage += "0";
        }
    }
    dataOutputStream.writeUTF(sendMessage);
    sendMessage = "";
    /*System.out.println("Client get from Server: " + dataInputStream.readUTF());
    System.out.println("Client sends: " + start);*/

    //receive String and convert it to enemy logic table
    receivedMessage = dataInputStream.readUTF();
    player.setEnemyBoard(receivedMessage);
    receivedMessage = "";
    player.setMyTurn(false);

    while(!message1.equals("WIN") || !message1.equals("LOOSE")){

        System.out.print("c");
        if(!player.isMyTurn()) {
            receivedMessage = dataInputStream.readUTF();

            System.out.println("client NOT my turn"); /////////////////////////////

            if(!receivedMessage.isEmpty()) {
                BattleShipGame.coordinatesInput = receivedMessage;
                receivedMessage = "";
            }
        } else {
            sendMessage = BattleShipGame.coordinatesOutput;

            System.out.println("client MY turn"); ////////////////////////////

            if(!sendMessage.isEmpty()) {
                dataOutputStream.writeUTF(sendMessage);
                sendMessage = "";
            }
        }


        dataOutputStream.flush();
    }

    dataInputStream.close();
    socket.close();
}
* *} Тысяча двадцать-один
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...