战舰坐标输入(带字母)Java

Battleship coordinate input (with letter) Java

我是新来的(一般的 Whosebug 和编程),我正在尝试在 Java 中创建一个战舰游戏。我对自己拥有的东西很满意,并且知道代码可能不是最有效的,但这不是我想在这里解决的问题。

在输入你的船放在哪里或攻击哪里的时候,之前我有这样它会问列是什么,然后分别问行是什么。现在我正在尝试制作一个方法(称为坐标,它是最后一个),允许您一起输入坐标(格式为 'A1')。它运行完美,直到输入错误(有两个字母,两个数字,其中没有任何内容,等等)

另一件事是在坐标方法中,在 catch 中我不得不输入 return 20 因为它说缺少 return 语句,但我实际上不需要 return do-while 循环中的任何内容。我该怎么做才能把它拿走?

这是我在这个网站上的第一个问题,所以我不知道是否有人需要这个(我不知道是否有任何规则禁止不必要的代码),但我会把整个程序留在这里,以及示例输出。

public static int firing(String[][] board, int hits, int torpedoes, int shipSize, int shipAmount, int whatPlayer)
{
    Scanner userInput = new Scanner(System.in);
    System.out.println("What coordinate do you want?");
    String coordinate = userInput.nextLine();
    int col = coordinates(coordinate, "col");
    int row = coordinates(coordinate, "row");
    while (col > 8 || col < 1 || row > 8 || row < 1)
    {
        System.out.println("That is not a valid coordinate.");
        Scanner input = new Scanner(System.in);
        System.out.println("What coordinate do you want?");
        coordinate = input.nextLine();
        col = coordinates(coordinate, "col");
        row = coordinates(coordinate, "row");
    }

}

public static int letterToNumber(String colLet)
//colLet = column in letter
//This method is to change the column letters to numbers
{
    int num = 1;
    while (!colLet.equalsIgnoreCase("A")&&
           !colLet.equalsIgnoreCase("B")&&
           !colLet.equalsIgnoreCase("C")&&
           !colLet.equalsIgnoreCase("D")&&
           !colLet.equalsIgnoreCase("E")&&
           !colLet.equalsIgnoreCase("F")&&
           !colLet.equalsIgnoreCase("G")&&
           !colLet.equalsIgnoreCase("H"))
    {
        System.out.println("That is not a valid coordinate (not one of the letters)");
        Scanner input = new Scanner(System.in);
        System.out.println("Please enter a valid coordinate: "
                + "\nIt should be in the format 'A1' (column then row)");
        String coordinate = input.nextLine();
        colLet = "" + coordinate.charAt(0);
    }
    switch (colLet.toLowerCase())
    {
        case "a": num = 1; break;
        case "b": num = 2; break;
        case "c": num = 3; break;
        case "d": num = 4; break;
        case "e": num = 5; break;
        case "f": num = 6; break;
        case "g": num = 7; break;
        case "h": num = 8; break;
        default: System.out.println("That wasn't a letter!");
    }
    return num;
}


public static int coordinates(String coordinate, String RorC)
// RorC is for Row or column
{
    boolean isValid;
    if (RorC.equals("row"))
    {
        do
        {
            try
            {
                String rowStr = "" + coordinate.charAt(1);
                int row = Integer.parseInt(rowStr);
                isValid = true;
                return row;
            }
            catch(Exception e)
            {
                System.out.println("Error");
                Scanner userInput = new Scanner(System.in);
                System.out.println("That is an invalid coordinate (row probably only had one character)"
                        + "\nPlease enter a valid coordinate."
                        + "\nIt should be in the format 'A1' (column then row)");
                coordinate = userInput.nextLine();
                isValid = false;
                return 20;
            }
        }while(isValid = false);
    }
    else if (RorC.equals("col"))
    {
        do
        {
            try
            {
                String colLet = "" + coordinate.charAt(0);
                int col = letterToNumber(colLet);
                isValid = true;
                return col;
            }
            catch (Exception e)
            {
                System.out.println("Error");
                Scanner userInput = new Scanner(System.in);
                System.out.println(""
                        + "That is an invalid coordinate (col probably had nothing inside it)"
                        + "\nPlease enter a valid coordinate."
                        + "\nIt should be in the format 'A1' (column then row)");
                coordinate = userInput.nextLine();
                isValid = false;
                return 20;
            }
        }while(isValid=false);
    }
    else
    {
        return 0;
    }
}
}

我知道我的代码效率不高,但我会在完成后清理它。 这是一个输出示例(我不知道如何把它放在没有代码格式的框中)

It is now player 1's turn to choose where to place their ships.
Can the other player please turn around.

You will now be placing ship number 1.
Please write 'H' if you want to create a horizontal ship,
or 'V' if you want it to be vertical.
h
________________________________

   A  B  C  D  E  F  G  H  
