8 Replies - 369 Views - Last Post: 06 November 2017 - 02:08 PM Rate Topic: -----

#1 prubic  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 10-November 15

Help with JavaFX Battleship Project

Posted 01 November 2017 - 03:02 PM

Hi, I'm currently making a battleship game in JavaFX for my college project and I need some advice. I created a GridPane that looks like grid for battleship game but I cannot access the number of rows or columns of that GridPane so that I can use it for the Board class. I also don't know how to access the cell inside the GridPane so that I can click on it and put a random sized ship on its location. Does anyone know should I use GridPane or should I use something else like HBox or VBox to create a grid and how?

Is This A Good Question/Topic? 0
  • +

Replies To: Help with JavaFX Battleship Project

#2 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 3447
  • View blog
  • Posts: 15,614
  • Joined: 20-September 08

Re: Help with JavaFX Battleship Project

Posted 01 November 2017 - 03:18 PM

I think we'll need to see the code
Was This Post Helpful? 0
  • +
  • -

#3 prubic  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 10-November 15

Re: Help with JavaFX Battleship Project

Posted 06 November 2017 - 11:33 AM

I actually have a new problem now. I made a design in TilePane but I get an error that I don't know how to fix:
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at com.prubic.view.DesignedBoard.lambda$placeShip$1(DesignedBoard.java:65)
Here is my code in Main:
public class Main extends Application {
    
    private static Player player = new Player();
    private static Player opponent = new Player();
    
    private static DesignedBoard pPlacementBoard = player.getBoard();
    private static DesignedBoard oPlacementBoard = opponent.getBoard();
    
    
    private static Stage primaryStage;
    private static Player current = player;
    
    public static Label placeStatus = new Label("Player, place your ships");
    public static Label emptyLabel = new Label("");
    public static Label shipStatus = new Label("(Click button or press space to rotate)");
    
    private static BorderPane root = new BorderPane(pPlacementBoard);
    
    public static VBox bottomBox = new VBox();
    public static HBox buttonBox = new HBox();
    
    private static int turn = 1;
    
    private static GameBoard pGameBoard = null;
    
    public static Button rotateBtn = new Button("Rotate");
    public static Button saveBtn = new Button("Save board");
    public static Button loadBtn = new Button("Load board");
    
    public static Separator separator = new Separator();
    
    private static ArrayList<Integer> shipSizes = new ArrayList<>();
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        
        rotateBtn.setStyle("-fx-font-family: Calibri; -fx-font-size: 14;");
	placeStatus.setStyle("-fx-font-family: Calibri; -fx-font-size: 20; -fx-font-weight: bold;");
	bottomBox.setSpacing(0);
        
        separator.setOrientation(Orientation.HORIZONTAL);
        
        buttonBox.setSpacing(0);
        buttonBox.setAlignment(Pos.BOTTOM_LEFT);
        buttonBox.getChildren().addAll(saveBtn, loadBtn);
	bottomBox.getChildren().addAll(placeStatus, emptyLabel, shipStatus, rotateBtn, separator, buttonBox);
        
        rotateBtn.setOnAction(e -> rotate());
        saveBtn.setOnAction(e -> saveBoard());
        loadBtn.setOnAction(e -> loadBoard());
        
        addShips(shipSizes);
                
        root.setBottom(bottomBox);
        bottomBox.setAlignment(Pos.CENTER);
        
        Scene scene = new Scene(root);        
        primaryStage.setScene(scene);
        primaryStage.sizeToScene();
        primaryStage.setResizable(true);
        primaryStage.setTitle("Battleship");
        primaryStage.show();
        
