如何解决为二维数组制作边框的最佳方法?
我目前正在处理 2D 数组,虽然我发现它们易于使用,但我经常面临为它们创建边界以及处理它的步骤的挑战。例如,我正在重做我用 python 制作的战舰游戏。 python版本没有边框,但是java版本我想挑战一下。
我尝试在初始化板的方法中创建边框,但是当我在主方法中调用板时会导致格式问题。现在我正在使用嵌套的 for 循环处理 main 中的边框,虽然结果变得更好,但边框仍然不完整。我正在尝试创建我在网上找到的这个边框:
+---+
| |
+---+
但是我没有成功。这是我的代码:
public static String[][] Battlefield() {
int row;
int col;
int cap_start = 65;
//Makes board
String[][] BattleBoard = new String[11][11];
for (row = 0; row < BattleBoard.length; row++) {
for (col = 0; col < BattleBoard[row].length; coL++) {
if (row == 0) {
//System.out.print(
// " " + Character.toString((char) cap_start) + " ");
BattleBoard[row][col] =
" " + Character.toString((char) cap_start) + " ";
cap_start++;
} else if (col == 0) {
//Gives us 0-9
//System.out.print(Integer.toString(row - 1) + " ");
BattleBoard[row][col] = (Integer.toString(row - 1)) + " ";
} else {
//System.out.print(" ");
BattleBoard[row][col] = " ";
}
}
}
return BattleBoard;
}
public static void main(String[] args) {
Scanner userInput = new Scanner(system.in);
Scanner colInput = new Scanner(system.in);
Scanner rowInput = new Scanner(system.in);
String player_col = "";
String player_row = "";
String[][] gameBoard = Battlefield();
for (int row = 0; row < gameBoard.length; row++) {
for (int col = 0; col < gameBoard[row].length; coL++) {
System.out.print(gameBoard[row][col] + " |");
if (row <= gameBoard.length - 1)
System.out.print("+---+");
}
System.out.println();
}
}
解决方法
这是我整理的东西。
A B C D E F G H I J K
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
1 + + + + + + + + + + + +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
2 + + + + + + + + + + + +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
3 + + + + + + + + + + + +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
4 + + + + + S + + + + + + +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
5 + + + + + S + + + + + + +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
6 + + + + + S + + + + + + +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
7 + + + + + S + + + + + + +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
8 + + + + + S + + + + + + +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
9 + + + + + + + + + + + +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
10 + + + + + + + + + + + +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
11 + + + + + + + + + + + +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
我创建了一个二维 char
网格来保存船舶的位置、命中、未命中和水位。
我使用了几个 StringBuilders
来创建网格的显示。网格的显示由Strings
组成。实际的网格阵列是逻辑模型。
我在网格中放了一艘船,这样你就可以看到它的样子了。
我将 displayGrid
方法分解为三个从属方法。分工,你可以分别专注于展示的每个部分。
在 Java 中,类名以大写字母开头。字段和方法名称以小写字母开头。类名通常是名词-动词组合。方法名称通常是动词-名词组合。一般来说,尽快摆脱静态世界是个好主意。
这是完整的可运行代码。
public class BattleshipDisplay {
public static void main(String[] args) {
BattleshipDisplay bd = new BattleshipDisplay();
char[][] grid = bd.createGrid();
System.out.println(bd.displayGrid(grid));
}
public char[][] createGrid() {
char[][] grid = new char[11][11];
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
grid[i][j] = ' ';
}
}
grid[3][4] = 'S';
grid[4][4] = 'S';
grid[5][4] = 'S';
grid[6][4] = 'S';
grid[7][4] = 'S';
return grid;
}
public String displayGrid(char[][] grid) {
StringBuilder builder = new StringBuilder();
String section = "+-----";
builder.append(printHeaderLine(grid));
builder.append(printDashedLine(grid,section));
builder.append(printGrid(grid,section));
return builder.toString();
}
private StringBuilder printHeaderLine(char[][] grid) {
StringBuilder builder = new StringBuilder();
builder.append(" ");
for (int i = 0; i < grid.length; i++) {
builder.append((char) ((int) 'A' + i));
builder.append(" ");
}
builder.append(System.lineSeparator());
return builder;
}
private StringBuilder printGrid(char[][] grid,String section) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < grid.length; i++) {
builder.append(String.format("%3d",(i + 1)));
builder.append(" ");
for (int j = 0; j < grid[i].length; j++) {
builder.append("+ ");
builder.append(grid[i][j]);
builder.append(" ");
}
builder.append("+");
builder.append(System.lineSeparator());
builder.append(printDashedLine(grid,section));
}
return builder;
}
private StringBuilder printDashedLine(char[][] grid,String section) {
StringBuilder builder = new StringBuilder();
builder.append(" ");
for (int i = 0; i < grid.length; i++) {
builder.append(section);
}
builder.append("+");
builder.append(System.lineSeparator());
return builder;
}
}
,
您可以将字段的每个单元格表示为一个几乎正方形,由两行组成:一个上边框和一个带有右边框的元素,使用 box-drawing characters:
───┼
X │
截图:
输出由三部分组成:上一行字母,然后是一个包含左列数字和下边界行的字段。因此,包含船舶的整个字段可能如下所示:
│ A │ B │ C │ D │ E │ F │ G │ H │ I │ J │
───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
1 │ │ │ X │ │ │ │ X │ X │ X │ │
───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
2 │ X │ │ │ │ │ │ │ │ │ │
───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
3 │ │ │ X │ X │ X │ X │ │ │ │ │
───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
4 │ │ │ │ │ │ │ │ │ │ X │
───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
5 │ │ │ │ │ │ │ │ │ │ X │
───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
6 │ │ │ X │ │ │ │ X │ │ │ X │
───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
7 │ X │ │ │ │ │ │ X │ │ │ │
───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
8 │ X │ │ │ │ │ │ │ │ │ │
───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
9 │ │ │ │ │ X │ │ │ │ │ X │
───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
10 │ │ │ │ │ X │ │ │ │ │ │
───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
截图:
public static String[] outputField(String[][] field,int n) {
return Stream.of(
// upper row of letters
Stream.of(IntStream.range(-1,n)
// first an empty square
.mapToObj(i -> i < 0 ? " │" :
// then squares with letters
" " + Character.toString('A' + i) + " │")
.collect(Collectors.joining())),// field with a left column of numbers
IntStream.range(0,n)
// row of the field,line of squares
.mapToObj(i -> IntStream.range(0,n)
// first a square with a number,then squares of the field
.mapToObj(j -> new String[]{
// upper row of square with an upper border
(j == 0 ? "───┼" : "")
+ "───" + (j < n - 1 ? "┼" : "┤"),// lower row of square with element and right border
(j == 0 ? String.format("%2d",(i + 1)) + " │" : "")
+ " " + field[i][j] + " │"})
// reduce Stream<String[]> to a single array String[]
.reduce((arr1,arr2) -> IntStream.range(0,2)
.mapToObj(j -> arr1[j] + arr2[j])
.toArray(String[]::new))
.orElse(new String[]{}))
.flatMap(Arrays::stream),// lower border row
Stream.of(IntStream.range(-1,n)
.mapToObj(i -> i < n - 1 ? "───┴" : "───┘")
.collect(Collectors.joining())))
.flatMap(Function.identity())
.toArray(String[]::new);
}
public static void main(String[] args) {
int n = 10;
String[][] field = IntStream.range(0,n)
.mapToObj(i -> new String[n])
.peek(row -> Arrays.fill(row," "))
.toArray(String[][]::new);
// four-pipe ship
field[2][2] = field[2][3] = field[2][4] = field[2][5] = "X";
// three-pipe ships
field[0][6] = field[0][7] = field[0][8] = "X";
field[3][9] = field[4][9] = field[5][9] = "X";
// two-pipe ships
field[5][6] = field[6][6] = "X";
field[8][4] = field[9][4] = "X";
field[6][0] = field[7][0] = "X";
// one-pipe ships
field[0][2] = "X";
field[1][0] = "X";
field[5][2] = "X";
field[8][9] = "X";
// output
Arrays.stream(outputField(field,n)).forEach(System.out::println);
}
另见:
• Formatting 2d array of numbers
• How to draw a staircase with Java?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。