[英]Loading partial sudoku text file into 2D array
我在做数独游戏,打开保存的数独文件时遇到问题。 假设我正在做拼图,并且想稍后再讲,我将部分完成的拼图保存到一个文件中,该文件可以正常工作。 当我打开它时,它不起作用。
这是保存的代码(变量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());
}
}
});
这是开放的代码:
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网格(使用相应的数字填充网格)。
我遇到的错误是“行长度%d ...”错误或“无效令牌%s ...”错误。 当我从“打开”功能中选择文件时,它不会将任何内容加载回网格中。 那就是我迷路的地方。 如果拼图完成并保存,则可以将其打开,因为包含拼图的外部文本文件已满,并且文件中的每个元素(空格)中都有一个数字,因此对每个拼图进行迭代时数字,它找不到任何错误或缺少数字。 但是,如果保存了部分文件,则无法将其重新打开到网格中以再次开始播放...
您对(样本)行的表示是这样的:
1,2,,7,6,,,,5
但是,当你分割该行上,
你会得到:
[1,2,7,6,5]
显然这不是长度为9的数组,因此, if (splitLine.length != 9)
将返回false
。 您必须将一个非数字字符保存到文本文件中,以指示“空”空间,否则split函数将很少返回正确长度的行。 可以用一个81个字符,从0到9的数字和一个“空”字符的单个列表来代表整个Sodoku面板,不需要逗号或换行符。 这里的关键是,仍然需要使用空字符来维护数据结构的拓扑。
附带说明一下:
if (c < ROWS - 1) {
saveFile.write(",");
}
应该可能参考COLS
代替。
通过阅读您的代码,在我看来,令人讨厌的行是:
if (splitLine[c].length() != 1 || !(Character.isDigit(splitLine[c].charAt(0)))) {
throw new IllegalArgumentException(...
在函数openPuzzle中。 这是因为当保存部分完成的数独时,您的文件将看起来像“ 1,2,,3,,1,6,7,.....”。现在,读入时的空白单元格的字符串长度为0。因此splitLine [c] .length()!= 1将失败。 为了解决这个问题,我建议将代码更改为:
if (splitLine[c].length() > 0 || !(Character.isDigit(...
以便在加载零长度字符(未填充的空格)时接受该字符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.