0

所以我正在为一个班级制作一个基于文本的 rpg。目前,该功能适用​​于我目前想要的一个房间。但是我想要一种更有效的方法来做到这一点。我想在没有索引的情况下做到这一点。我想从 contains(3.a) 到 end.3 的位置打印文本文件中的元素列表。你们中的任何一个兽医可以帮助我吗?. 这是我第一次尝试这种类型的项目。我这么早问的原因是因为这是项目的介绍,学期末的最终项目将是一个已解析的 40 页文本文件。

文本文件

1.a

Outside building
-------
WEST       2
UP         2
NORTH      3
IN         3

end.1

2.a

End of road
You are at the end of a road at the top of a small hill.
You can see a small building in the valley to the east.
------
EAST      1
DOWN      2

end.2

3.a

Inside building
You are inside a building, a well house for a large spring
-------
SOUTH    1
OUT      1

end.3

编码

public static void main(String[] args)throws FileNotFoundException{ 
    
    
    int direction = 0;
    Scanner s = new Scanner(new File("C:\\Users\\Basil Sheppard\\eclipse-workspace\\software practice\\src\\software\\rooms.txt"));
    Scanner choice = new Scanner(System.in);
    ArrayList<String> listS = new ArrayList<String>();
    

    while ( s.hasNextLine()) 
        listS.add(s.nextLine());
    
    
    System.out.println("please enter 3 for testing");
    direction = choice.nextInt();

    switch (direction){

//tests for room 3  
    case 3: {
    boolean found = listS.contains("3.a");
    if(found) {
        for(int i = 22; i<27; i++) {
            System.out.println(listS.get(i));
        }
    }
                            
} 
4

4 回答 4

0

尝试这个。

try (Scanner s = new Scanner(new File("C:\\Users\\Basil Sheppard\\eclipse-workspace\\software practice\\src\\software\\rooms.txt"))) {
    Scanner choice = new Scanner(System.in);
    ArrayList<String> listS = new ArrayList<String>();

    while (s.hasNextLine())
        listS.add(s.nextLine());

     System.out.println("please enter 3 for testing");
    int direction = choice.nextInt();

    listS.stream()
        .dropWhile(x -> !x.equals(direction + ".a"))
        .takeWhile(x -> !x.equals("end." + direction))
        .forEach(System.out::println);
    System.out.println("end." + direction);
}

输出

3.a

Inside building
You are inside a building, a well house for a large spring
-------
SOUTH    1
OUT      1

end.3

请注意,.takeWhile(x -> !x.equals("end." + direction))丢弃end.3自身。

于 2020-08-19T21:22:08.467 回答
0

你的方法看起来完全错误。

我会做什么:

  1. 创建一个类 MapLocation,具有以下内容:
    1. 标题,字符串
    2. 说明,字符串[]
    3. 导航,MapNavi[]
  2. 创建另一个类 MapNavi,具有以下内容:
    1. MapLoc,整数
    2. 方向,字符串
  3. 读取整个文件并将其解析为 MapLocation[]
  4. 处理输入并遍历 MapLocation[]

该文件的结构似乎是:

(#.a

Title
Description Lines*
-------
MapNavi+

end.#)+

因此,您可以构建一个解析器来处理上述文件,这非常简单。您还可以使用纯正则表达式解析整个文件。

示例解析器:

try (BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(_FILE_NAME))))
{
    String line;
    int state = 0;
    MapLocation currSegment = null;
    while ((line = br.readLine()) != null)
    {
        switch (state)
        {
        case 0:
           if (line.endsWith(".a"))
           {
               String segId = line.substring(0, line.indexOf(".a"));
               currSegment = new MapLocation(Integer.parseInt(segId));
               state++;
           }
           break;
        case 1:
           if (line.length() != 0)
           {
               currSegment.setTitle(line);
               state++;
           }
        case 2:
           if ("-------".equals(line))
           {
               state++;
           } else if (line.length() > 0)
           {
               currSegment.addDescription(line);
           }
        case 3:
           if (line.equals("end." + currSegment.getSegId()))
           {
               mapLocations.put(currSegment.getSegId(), currSegment);
               currSegment = null;
               state = 0;
           } else if (line.length() > 0)
           {
               String[] nav = line.split("\t");
               Integer mapLoc = Integer.parseInt(nav[1]);
               currSegment.addNavi(mapLoc, nav[0]);
           }
        }
    }
}

一旦文件被解析到 mapLocations 容器中,您就可以处理输入了:

try (Scanner in = new Scanner(System.in))
{
    MapLocation currLoc = // startLocation;
    while (!quitSignal.equals(line = in.nextLine()))
    {
        int mapLoc = Integer.parseInt(line);
        if (currLoc.validateNav(mapLoc))
        {
            currLoc = mapLocations.get(mapLoc);
            System.out.println("You travel to " + currLoc.getTitle());
            System.out.println(currLoc.toString());
        }
        else
        {
            System.out.println("You cannot travel to location '" + line + "' from here.  Please re-select your destination.");
        }
    }
}
于 2020-08-19T21:23:16.507 回答
0

您应该考虑将路径存储为 xml 文件!Java 有一些很酷的阅读方式,它可以理解列表中的元素。您甚至可以写入 xml 以更轻松地构建您的游戏。查看如何在 xml 中读取:https ://stackoverflow.com/a/428091/9789673

于 2020-08-19T20:57:56.130 回答
-1

我认为您需要考虑两个主要问题:

  • 结构化您的文件,使其行具有易于解析的相当一致的结构。
  • 想想如何组织代码,以便只扫描文件一次,创建类以在第一次阅读文件时以有组织的方式将数据存储在内存中。(是的,从某种意义上说,这是一个“索引”,但你不能同时拥有它:要么在第一次扫描文件时存储/索引文件中的信息,要么将信息丢弃并不得不扫描在下一个查询中再次通过它,这本质上是低效的。)

例如,您可能会像这样构建文件:

BEGIN:LOCATION:1
BEGIN:DESCRIPTION:
A house.
END:DESCRIPTION
BEGIN:DIRECTIONS
NORTH:3
SOUTH:4
END:DIRECTIONS
END:LOCATION

换句话说,这些行通常由 'command':'subcommand' 组成,并且在文件中给定一行,将其拆分为它的组件相当容易(查看 String.indexOf()、String.substring()。如果可以,请查看正则表达式 API:查看 Pattern 和 Matcher 类。(理论上,当您尝试同时扫描同一行/文本以查找多个不同的模式/子字符串时,这可以带来一些效率,并且是如果您正在扫描大量文本以查找更复杂的模式/命令,您通常会使用的方法。为了您的目的,您也可以使用简单的字符串方法——indexOf()、substring() 等——如果你发现这些更容易掌握。)

其他人提到了 XML:这是一种您也可以考虑的结构化格式,并且具有内置于 Java 平台中的标准解析例程的优势。但是,您设计的格式的普通旧文本文件本质上没有任何问题,只要它是一致的并且很容易编写一个例程来解析它......

于 2020-08-19T22:22:58.310 回答