如何将输入文本文件转换为单个变量? Java的

时间:2016-09-24 20:05:52

标签: java

我需要一个小型火星着陆器视频游戏的帮助,我正在为我的计算机科学课程做准备。我们必须使用扫描仪阅读游戏配置文本文件,并将其用作游戏不同方面的规则(重力,你拥有的燃料量等)。她给了我们不同的文本文件,它们都有不同的困难和价值观,但它们都具有相同的格式,因此我需要能够简单地调用不同的文本文件并准备好一个新的级别。我的问题是:

如何将文件中的输入转换为单独的变量,以便我可以操作它们来创建游戏?

这里是用于读取文本文件的代码,它还将其打印到控制台

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class MarsLander {
public static void main(String [] args) {
        try {
            Scanner sc = new Scanner(new File("gameConfig.txt"));
            while (sc.hasNext()){
                String s = sc.next();
                System.out.println(s);
            }
            sc.close();
        }
        catch (FileNotFoundException e) {
            System.out.println("Failed to open file!");
        }
    }
}

以下是其中一个文字游戏配置文件:

1000 500
mars_sky.jpg
ship.png ship_bottom.png ship_left.png ship_right.png ship_landed.png ship_crashed.png
20 50
500.0 400.0
100
thrust.wav yay.wav explosion.wav
-0.1
2.0
0.5
500 50

1 个答案:

答案 0 :(得分:0)

在我的解决方案中,我正在思考一些更通用的东西。让我先向您展示我编写的代码。然后我会解释它的行为和特殊性。

public class GameExample {

    private static class Game {
        private Long x, y;

        private List<String> images = new ArrayList<>();

        private Game(final Long x, final Long y, final List<String> images) {
            this.x = x;
            this.y = y;

            this.images = images;
        }

        public Long getX() {
            return x;
        }

        public Long getY() {
            return y;
        }

        public List<String> getImages() {
            return images;
        }

        public static class Builder {
            // Parsing methods used by the builder to read the files and build the configuration
            // TODO: add here builder methods for each line of the file
            private final List<BiFunction<String, Game.Builder, Game.Builder>> parsingMethods = Arrays.asList(
                (str, builder) -> builder.withPositions(str),
                (str, builder) -> builder.withImages(str));

            private Long x, y;

            private List<String> images = new ArrayList<>();

            private Builder withPositions(final String str) {
                String[] positions = str.split(" ");
                x = Long.valueOf(positions[0]);
                y = Long.valueOf(positions[1]);

                return this;
            }

            private Builder withImages(final String str) {
                Stream.of(str.split(" ")).forEach(imgStr -> images.add(imgStr));

                return this;
            }

            public Game build(final String filename) throws IOException {
                Scanner sc = null;
                try {
                    // Read the file line by line
                    List<String> lines = Files.lines(Paths.get(filename)).collect(Collectors.toList());

                    // Iterate over each line and call the configured method
                    IntStream.range(0, lines.size()).forEach(
                        index -> parsingMethods.get(index)
                                .apply(lines.get(index), this));

                    // Build an instance of the game
                    return new Game(x, y, images);
                } catch (IOException e) {
                    e.printStackTrace();
                    throw e;
                } finally {
                    if (sc != null) sc.close();
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        final Game.Builder builder = new Game.Builder();
        Game game = builder.build("file.txt");

        System.out.println(game.getX() + ":" + game.getY());
        System.out.println(game.getImages());
    }
}

这段代码会输出:

<强> 10:15

<强> test.jpg放在

使用给定的配置文件:

10 15

<强> test.jpg放在

让我解释一下做了什么。我们定义了一个Game构建器,它只有一个带有签名Game build(final String filename)的公共方法。它需要文件名,并将根据此文件的内容构建游戏。这种方法的基础是构建器定义了一个列表,用于确定构建器的哪个方法用于文件的每一行:

private final List<BiFunction<String, Game.Builder, Game.Builder>> parsingMethods = Arrays.asList(
            (str, builder) -> builder.withPositions(str),
            (str, builder) -> builder.withImages(str));

此列表显示:

  1. 将方法withPositions用于第一行
  2. 将方法withImages用于第二行
  3. 现在,在build方法中,它实现了在行上执行方法的逻辑:

    // Iterate over each line and call the configured method
    IntStream.range(0, lines.size()).forEach(
        index -> parsingMethods.get(index)
            .apply(lines.get(index), this));
    

    因此,我们可以通过执行以下操作轻松解析新的数据行:

    1. 在构建器中添加一个新的私有方法,描述如何解析该行;

    2. 在名为parsingMethods的列表中添加此方法。