如果玩家位置具有列表值,则替换二维数组索引

Replacing 2d array index if player position has values of a list

所以现在当玩家进入一个位置 (pos) 时,例如 A5,如果那里没有船,它将用空字符串替换该棋盘数组索引。但是如果那里有一艘船,我希望它用 hitShip 字符串替换它。

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;

所有坐标 (A1-J10) 的开关盒都适用

ship1 的值为“A6”和“A7”,ship2 的值为“F1”和“F2”。

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

我有这段代码可以根据玩家是否击中船只来打印 hit/miss 消息,但我不确定如何使用它来用 hitShip 变量替换棋盘数组的索引。

// 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!!!");
        }

这是完整代码

 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;
    }
}

如您所见,编写和维护大量 switch 语句构成了 not-so-elegant 解决方案。我建议您做的第一件事是清除该代码。仅通过查看,我可以看到随着 pos 的第一个字符中的字母在字母表中前进,您在 board 上使用的第二个索引增加了两个。

所以让我们使用 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;
}

现在无论 pos 是什么,都被标记为空。如果我是你,我现在会有一个单独的方法来确定船只是否被击中 - 尝试使你的代码更加模块化是一种很好的做法。

在我看来你并不真的需要使用列表,你可以只为你的船使用数组:

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 boolean isShip(String[][] board, String pos) {
    for (String[] ship : ships) {
        for (String shipPos : ship) {
            if (shipPos.contains(pos)) {
                return true;
            }
        }
    }
    return false;
}

现在,我们只需将新的 isShip 方法合并到重写的 placePiece 方法中:

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;
}

我没有测试过代码,但从代码来看,它应该都能正常工作。通过阅读您的代码,我建议您了解更多信息:

  • 以模块化方式构建代码
  • 正在编写 'clean' 代码

并且我建议在了解泛型之前不要使用 List