将部分数独文本文件加载到2D数组中

时间:2015-12-08 18:46:20

标签: java arrays actionlistener

我正在制作一个数独游戏,但我遇到了打开已保存的Sudoku文件的问题。让我们说我正在做这个谜题,并希望稍后再回过头来,我将部分完成的谜题保存到文件中,该文件有效。当我打开它时,它不起作用。

这是保存的代码(变量ROWS和COLUMNS都等于9):

private void savePuzzle() throws IOException {

    JFileChooser fileChooser = new JFileChooser();
    int returnVal = fileChooser.showDialog(this, "Save");

    BufferedWriter saveFile = null;
    File file;

    // If the user has canceled, no need to continue
    if (returnVal != JFileChooser.APPROVE_OPTION) {
        return;
    }

    file = fileChooser.getSelectedFile();

    saveFile = new BufferedWriter(new FileWriter(file));
    for (int r = 0; r < ROWS; r++) {
        for (int c = 0; c < COLUMNS; c++) {
            saveFile.write(inputBoxes[r][c].getText());
            if (c < ROWS - 1) {
                saveFile.write(",");
            }
        }
        saveFile.write("\n");
    }
    saveFile.close();
}

以下是保存的操作按钮:

saveAction.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent evt) {
            try {
                // call method to save puzzle by writing its contents to an external save file
                savePuzzle();
            } catch (IOException ex) {
                System.out.println(ex.toString());
            }
        }
    }); 

以下是open的代码:

private void openPuzzle() throws FileNotFoundException, IllegalArgumentException {

    JFileChooser fileChooser = new JFileChooser();
    int returnVal = fileChooser.showDialog(this, "Open");

    File file = fileChooser.getSelectedFile();
    Scanner readFile = new Scanner(file);

    // If the user has canceled, no need to continue with open process
    if (returnVal != JFileChooser.APPROVE_OPTION) {
        return;
    }

    // Row
    int r = 0;

    // Update squares with data from file
    while (readFile.hasNextLine()) {
        String[] splitLine = readFile.nextLine().split(",");

        // Verify the length of the row
        if (splitLine.length != 9) {
            throw new IllegalArgumentException(String.format("Row length(%d) not correct in %s at row %d",
                    splitLine.length, file, r));
        }

        for (int c = 0; c < 9; c++) {
            // Verify each item in row
            if (splitLine[c].length() != 1 || !(Character.isDigit(splitLine[c].charAt(0)))) {
                throw new IllegalArgumentException(String.format("Invalid token %s in %s at row %d col %d",
                        splitLine[c], file, r, c));
            }
            // Update square
            inputBoxes[r][c].setText(splitLine[c]);
        }
        // Move to next row
        r++;
    }
}

打开操作按钮:

openAction.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent evt) {
            try {
                // call method so that user can open their saved puzzle and populate the grid with its contents
                openPuzzle();
            } catch (FileNotFoundException ex) {
                System.out.println(ex.toString());
            } catch (IllegalArgumentException ex) {
                System.out.println(ex.toString());
            }
        }
    });

我知道开放代码在保存的文本文件中找到空值,如果它是一个部分完成的谜题,并且它正在返回那些catch语句,但我不知道如何让它继续阅读每个元素该行(无论是数字还是空格),只需将文本文件中的内容返回到GUI网格(使用相应的数字填充网格)。

我得到的错误是&#34;行长度%d ...&#34;错误或&#34;无效的标记%s ...&#34;错误。当我从Open函数中选择文件时,它不会将任何内容加载回网格。这就是我失去的地方。如果拼图完成并保存,那么它可以打开,因为包含拼图的外部文本文件已满,文件中的每个元素(空格)都有一个数字,因此当它遍历每个拼图时数字,它没有发现任何错误或缺少数字。但是当保存部分文件时,无法将其打开回网格以再次开始播放...

2 个答案:

答案 0 :(得分:1)

Your representation of a (sample) row is this:

ConnectionString2

But when you split that line on 1,2,,7,6,,,,5 , you will get:

,

This is clearly not an array of length 9, so [1,2,7,6,5] will return if (splitLine.length != 9). You must save a non-digit character to the text file that indicates an 'empty' space, or the split function will very rarely return a row of the correct length. It is possible to represent an entire Sodoku board with a single list of 81 characters, the digits 0 through 9 and an 'empty' character, no commas or line breaks needed. The key here is that the empty character is still required to maintain the topology of your data structure.

As a side note this:

false

Should probable reference if (c < ROWS - 1) { saveFile.write(","); } instead.

答案 1 :(得分:0)

通过阅读您的代码,在我看来,违规行是:

if (splitLine[c].length() != 1 || !(Character.isDigit(splitLine[c].charAt(0)))) {
            throw new IllegalArgumentException(...

在openPuzzle函数中。这是因为在保存部分完成的数据时,您的文件将显示为&#34; 1,2,,3,1,6,7,......&#34;现在读入时的空单元格的字符串长度为0.因此splitLine [c] .length()!= 1将失败。要解决这个问题,我建议将代码更改为:

if (splitLine[c].length() > 0 || !(Character.isDigit(...

在加载时,接受零长度字符(未填充空格)。