        placeShips(shipSizes);
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);                   
    }

    private static void addShips(ArrayList<Integer> shipSizes) {
        shipSizes.add(5);
        shipSizes.add(4);
        shipSizes.add(3);
        shipSizes.add(3);
        shipSizes.add(2);
    }
    
    private static void rotate() {
        DesignedBoard board = current.getBoard();
        board.setRotated(!board.isRotated());
    }
    
    public static void placeShips(ArrayList<Integer> shipSizes) {
        
        if (!shipSizes.isEmpty() && current.equals(player)) {
            player.getBoard().placeShip(shipSizes);
        } else {
            play();
        }
    }
    
    private static void play() {
        
        pGameBoard = new GameBoard(oPlacementBoard, player);
        
        shipStatus.setText("");
        
        rotateBtn.setText("End turn");
        rotateBtn.setVisible(false);
        
        continueGame();  
    }
    
    public static void continueGame() {
        
        if (turn % 2 != 0) {
            root.setCenter(pGameBoard);
            placeStatus.setText("Player's turn");
            emptyLabel.setText("Opponent ships remaining: " + opponent.getShips().size());
            rotateBtn.setOnAction(e -> pGameBoard.endTurn()); 
        }
    }
            
    public static void incrementTurn() {
        turn++;
    }

    public static void gameOver() {
        
        Stage gameOverStage = new Stage();
        
        gameOverStage.initOwner(primaryStage);
        gameOverStage.initModality(Modality.APPLICATION_MODAL);
        
        Label gameOver = new Label("GAME OVER");
        Button exit = new Button("Exit");
        exit.setOnAction(e -> System.exit(0));
        
        VBox gameOverRoot = new VBox();
        gameOverRoot.setAlignment(Pos.CENTER);
        gameOverRoot.getChildren().addAll(gameOver, exit);
        
        Scene gameOverScene = new Scene(root, 300, 50);
        gameOverStage.setScene(gameOverScene);
        gameOverStage.setTitle("We have a winner!");
        gameOverStage.show();
        
    }

    private void saveBoard() {
        BoardLoader.saveBoard(player.getBoard(), player.getShips());
    }

    private DesignedBoard loadBoard() {
        DesignedBoard playerBoard = BoardLoader.loadBoard();
        return playerBoard;
    }
    
}



And here is also my DesignedBoard class code if you need it:
public class DesignedBoard extends TilePane implements Serializable {
    
    private Cell cell;
    private Cell[][] board = new Cell[10][10];
    
    private boolean rotated = false;
    private Player player;
    
    public DesignedBoard(Player player) {
        
        super();
        
        this.player = player;
        this.setPrefColumns(10);
        this.setTileAlignment(Pos.CENTER);
        
        for (int col = 0; col < 10; col++) {
            for (int row = 0; row < 10; row++) {
                board[row][col] = new Cell(row, col);
                this.getChildren().add(board[row][col]);
            }
        }
        
    }
    
    public Cell[][] getBoard() {
        return board;
    }

    public boolean isRotated() {
        return rotated;
    }

    public void setRotated(boolean rotated) {
        this.rotated = rotated;
    }
    
    public void placeShip(ArrayList<Integer> shipSizes) {          
        for (Cell[] cell : board) {
            for (Cell c : cell) {
                c.setonmouseentered(e -> mouseInPlacingShips(e, shipSizes.get(0)));
                c.setOnMouseExited(e -> mouseOutPlacingShips(e, shipSizes.get(0)));                   
                c.setOnMouseClicked(e -> createShip(e, shipSizes)); 
            }
        }
    }

    private void mouseInPlacingShips(MouseEvent e, int shipSize) {
        
        Cell current = (Cell) e.getSource();
        
        int maxCell = board[0].length - shipSize;
        
        int row = current.getRow();
        int col = current.getCol();
        
        if (!current.isShip()) {
           
            if (!rotated) {
                
                int y = col;
                
                if (y > maxCell) {
                    
                    for (int i = maxCell; i < board[0].length; i++) {
                        if (board[row][i].isShip()) {
                            return;
                        }
                    }
                    
                    for (int i = maxCell; i < board[0].length; i++) {
                        board[row][i].setFill(Color.SPRINGGREEN);
                    }
                    
                } else {
                    
                    for (int i = col; i < col + shipSize; i++) {
                        if (board[row][i].isShip()) {
                            return;
                        }
                    }
                    
                    while (y < board[0].length && y < (col + shipSize)) {
                        board[row][y].setFill(Color.SPRINGGREEN);
                        y++;
                    }
                }
            } else {
                
                int x = row;
                
                if (x > maxCell) {
                    
                    for (int i = maxCell; i < board[0].length; i++) {
                        if (board[i][col].isShip()) {
                            return;
                        }
                    }
                    
                    for (int i = maxCell; i < board[0].length; i++) {
                        board[i][col].setFill(Color.SPRINGGREEN);
                    }
                    
                } else {
                    
                    for (int i = row; i < row + shipSize; i++) {
                        if (board[i][col].isShip()) {
                            return;
                        }
                    }
                     
                    while (x < board[0].length && x < (row + shipSize)) {
                        board[x][col].setFill(Color.SPRINGGREEN);
                        x++;
                    }
                }
            }
        }
    }

    private void mouseOutPlacingShips(MouseEvent e, int shipSize) {
        clearAll();         
    }

    private void createShip(MouseEvent e, ArrayList<Integer> shipSizes) {
        int shipSize = shipSizes.get(0);
        
        Cell current = (Cell) e.getSource();
        int row = current.getRow();
        int col = current.getCol();
        
        int maxCell = board[0].length - shipSize;
        ArrayList<Cell> ship = new ArrayList<>();
        
        if (!rotated) {
            if (col > maxCell) {
                for (int i = maxCell; i < board[0].length; i++) {
                    ship.add(board[row][i]);
                }
            } else {
                for (int i = col; i < col + shipSize; i++) {
                    ship.add(board[row][i]);
                }
            }
        } else {
            if (row > maxCell) {
                for (int i = maxCell; i < board[0].length; i++) {
                    ship.add(board[i][col]);
                }
            } else {
                for (int i = row; i < row + shipSize; i++) {
                    ship.add(board[i][col]);
                }
            }
        }
        
        try {
            player.addShip(new Ship(ship, player));
            for (Cell s : ship) {
                s.setFill(Color.DARKSEAGREEN);
            }
            
            shipSizes.remove(0);
            if (!shipSizes.isEmpty()) {
               Main.placeShips(shipSizes);
            }
            
        } catch (ShipAlreadyCreatedException ex) {
            return;
        }
    }

    private void clearAll() {
        
        for (int col = 0; col < 10; col++) {
            for (int row = 0; row < 10; row++) {
                if (!board[row][col].isShip()) {
                   board[row][col].setFill(Color.TRANSPARENT);
                }
            }
        }
    }
    
}



I tried putting if statement to only do mouseOut if an array shipSizes is empty, but I still get an exception. If I remove the method clearAll() that clears boats from array, then I cannot make it so that with each mouseOver I can place a new ship.
Was This Post Helpful? 0
  • +
  • -

#4 ndc85430  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 590
  • View blog
  • Posts: 2,487
  • Joined: 13-June 14

Re: Help with JavaFX Battleship Project

Posted 06 November 2017 - 11:53 AM

Do you understand what the exception is telling you? You need to work backwards from there to see why the relevant ArrayList is empty.
Was This Post Helpful? 1
  • +
  • -

#5 prubic  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 10-November 15

Re: Help with JavaFX Battleship Project

Posted 06 November 2017 - 11:57 AM

I know that it is empty because I remove the ship from the Array so that it is not in the mouseOver when I already placed it. But I don't know how to keep it in the array but still move to the next ship and end placing them after the loop has gone through the entire Array of them.
Was This Post Helpful? 0
  • +
  • -

#6 snoopy11  Icon User is offline

  • Engineering ● Software
  • member icon

Reputation: 1377
  • View blog
  • Posts: 4,318
  • Joined: 20-March 10

Re: Help with JavaFX Battleship Project

Posted 06 November 2017 - 01:03 PM

It looks like a Design consideration, have you considered two Arrays, one for mouseOver and one to keep track of the placing ?
Was This Post Helpful? 1
  • +
  • -

#7 prubic  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 10-November 15

Re: Help with JavaFX Battleship Project

Posted 06 November 2017 - 01:31 PM

I could make two arrays, so if I do that I would addShips to both of the arrays and then use one of them for the mouseExited and mouseEntered and the other for the code?
Was This Post Helpful? 0
  • +
  • -

#8 snoopy11  Icon User is offline

  • Engineering ● Software
  • member icon

Reputation: 1377
  • View blog
  • Posts: 4,318
  • Joined: 20-March 10

Re: Help with JavaFX Battleship Project

Posted 06 November 2017 - 01:54 PM

Yes ... why not..?

Keep track of the ships through a counter variable.
Was This Post Helpful? 1
  • +
  • -

#9 prubic  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 10-November 15

Re: Help with JavaFX Battleship Project

Posted 06 November 2017 - 02:08 PM

Ok, I will try and write that code and then I will send it back to you to check if that would work.

Thank you!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1