Home > front end >  Replacing 2d array index if player position has values of a list
Replacing 2d array index if player position has values of a list

Time:06-05

So right now when a player enters a position (pos) like A5 for example it will replace that board array index with the empty string if a ship isnt there. But if a ship is there I want it to replace it with the hitShip string.

public static void placePiece(String[][] board, String pos) {
        String empty = "0";
        String hitShip = "X";
        playerTargets.add(pos);

        switch (pos) {
            case "A1":
                board[1][2] = empty;
                break;
            case "B1":
                board[1][4] = empty;
                break;
            case "C1":
                board[1][6] = empty;
                break;
            case "D1":
                board[1][8] = empty;
                break;
            case "E1":
                board[1][10] = empty;
                break;
            case "F1":
                board[1][12] = empty;
                break;
            case "G1":
                board[1][14] = empty;
                break;
            case "H1":
                board[1][16] = empty;
                break;
            case "I1":
                board[1][18] = empty;
                break;
            case "J1":
                board[1][20] = empty;
                break;

And the switch case goes on for all coordinates (A1-J10)

ship1 has values "A6" & "A7" and ship2 has values "F1" & "F2".

 List ship1 = Arrays.asList(ar[0][0], ar[1][0]);
 List ship2 = Arrays.asList(ar[2][0], ar[3][0]);

I have this code to print hit/miss message depending on whether the player hit a ship but I'm not sure how I can use this to replace the board array's indexes with the hitShip variable.

// CHECKS IF THE PLAYER TARGETS HIT SHIP1
        boolean hit = false;
        for (Object string : ship1) {
            if (pos.contains((CharSequence) string)) {
                hit = true;
                break;
            }
        }
        // CHECKS IF THE PLAYER TARGETS HIT SHIP2
        for (Object string : ship2) {
            if (pos.contains((CharSequence) string)) {
                hit = true;
                break;
            }
        }

        // PRINTS HIT/MISS MESSAGE DEPENDING ON WETHER THE PLAYER HIT A SHIP
        if (hit) {
            System.out.println("\nHit!!!");
        } else {
            System.out.println("\nMiss!!!");
        }

This is the full code

 import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

import javax.sound.midi.Track;

public class Battleship {

    static ArrayList<String> playerTargets = new ArrayList<String>();
    String[] ship1 = new String[] { ar[0][0], ar[1][0] };
    String[] ship2 = new String[] { ar[2][0], ar[3][0] };

    // and we'll have an array of all these ships just to make things easier
    String[][] ships = new String[] { ship1, ship2 };

    public static void main(String[] args) throws FileNotFoundException {

        String[][] board = {
                { " ", " ", "A", " ", "B", " ", "C", " ", "D", " ", "E", " ", "F", " ", "G", " ", "H", " ", "I", " ",
                        "J" },
                { "1", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
                        " " },
                { "2", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
                        " " },
                { "3", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
                        " " },
                { "4", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
                        " " },
                { "5", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
                        " " },
                { "6", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
                        " " },
                { "7", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
                        " " },
                { "8", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
                        " " },
                { "9", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
                        " " },
                { "1", "0", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
                        " ", " " } };
        System.out.println("Let's Play Battleship!");
        printBoard(board);

        for (int i = 1; i < 31; i  ) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("Choose your target Ex.(A3): ");
            String pos = scanner.next();

            while (playerTargets.contains(pos)) {
                System.out.println("Position taken! Please enter a valid position: ");
                pos = scanner.next();
            }

            placePiece(board, pos);
            String result = ships(board, pos);

            // ENDS THE PROGRAM IF USER HAS HIT ALL THE SHIPS
            if (result.length() > 0) {
                printBoard(board);
                System.out.println();
                System.out.println(result);
                break;
            }

            System.out.println("You have "   (30 - i)   " missiles left");
            printBoard(board);

        }

    }

    public static void printBoard(String[][] board) {
        for (String[] row : board) {
            for (String c : row) {
                System.out.print(c);
            }
            System.out.println();
        }
    }

    public static String ships(String[][] board, String pos) throws FileNotFoundException {

        // READS SHIP POSITIONS FROM SHIP FILE
        String filePath = "/Users/Otez/Desktop/ships.txt";
        List<String[]> list = new ArrayList<>();
        try {
            Scanner scanner = new Scanner(new File(filePath));
            while (scanner.hasNextLine()) {
                String[] arr = scanner.nextLine().split(",");
                for (String item : arr) {
                    list.add(new String[] { item });
                }
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
        String[][] ar = list.toArray(String[][]::new);

        // CHECKS IF THE PLAYER TARGETS HIT SHIP1
        boolean hit = false;
        for (Object string : ship1) {
            if (pos.contains((CharSequence) string)) {
                hit = true;
                break;
            }
        }
        // CHECKS IF THE PLAYER TARGETS HIT SHIP2
        for (Object string : ship2) {
            if (pos.contains((CharSequence) string)) {
                hit = true;
                break;
            }
        }

        // PRINTS HIT/MISS MESSAGE DEPENDING ON WHETHER THE PLAYER HIT A SHIP
        if (hit) {
            System.out.println("\nHit!!!");
        } else {
            System.out.println("\nMiss!!!");
        }

        // CHECKS IF PLAYER TARGETS HIT THE SHIPS ON THE BOARD
        if (playerTargets.contains(ship1) && playerTargets.contains(ship2)) {
            return "YOU SANK MY ENTIRE FLEET!!!\n";
        }
        return "";
    }

    public static void placePiece(String[][] board, String pos) {
        String empty = "0";
        String hitShip = "X";
        playerTargets.add(pos);

        int firstIndex = Character.getNumericValue(pos.charAt(1));
        int secondIndex = (pos.charAt(0) - 64) * 2;
        board[firstIndex][secondIndex] = empty;
        String characterToPlace = empty;
        if (isShip(board, pos)) {
            characterToPlace = hitShip;
        }
        board[firstIndex][secondIndex] = characterToPlace;
    }

    public static boolean isShip(String[][] board, String pos) {
        for (String[] ship : ships) {
            for (String shipPos : ship) {
                if (shipPos.contains(pos)) {
                    return true;
                }
            }
        }
        return false;
    }
}

CodePudding user response:

As you can see, writing and maintaining massive switch statements make for a not-so-elegant solution. The first thing I suggest you do, is clear up that code. Just from looking at it, I can see that as the letter in the first character of pos progresses through the alphabet, the second index you use on board increases by two.

So let's just resolve all this duplicate code using the magic of ASCII:

public static void placePiece(String[][] board, String pos) {
    String empty = "0";
    String hitShip = "X";
    playerTargets.add(pos);

    int firstIndex = Character.getNumericValue(pos.charAt(1));
    int secondIndex = (pos.charAt(0) - 64) * 2;
    board[firstIndex][secondIndex] = empty;
}

Now whatever pos is, gets marked as empty. If I were you, I would now have a separate method which determines whether a ship was hit - it's good practice to try make your code more modular.

It seems to me that you don't really need to use lists, you could just use arrays for your ships:

String[] ship1 = new String[] {ar[0][0], ar[1][0]};
String[] ship2 = new String[] {ar[2][0], ar[3][0]};

//and we'll have an array of all these ships just to make things easier
String[][] ships = new String[] {ship1, ship2};

These variables would ideally be global, because we don't need to keep creating them every time we check to see if the user has hit a ship.

Now we'll make a function to determine whether there is a ship at a location - remember, modular code is easier to change and maintain. I've written it very similarly to how you did, it just becomes shorter when using an array of ships.

public static boolean isShip(String[][] board, String pos) {
    for (String[] ship : ships) {
        for (String shipPos : ship) {
            if (shipPos.contains(pos)) {
                return true;
            }
        }
    }
    return false;
}

Now, we just incorporate our new isShip method into our rewritten placePiece method:

public static void placePiece(String[][] board, String pos) {
    String empty = "0";
    String hitShip = "X";
    playerTargets.add(pos);

    int firstIndex = Character.getNumericValue(pos.charAt(1));
    int secondIndex = (pos.charAt(0) - 64) * 2;
    String characterToPlace = empty;
    if (isShip(board, pos)) {
        characterToPlace = hitShip;
    }
    board[firstIndex][secondIndex] = characterToPlace;
}

I've not tested the code but from looking at it, it should all work. From reading your code, I'd recommend you learn more about:

  • Structuring your code in a modular way
  • Writing 'clean' code

And I recommend holding off from using Lists until you learn about generics.

  •  Tags:  
  • java
  • Related