简体   繁体   English

高分二进制文件

[英]Highscore binary file

Hi!你好!

I would like to maintain a high score system with a maximum of 5 binary scores for my school project game.我想为我的学校项目游戏维护一个最多 5 个二进制分数的高分系统。 If the new value is higher than what is already in the file, I want to replace it with the new value.如果新值高于文件中已有的值,我想用新值替换它。

I've been at it for a long time, but I'm not really getting it out.我已经做了很长时间了,但我并没有真正把它弄出来。 It always adds new lines and my check that the value is already in the file does not work.它总是添加新行,并且我检查该值是否已在文件中不起作用。 I hope you can help me a step further.我希望你能帮助我更进一步。

thanks in advance提前致谢

Here's my code:这是我的代码:

private static final String HIGHSCORE_PATH = "highscore-" + LocalDate.now() + ".dat";
    private static final Path filePath = Paths.get(HIGHSCORE_PATH);
    private final ArrayList highscoreList = new ArrayList();
    private final ArrayList highscoreFileWaardes = new ArrayList();
    FileOutputStream fos = new FileOutputStream(HIGHSCORE_PATH, true);
    int numberRulesInUse = 0;
    int teller2 = 0;
    int teller3 = 0;

public void writeHighscore(int highscore) throws IOException {
        if (Files.exists(filePath)) {
            try (Scanner fileScanner = new Scanner(filePath)) {
                if (numberRulesInUse > 6) {
                    System.out.println("File is too long");
                    return;
                } else if (numberRulesInUse == 0) {
                    for (int i = 0; i < 5; i++) {
                        highscoreList.add(0);
                    }
                } else {
                    String highscoreBinair = fileScanner.nextLine();
                    highscoreList.set(teller2, (Integer.parseInt(highscoreBinair, 2)));
                    while (fileScanner.hasNext()) {
                        if (aantalRegelsInGebruik < 5) {
                            if (!highscoreList.get(teller3).equals(highscoreFileWaardes.get(teller3))) {
                                highscoreList.set(teller3, (Integer.parseInt(highscoreBinair, 2)));
                                teller3++;
                                numberRulesInUse++;
                            } else {
                                System.out.println("Already in file");
                                return;
                            }
                        } else {
                            System.out.println("FILE DOESN'T ALLOW MORE THAN 5 RULES");
                            return;
                        }
                    }
                }
            } catch (IOException ioException) {
                throw new IOException("Error while reading file");
            }
            
            if ((Integer) highscoreList.get(teller3) < highscore && (Integer) highscoreList.get(teller3) != highscore) {
                try {
                    highscoreList.set(teller3, Integer.parseInt(String.valueOf(highscore)));
                    fos.write(Integer.toBinaryString(Integer.parseInt(String.valueOf(highscoreList.get(teller3)))).getBytes());
                    fos.write("\n".getBytes());
                    teller3++;
                    numberRulesInUse++;
                } catch (IOException e) {
                    throw new IOException("Error while writing to file");
                }
            } else {
                System.out.println("No new highscore or highscore already exists");
            }
        }
        fos.flush();
        //fos.close();
    }

Let's take a step back and think about what you are trying to do, and if there is an easier way to do it all.让我们退后一步,想想你想要做什么,以及是否有更简单的方法来完成这一切。

  1. Load the scores from the file to a list,将文件中的分数加载到列表中,
  2. Add the new high score to the list if it is higher,如果更高,则将新的高分添加到列表中,
  3. Save the top 5 new high scores,保存前5名的新高分,
  4. Profit!利润!

We start by reading each line of the file to an array and parsing it to an Integer existingHighScores.add(Integer.parseInt(line, 2));我们首先将文件的每一行读取到一个数组并将其解析为 Integer existingHighScores.add(Integer.parseInt(line, 2));

The next step is to check if your score is higher or not, however, there is an far easier way to do this by simply adding the score to the end of the list existingHighScores.add(highscore);下一步是检查你的分数是否更高,但是,有一种更简单的方法可以做到这一点,只需将分数添加到列表的末尾即可existingHighScores.add(highscore); , and then we can sort the list in descending order Collections.sort(existingHighScores, Collections.reverseOrder()); ,然后我们可以对列表进行降序排序Collections.sort(existingHighScores, Collections.reverseOrder()); that single line of code will cut out all your loops and if/else checks and give you some great readable code.那一行代码将切断所有循环和 if/else 检查,并为您提供一些可读性强的代码。

Finally, because we have a nicely sorted list we can just save the first 5 items in the list which are the 5 top scores to file, and as mentioned earlier, because the code is sorted it will remove the need to compare and remove lower scores:最后,因为我们有一个很好排序的列表,我们可以只保存列表中的前 5 个项目,它们是 5 个最高分到文件中,并且如前所述,因为代码是排序的,它将消除比较和删除较低分数的需要:

    for (int i = 0; i < 5; i++)
    {
        out.write(Integer.toBinaryString(existingHighScores.get(i)).getBytes());
        out.write("\n".getBytes());
    }

Now if we put it all together a fully working example might look something like this:现在,如果我们把它们放在一起,一个完整的例子可能看起来像这样:

public void writeHighscore(int highscore) throws Exception {

    //File path
    Path file = Paths.get(HIGHSCORE_PATH);
    
    //Fill arraylist with 5 0's to avoid issues if the list loaded from file is corrupt, or shorter than 5
    ArrayList<Integer> existingHighScores = new ArrayList<>(Arrays.asList(0,0,0,0,0));
    
    //Load the exising high scores
    InputStream in = Files.newInputStream(file);
    BufferedReader reader = new BufferedReader(new InputStreamReader(in)));

    String line = null;
    while ((line = reader.readLine()) != null)
    {
        //load score, of if there is an error default to 0
        try{
            existingHighScores.add(Integer.parseInt(line, 2));
        }
        catch (Exception e){
           existingHighScores.add(0);
        }
    }

    //Remember to close the file, otherwise we cant save the new scores below
    reader.close();
    in.close();

    //Add the new high score to list
    existingHighScores.add(highscore);
    
    //Sort the scores
    Collections.sort(existingHighScores, Collections.reverseOrder());

    
    //Save the highscores to file
    OutputStream out = new BufferedOutputStream(Files.newOutputStream(file)));

    //Only write the first 5 scores
    for (int i = 0; i < 5; i++)
    {
        out.write(Integer.toBinaryString(existingHighScores.get(i)).getBytes());
        out.write("\n".getBytes());
    }
}

Now you can add your exception handling and error checking if(Files.exists(file)) etc, and you can play with the code to get the file format working exactly as you want, but the logic itself remains simple and unchanged.现在您可以添加异常处理和错误检查if(Files.exists(file))等,并且您可以使用代码来让文件格式完全按照您的意愿工作,但逻辑本身保持简单且不变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM