简体   繁体   中英

Java battleship using arraylist: comparing user input to array list

I am trying to finish up an assignment for class I have been working on. I am supposed to build a battleship game using a location class, arraylist, and 2D array against a computer. The user gets 8 guesses on a 5x5 board. I am attacthing the directions below so it is more clear.

I am currently stuck trying to check if the users guess (in row, col form) matches the location object of a ship stored in the arraylist, however, no matter what your input, it always evaluates it as else, and marks it as a miss (aka places an X on the board). What am I doing wrong?

directions page 1 directions page 2

Here is my code so far:

driver class:

import java.util.Random; import java.util.Scanner; import java.util.ArrayList; 

public class battleshipDriver {

    public static void main(String[] args) {
        //fields
        char [][] board = new char[5][5]; // game board array
        ArrayList<Location> Location1 = new ArrayList<>(); // array list to hold location objects
        initialBoard(board); // prints initial board state
        Random computer = new Random(); //create num gen for computer placements
        int row, col;
        Scanner user = new Scanner(System.in);

        //stuff that is doing things
        //puts comp's placements in Location
        for(int i = 0; i <= 4; i ++) {
            row = computer.nextInt(5);
            col = computer.nextInt(5);
            Location battleship = new Location(row, col);
            Location1.add(battleship);
        }
        System.out.println(Location1);
        int turnsLeft = 8;
        int numShips = 4;
        do {
            System.out.println("You have " + turnsLeft + " turns left." + "\n"
                + "There are " + numShips + " ships left.");
            System.out.println("Please make a guess (row, column)");

            row = user.nextInt();
            col = user.nextInt();
            Location userGuess = new Location(row, col);

            if(row>4 || col>4 ) {
                System.out.println("Your move is invalid.");
            }

            else if (board[row][col] == 'X' || board[row][col] == '*') {
                System.out.println("You have already guessed that location");
            }
            for(Location loc: Location1) {
                if(Location1.contains(userGuess)) {
                    Location1.remove(userGuess);
                    board[row][col] = '*';
                    updateBoard(board);
                    System.out.println("You hit a ship");
                    break;
                }
                else {
                    board[row][col] = 'X';
                    updateBoard(board);
                    break;
                }
            }
        }while(turnsLeft != 0);

    }



    //printBoard method
    public static void initialBoard(char[][] board) {
        //for loops iterate through each 
        for(int row = 0; row< board.length; row++) { 
            for(int col = 0; col < board[row].length; col++) {
                board [row][col] = 'O'; //assigns O to signify open water 
                //(this may need to change. Most likely 
                //will always make the board O's only
                System.out.print(board[row][col] + " ");
            }
            System.out.println();
        }
    }
    public static void updateBoard(char[][] board) {
        for(int row = 0; row< board.length; row++) { 
            for(int col = 0; col < board[row].length; col++) {
                System.out.print(board[row][col] + " ");
            }
            System.out.println();
        }


    }
}

location class:

public class Location {
    private int row;
    private int col;

    //getters and setters
    public int getRow() {
        return row;
    }
    public int getCol() {
        return col;
    }

    public void setRow(int row) {
        this.row = row;
    }
    public void setCol(int col) {
        this.col = col;
    }

    //constructors 
    public Location(int row, int col) {
        this.row = row;
        this.col = col;

    }

    public String toString() {
        return  row + ", " + col ;
    }
}

I currently have the array list printing its contents so that I can just input known ship locations to see if i get it working properly.

The Location class must override equals and hashCode for ArrayList#contains(...) to work. That's your problem and its solution.

Make row and col final fields and use them to check for equality and to calculate the hashCode (you must only use invariants to do this).

Something like:

package pkg1;

public class Location {
    private final int row;
    private final int col;

    // getters and setters
    public int getRow() {
        return row;
    }

    public int getCol() {
        return col;
    }

    // make the field immutable!
    // public void setRow(int row) {
    // this.row = row;
    // }

    // make the field immutable!
    // public void setCol(int col) {
    // this.col = col;
    // }

    // constructors
    public Location(int row, int col) {
        this.row = row;
        this.col = col;

    }

    public String toString() {
        return row + ", " + col;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + col;
        result = prime * result + row;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Location other = (Location) obj;
        if (col != other.col)
            return false;
        if (row != other.row)
            return false;
        return true;
    }
}

In the contains(...) method entry in the ArrayList API :

Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)).

So as you can see, the method uses the .equals(...) method to check for containment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM