1

在 Android 上创建一个将使用 RMI 和 Tomcat 的小型战舰游戏。

我需要从文本文件“boards.txt”加载数据,并可能将其存储在 HashMap 中以便查询。

我无法附加该文件,但下面是记事本中 .txt 文件的屏幕截图。它显示了 10,000 个战舰游戏板的板布局(我认为无论如何都是这个数字),它们是 10x10 网格。

因此,文件的每 100 个字符将是不同船只的位置和 10 x 10 网格的空格,每个网格由换行符分隔。

我正在努力的是实际的解析。我认为将数据保存到 HashMap 将使搜索随机板布局变得更加容易。下面是我目前用来读取数据的代码。

public static void main(String[] args) throws FileNotFoundException {
        Scanner scanner = new Scanner(new FileReader("C:\\Path\\boards.txt"));

        HashMap<String, String> map = new HashMap<String, String>();

        while (scanner.hasNextLine()) {
            String columns = scanner.nextLine();
            map.put(columns, columns);
        }

        System.out.println(map);
    }

现在我拥有它的主要原因是为了摆脱错误。以前我的代码是这样的:

public static void main(String[] args) throws FileNotFoundException {
        Scanner scanner = new Scanner(new FileReader("C:\\Path\\boards.txt"));

        HashMap<String, String> map = new HashMap<String, String>();

        while (scanner.hasNextLine()) {
            String[] columns = scanner.nextLine().split(" ");
            map.put(columns[0], columns[1]);
        }

        System.out.println(map);
    }

但是,我遇到了一个越​​界异常。由于事实上没有空格可以分割。

好的,所以我的主要问题是,如何将整个 .txt 文件保存到 HashMap 并一次只显示一行 100 个字符。

其次(较低优先级) - 我想随机选择一行,这样我就可以创建一个 1-10000 之间的随机数来显示一行。我曾想过使用 String、Integer HashMap 并以某种方式为每一行设置一个索引值,但我不知道该怎么做。

**编辑对不起,我忘了添加屏幕截图。这里是: 在此处输入图像描述

感谢您的回答,我现在将阅读它们

4

4 回答 4

2

直接回答您的问题:

1)你几乎有你的文件阅读器,但你不必费心Map,一个List就足够了。

Scanner scanner = new Scanner(new FileReader("C:\\Path\\boards.txt"));
List<String> lines = new ArrayList<String>();
while (scanner.hasNextLine()) {
    String columns = scanner.nextLine();
    lines.add(columns);
}

2)要抓取一条随机线,只需在List.

Random random = new Random();
int randomLineIndex = random.nextInt(lines.size());
String randomLine = lines.get(randomLineIndex);

现在,说了这么多,如果您不需要加载整个文件,请不要。如果您只需要从文件中随机获取一行,那么就直接使用它并节省自己的计算和内存。

为此,您首先需要知道文件中的行数。 这个问题给你:

String file = "C:\\Path\\boards.txt";
BufferedReader reader = new BufferedReader(new FileReader(file));
int lineCount = 0;
while (reader.readLine() != null) lineCount++;
reader.close();

现在您知道有多少行并且可以随机选择一个:

Random random = new Random();
int randomLineIndex = random.nextInt(lineCount);

然后你可以抓住那条线而忽略其余的:

reader = new BufferedReader(new FileReader(file));
int i = 0;
while (++i < randomLineIndex)
    // Skip all lines before the one we want
    reader.readLine();
String randomLine = reader.readLine();
于 2012-12-19T22:13:51.590 回答
2

我就是这样做的。您最多可以使用相同的种子重玩 2^48 种不同的游戏。这避免了读取文件或在内存中存储索引的需要。您可以根据需要重新创建任何棋盘游戏。

public class Baord {
    private static final int[] SHIP_SIZES = {4, 4, 3, 3, 3, 2, 2, 2, 2,  1, 1};
    public static final char EMPTY = '.';

    private final Random random;
    private final char[][] grid;
    private char letter = 'a';
    private final int width;
    private final int height;

    public Baord(int height,int width,  int seed) {
        this.width = width;
        this.height = height;
        this.random = new Random(seed);
        this.grid = new char[height][width];
        for (char[] chars : grid)
            Arrays.fill(chars, EMPTY);
        for (int len : SHIP_SIZES)
            placeShip(len);
    }

    private void placeShip(int len) {
        OUTER:
        while (true) {
            if (random.nextBoolean()) {
                // across
                int x = random.nextInt(width - len + 1);
                int y = random.nextInt(height);
                for (int j = Math.max(0, y - 1); j < Math.min(height, y + 2); j++)
                    for (int i = Math.max(0, x - 1); i < Math.min(width, x + len + 2); i++)
                        if (grid[j][i] > EMPTY)
                            continue OUTER;
                for (int i = 0; i < len; i++)
                    grid[y][x + i] = letter;

            } else {
                // down
                int y = random.nextInt(height - len + 1);
                int x = random.nextInt(width);
                for (int j = Math.max(0, x - 1); j < Math.min(width, x + 2); j++)
                    for (int i = Math.max(0, y - 1); i < Math.min(height, y + len + 2); i++)
                        if (grid[i][j] > EMPTY)
                            continue OUTER;
                for (int i = 0; i < len; i++)
                    grid[y + i][x] = letter;
            }
            break;
        }
        letter++;
    }

    public String toString() {
        StringBuilder ret = new StringBuilder();
        for (int y = 0; y < grid.length; y++)
            ret.append(new String(grid[y])).append("\n");
        return ret.toString();
    }

    public static void main(String... args) {
        for (int i = 0; i < 3; i++)
            System.out.println(new Baord(8, 16, i));
    }
}

印刷

..........ddd...
.....aaaa.......
eee.......j.....
.............i..
..bbbb.......i.c
.......g.......c
.k.h...g...f...c
...h.......f....

ii..............
.....ccc..ff...b
...............b
aaaa...........b
.........j..h..b
....gg......h...
..............k.
eee..ddd........

.d.....eee.....f
.d.............f
.d..............
......j.ccc....g
.............b.g
.............b..
h.i..........b..
h.i...aaaa.k.b..

.......h....aaaa
.......h........
.e.........ccc..
.e..............
.e.bbbb...ii..ff
........d.......
.g..j...d.......
.g......d.....k.

............ccc.
.....bbbb.......
.ii.......k..d..
.....f.......d..
eee..f.......d..
................
.j.g........hh..
...g.aaaa.......
于 2012-12-19T22:24:59.210 回答
0

为什么要使用键和值相同的 HashMap?您所描述的本质上只是一个数组,其中每个存储桶包含一行 100 个字符。拉出随机地图意味着创建一个介于 1-10000 之间的随机数并打印该存储桶的内容。

关于解析,我们需要从您的文件本身中查看一个示例,以帮助解决您遇到的任何语法问题。

于 2012-12-19T21:58:44.553 回答
0

仅供参考。

scanner.next().split(":");不在时为我工作 scanner.nextLine().split(":");

于 2013-04-30T15:23:19.547 回答