Java - 在do while中使用逻辑或

4

我在编程方面比较新,希望您能够耐心等待。

我正在尝试编写一个战舰游戏,目前还没有使用OO技术,而是采用逐步处理的过程式编程方法进行。

我有一个读取要开火的坐标的方法,我想要验证这些坐标是否有效。有一种方法可以检查它们是否为数字,并且是否在正确的范围内,另一种方法则“应该”检查已经输入的内容。

问题在于,在进行while循环时,我无法跳出do while循环来继续执行,while部分采用了两个以逻辑或运算符连接的方法。在编写这些方法时,它们都能够完成其预期功能,但我不能确定检查坐标是否已被击中的方法是否正确。

如果您能提供任何方面的建议,那将不胜感激!

代码:

public static String inputCoords(List<String> coordsFired){
    Scanner sc = new Scanner(System.in);

    //Console c = System.console();
    String coordsEntered;

    do {
        System.out.println("in do\\while");
        System.out.println("Enter coordinates as 'x, y': ");
        coordsEntered = sc.nextLine();
        System.out.println("end of do\\while loop");
    } while(!validateCoords(coordsEntered) 
         || !coordsFiredAt(coordsEntered, coordsFired));

    coordsFired.add(coordsEntered);
    System.out.println("contents of List<String> coordsFired" + coordsFired);

    return coordsEntered;
}

public static boolean validateCoords(String coordsEntered){
    boolean results;
    int x, y;
    String strx = splitCoordsString(coordsEntered, 'x');
    String stry = splitCoordsString(coordsEntered, 'y');

    if (numericCheckCoordsFire(strx) && numericCheckCoordsFire(stry)) {
        x = Integer.parseInt(strx);
        y = Integer.parseInt(stry);

        if (x > 25 || y > 25) {
            results = false;
            System.out.println("The dimensions of the board are 25 x 25, 'x,y' entered must be less than this.  You entered '" + strx + "' for x and '" + stry + "' for y.");
        } else {
            results = true;
        }
    } else {
        results = false;
        System.out.println("Coords are supposed to be numbers...  You entered '" + strx + "' for x and '" + stry + "' for y.");
    }

    System.out.println(results);
    return results;
}

public static boolean coordsFiredAt(String coordsEntered, List<String> coordsFired) {
    boolean results = false;

    // go through each item in the list and compare against coordsEntered
    for (String s : coordsFired) {
        System.out.println("in for loop, printing iterated var" + s);

        if (s.equals(coordsEntered)) {
            // put these matched coordsFire into listHit
            results = false;
        } else {
            System.out.println("already fired at " + coordsEntered);
            results = true;
        }
    }

    return results;
}

1
在自学编程时,我正在尝试编写一款战舰游戏;目前还不是面向对象的,而是过程式的 - 一步一步来。这样你就像在学爬行时参加马拉松一样,很辛苦。说真的,我建议你停下来,逐步学习。你可以从Java教程开始。 - Luiggi Mendoza
2
我建议通过做自己感兴趣的事情来学习。我一次又一次地自掘坟墓,试图按照“逻辑”方式学习。这只是一个观点,但我强烈建议不要听Luiggi Mendoza的话。但他说的从头到尾确实很多。但那也是乐趣的一部分,对吧?=D - Einar
2
我认为在coordsFiredAt()函数中是这样的:'if (s.equals(coordsEntered)) {'。当结果应该为true时,结果是否被设置为false了? - Einar
对于指针,我建议注释方法的预期功能。coordsFireAt() 何时返回 true 或 false,validateCoords() 同理?请在函数/方法名称上方进行注释。此外,我会稍微修改您使用的变量名称。我发现它们的名称有点难以理解其意图。 - Einar
1
Laambi - 就是这样,我把它们搞反了... 感谢你的指点,非常感谢。 - sebastientorres
显示剩余2条评论
2个回答

3
我建议您在IT技术中加入面向对象编程(OOP),并为坐标创建一个类(Coords):
public class Coords {

    private final int x;
    private final int y;

    public Coords(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    /**
     * This method is used for Coords comparison
     */
    @Override
    public boolean equals(Object o) {
        Coords coords = (Coords) o;
        return y == coords.y && coords.x ==x;
    }

    /**
     * This method is used to output coords.
     */
    @Override
    public String toString() {
        return "(" + x + "," + y + ")";
    }
}

你的代码将如下所示:

所以你的代码会像这样:

public static Coords inputCoords(List<Coords> coordsFired) {
        Scanner sc = new Scanner(System.in);

        //Console c = System.console();
        Coords coords;

        do {
            System.out.println("in do\\while");
            System.out.println("Enter coordinates as 'x, y': ");
            String coordsEntered = sc.nextLine();
            coords = parseCoords(coordsEntered);
            System.out.println("end of do\\while loop");
        } while (coords == null || !areCoordsValid(coords) || !areCoordsNotFired(coords, coordsFired));

        coordsFired.add(coords);
        System.out.println("contents of List<String> coordsFired" + coordsFired);

        return coords;
    }

    public static boolean areCoordsValid(Coords coords) {
        boolean result = true;

        if (coords.getX() > 25 || coords.getY() > 25) { // I think you also need to validate that it is possible values
            result = false;
            System.out.println("The dimensions of the board are 25 x 25, 'x,y' entered must be less than this. " +
                    "You entered '" + coords.getX() + "' for x and '" + coords.getY() + "' for y.");
        }

        return result;
    }

    public static boolean areCoordsNotFired(Coords coords, List<Coords> firedCoards) {
        boolean result = true;
        if (firedCoards.contains(coords)) {
            result = false;
            System.out.println("You already fired at " + coords.getX() + "," + coords.getY());
        }
        return result;
    }

    public static Coords parseCoords(String coordsEntered) {
        Coords coords = null;
        try {
            String[] splittedCoords = coordsEntered.split(","); // Method splits values by comma. It should return an array of Strings with x value at the first element and y at the second one;
            if (splittedCoords.length == 2) {
                String x = splittedCoords[0].trim(); // Method removes all spaces at the beginning and ending of a passed String
                String y = splittedCoords[1].trim();
                coords = new Coords(Integer.parseInt(x), Integer.parseInt(y)); //Creates new instance of Coords class. x and y are passed as constructor params.
            } else {
                System.out.println("Format for coords is wrong.  You entered '" + coordsEntered + "'.");
            }

        } catch (NumberFormatException e) { // Integer.parseInt throws an exception if the string does not contain parsable integer.
            // We catch an exception and handle it by writing a message
            System.out.println("Coords are supposed to be numbers...  You entered '" + coordsEntered + "'.");
        }
        return coords;
    }

在这种情况下,更适用的是Set。Set不包含重复元素,并且Set.contains()方法比List.contains()方法更快。但是,如果要使用Set,则应实现equals()hashCode()方法。


1
你想要在坐标无效或已被攻击时进行循环。
所以while条件应该是什么?
while(!validateCoords(coordsEntered) 
     || coordsFiredAt(coordsEntered, coordsFired))

根据提供的片段,那是正确的。不过Laambi理解了我想做的事情并把我带上了正确的道路。 - sebastientorres
3
List类有一个包含方法contains(),因此您可以将coordsFiredAt(coordsEntered,coordsFired) 替换为 coordsFired.contains(coordsEntered) - Conffusion
谢谢!非常有帮助。 - sebastientorres

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接