1  -  -  -  -  -  -  -  -
2  -  -  -  -  -  -  -  -
3  -  -  -  -  -  -  -  -
4  -  -  -  -  -  -  -  -
5  -  -  -  -  -  -  -  -
6  -  -  -  -  -  -  -  -
7  -  -  -  -  -  -  -  -
8  -  -  -  -  -  -  -  -
________________________________

What coordinates do you want your ship to start on?
If it is horizontal, it will go right from there,
and if it is vertical, it will go down from there.
Please enter the coordinates in the format 'A1' (column then row).
If you enter anything after that, it will be ignored.
u9
That is not a valid coordinate (not one of the letters)
Please enter a valid coordinate: 
It should be in the format 'A1' (column then row)
a1
That is not a valid coordinate (addship).
What coordinates do you want your ship to start on?
Please enter them in the format 'A1' (column then row).
If you enter anything after that, it will be ignored.
d7
________________________________

   A  B  C  D  E  F  G  H  
1  -  -  -  -  -  -  -  -
2  -  -  -  -  -  -  -  -
3  -  -  -  -  -  -  -  -
4  -  -  -  -  -  -  -  -
5  -  -  -  -  -  -  -  -
6  -  -  -  -  -  -  -  -
7  -  -  -  S  S  S  -  -
8  -  -  -  -  -  -  -  -
________________________________

This is your board.

将不胜感激任何帮助,即使它是关于不同的东西(不是我要解决的问题)。

我写了一个小程序,输入一个字符串并将其转换为行和列。它会不断询问用户是否输入了无效的字符串。

样本运行:

Provide a coordinate:
hello?
That is not a valid coordinate! Try again.
X4
That is not a valid coordinate! Try again.
C4
Coordinate{col=3, row=4}

我创建了一个帮助程序 class 来存储坐标。

注意所有 reads/writes 都在一个函数 (readCoordinate) 中,而所有字符串操作都在另一个函数 (parseCoordinate) 中。

如果用户字符串无效,您也可以抛出异常,为了简单起见,我return设置为 null。

package com.company;

import java.util.Scanner;

class Coordinate {
    private final int col, row;

    public Coordinate(int col, int row) {
        this.col = col;
        this.row = row;
    }

    @Override
    public String toString() {
        return "Coordinate{" +
                "col=" + col +
                ", row=" + row +
                '}';
    }
}


public class Main {
    private final Scanner input;

    public static void main(String[] args) {
        Main m = new Main();
        System.out.println(m.readCoordinate());
    }

    Main() {
        input = new Scanner(System.in);
    }

    private Coordinate readCoordinate() {
        System.out.println("Provide a coordinate:");

        while (true) {
            String line = input.nextLine();
            Coordinate c = parseCoordinate(line);

            if (c != null)
                return c;

            System.out.println("That is not a valid coordinate! Try again.");
        }
    }

    /**
     * Converts a string like A2 into a Coordinate object. Returns null if string is invalid.
     */
    public Coordinate parseCoordinate(String line) {
        line = line.trim().toLowerCase();

        if (line.length() != 2)
            return null;

        char letter = line.charAt(0);

        if (letter > 'h' || letter < 'a')
            return null;
        int col = letter - 'a' + 1;

        char number = line.charAt(1);
        if (number > '8' || number < '1')
            return null;
        int row = number - '1' + 1;

        return new Coordinate(col, row);
    }
}

问题答案:

什么是@Override?

它是一个可选的装饰器,标志着我正在覆盖一个方法,而不是创建一个新方法。如果我拼错了 toString,比如 tostring,我的 IDE 会警告我,我实际上并没有覆盖某些东西。你可以忽略它。

为什么 col 和 row 是最后的?那不是说以后不能改吗?

这意味着你不能在第一次赋值后给它们赋值(在构造函数中)。创建不可变(不可变 == 不能更改)数据 classes 是一个很好的做法。例如,您确定如果将 Coordinate 传递给方法,该方法将无法修改您的实例,并且您不会弄乱 Coordinate.

什么是 trim?

Trim 从字符串的两端删除 whitespace (space, tab, ...)。 " hello world! ".trim()"hello world!".

在 main 方法之后带有 Scanner(System.in) 的 Main() 是什么东西?

我创建了一次扫描仪并使用了很多次。每次你想读取一个字符串时,你都创建了一个新的扫描器。我认为这对扫描仪来说并不重要,但在某些情况下,您可能会通过重新创建对象而丢失一些东西。

在readCoordinate中,while条件下的true是多少?

while (true)表示永远循环。有一个 return 语句可以打破无限循环。

在 parseCoordinate 中,定义 col 时,如何将一个字符添加到一个 int 中?

字符使用数字表示,因此字符实际上是数字。在 Java 中 char 就像一个 16 位无符号整数,你可以对它们进行正常的整数计算。

为什么 readCoordinate 是 Coordinate 类型,为什么是私有的?

在您更好地编程之前,不要为访问修饰符烦恼。在小程序中意义不大。您可以标记哪些方法应该从外部调用,哪些方法不应该。