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

时间:2018-10-20 11:51:27

标签: java text-based

我是这里的新手(通常是stackoverflow和编程),并且正在尝试用Java创建战舰游戏。我对自己拥有的东西感到非常满意,并且知道代码可能不是最有效的,但这不是我想在这里解决的问题。

在输入要放置您的船的位置或要攻击的位置时,在我输入之前,它会询问列是什么,然后分别询问行是什么。现在,我正在尝试制作一种方法(称为坐标,这是最后一个方法),该方法将允许您一起输入坐标(格式为“ A1”)。效果很好,直到输入错误(有两个字母,两个数字,其中什么都没有,等等...)

另一件事是在坐标方法中,我不得不在catch中放入return 20,因为它说缺少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.

我们将不胜感激,即使它有不同的帮助(不是我要解决的问题)。

1 个答案:

答案 0 :(得分:0)

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

样品运行:

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}

我创建了一个用于存储坐标的助手类。

请注意,所有读取/写入是如何在一个函数(readCoordinate)中进行的,而所有字符串操作都在另一个函数(parseCoordinate)中。

如果用户字符串无效,也可能引发异常,为简单起见,我返回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是final?这不是意味着您以后不能更改它们吗?

这意味着您不能在第一次分配后分配给他们(在构造函数中)。创建不可变(不可变==不能更改)数据类是一个好习惯。例如,您确定如果将Coordinate传递给方法,该方法将无法修改您的实例,并且不会弄乱Coordinate

什么是修剪?

Trim删除字符串两端的空格(空格,制表符,...)。 " hello world! ".trim()"hello world!"

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

我一次创建了扫描仪,并多次使用。每次您想读取一个字符串时,您都创建了一个新的扫描仪。我认为这对扫描仪无关紧要,但是在某些情况下,您可能会因重新创建对象而丢失东西。

在readCoordinate中,while条件的真实情况是什么?

while (true)表示永远循环。有一个return语句打破了否则的无限循环。

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

字符用数字表示,因此字符是内在的数字。在Java中,char就像一个16位无符号整数,您可以对其进行常规的整数计算。

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

在您精通编程之前,请不要理会访问修饰符。在小程序中这没有多大意义。您可以标记应从外部调用哪些方法,而不应从外部调用。