所以我制作了一个数独谜题应用程序,它有一个问题。
除了实际检查每行和每列的总和之外,一切正常。
现在,带有谜题编号的外部文件被读入并随机填充9x9网格,留下随机网格。在用户完成拼图后,他们在“文件”菜单中单击“提交”,拼图将被写入输出文件,然后该输出文件应该将解决方案与读入的原始文件进行比较,以确保正确性,然后显示"恭喜"消息或者说抱歉没有去"消息。
现在,当用户在完成拼图后点击提交时,它总是显示"抱歉没有去"消息,即使拼图是正确的。不知道为什么它没有正确检查并显示正确的信息。
我会发布逻辑的整个代码,希望有人可以提供帮助。这里有相当数量的代码,所以如果您愿意花时间来查看它,我会非常感激。在此先感谢!!
以下是制作GUI和文件菜单的代码以及所有......
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
public class SudokuGUI extends JFrame {
// set unchangeable number of rows to 9
private static final int ROWS = 9;
// set unchangeable number of columns to 9
private static final int COLUMNS = 9;
private static int[][] array;
private static int[][] sudoku;
// put JTextField boxes into multi-dimensional array to create a 9x9 grid to hold Sudoku number values
private static JTextField[][] inputBoxes = new JTextField[9][9];
// declare font size
int fontSize = 30;
/**
* This constructor method creates a 9x9 grid (to house a Sudoku puzzle), and creates a file menu and a tools menu.
* The grid will be separated into 9 sets of 3x3 colored blocks.
* The file menu will have options to submit the puzzle, save the puzzle, open a puzzle, solve a puzzle, and exit.
* The tools menu will have the options to launch a set of simple game instructions, as well as a clock timer.
*/
public SudokuGUI () {
// create main frame
JFrame frame = new JFrame("Sudoku Puzzle");
// create a new font to set font type, font weight, and font size
Font font = new Font("Helvetica", Font.BOLD, fontSize);;
// set the frame size
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);;
// ********************************************* MENU BAR ****************************************************\\
// create new menu bar
JMenuBar menuBar = new JMenuBar();;
// create a "File" dropdown
JMenu fileMenu = new JMenu("File");
// add "File" menu to menu bar
menuBar.add(fileMenu);
// create a "Tools" dropdown
JMenu toolsMenu = new JMenu("Tools");
// add "Tools" menu to menu bar
menuBar.add(toolsMenu);
// create menu items for the "File" menu drop down
JMenuItem submitAction = new JMenuItem("Submit");
JMenuItem solveAction = new JMenuItem("Solve");
JMenuItem saveAction = new JMenuItem("Save");
JMenuItem openAction = new JMenuItem("Open");
JMenuItem exitAction = new JMenuItem("Exit");
// create menu items for the "Tools" menu drop down
JMenuItem openInstructions = new JMenuItem("Instructions");
JMenuItem openTimer = new JMenuItem("Launch Timer");
// add menu items to the "File" menu
fileMenu.add(submitAction);
fileMenu.add(solveAction);
fileMenu.add(saveAction);
fileMenu.add(openAction);
fileMenu.add(exitAction);
// add menu items to the "Tools" menu
toolsMenu.add(openInstructions);
toolsMenu.add(openTimer);
// add menu bar to the frame
frame.setJMenuBar(menuBar);
// make menu bar visible
frame.setVisible(true);
// ******************************************* END MENU BAR **************************************************\\
// *********************************************** GRID ******************************************************\\
// creates new panel that holds the Sudoku puzzle
JPanel puzzleBoard = new JPanel();
puzzleBoard.setLayout(new GridLayout (ROWS, COLUMNS));
// outer loop to create rows
for (int rows = 0; rows < ROWS; rows++) {
// inner loop to create columns
for (int columns = 0; columns < COLUMNS; columns++) {
// make editable squares in the grid
inputBoxes[rows][columns] = new JTextField();
// set text in input boxes to number values
inputBoxes[rows][columns].setText("" + sudoku[rows][columns]);
// center the numbers in each corresponding text box
inputBoxes[rows][columns].setHorizontalAlignment(JTextField.CENTER);
// set font for puzzle cells
inputBoxes[rows][columns].setFont(font);
if (sudoku[rows][columns] != 0) {
// if a cell contains a pre-populated number, do not let user edit that cell
inputBoxes[rows][columns].setEditable(false);
}
// instead of having an editable cell with a "0" in it, make that cell empty, for a more natural appeal
if (sudoku[rows][columns] == 0) {
// replace cells with a 0 in them with an empty string
inputBoxes[rows][columns].setText("");
}
// add created rows and columns to the main panel that holds the puzzle grid
puzzleBoard.add(inputBoxes[rows][columns]);
frame.getContentPane().add(puzzleBoard);
// set each 3 x 3 block to a different color for separation
if (rows < 3 && columns < 3) { // top left
// set to HTML color light red
inputBoxes[rows][columns].setBackground(Color.decode("#ff8484"));
} else if (rows < 3 && columns < 6) { // top middle
// set to HTML color light blue
inputBoxes[rows][columns].setBackground(Color.decode("#c1c1ff"));
} else if (rows < 3 && columns < 9) { // top right
// set to HTML color light red
inputBoxes[rows][columns].setBackground(Color.decode("#ff8484"));
} else if (rows < 6 && columns < 3) { // middle left
// set to HTML color light blue
inputBoxes[rows][columns].setBackground(Color.decode("#c1c1ff"));
} else if (rows < 6 && columns < 6) { // middle
// set to HTML color light red
inputBoxes[rows][columns].setBackground(Color.decode("#ff8484"));
} else if (rows < 6 && columns < 9) { // middle right
// set to HTML color light blue
inputBoxes[rows][columns].setBackground(Color.decode("#c1c1ff"));
} else if (rows < 9 && columns < 3) { // bottom left
// set to HTML color light red
inputBoxes[rows][columns].setBackground(Color.decode("#ff8484"));
} else if (rows < 9 && columns < 6) { // bottom middle
// set to HTML color light blue
inputBoxes[rows][columns].setBackground(Color.decode("#c1c1ff"));
} else if (rows < 9 && columns < 9) { // bottom right
// set to HTML color light red
inputBoxes[rows][columns].setBackground(Color.decode("#ff8484"));
}
} // end columns loop
} // end rows loop
// ********************************************* END GRID ****************************************************\\
// press the "Submit" menu item
submitAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// pass the submit() method into an array that holds the user submission;
int[][] userSubmission = submit();
// write the user submission array to an external file
writeToFile(userSubmission);
// if user submission correctly matches the puzzle solution
if (testSudoku()) {
// display a congratulatory message to the user the puzzle was solved correctly
JOptionPane.showMessageDialog(null, "CONGRATULATIONS!!"
+ "\nYou have solved the Sudoku puzzle!");
} else {
// otherwise display a message stating the user did not correctly solve the puzzle
JOptionPane.showMessageDialog(null, "Sorry, but you did not correctly solve the puzzle"
+ "\nKeep on trying, you'll get there...");
}
}
});
// press the "Exit" menu item
exitAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// exit the window
System.exit(0);
}
});
// launch the clock timer
openTimer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// make new instance of SudokuTimer
SudokuTimer runTimer = new SudokuTimer();
// run the timer
runTimer.launchTimer();
}
});
// launch simple game instructions for the user
openInstructions.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
JOptionPane.showMessageDialog(null, "A random Sudoku Puzzle has been generated."
+ "\nFill each empty square with a number from 1 to 9."
+ "\nEach 3x3 colored block must sum to 45, and not repeat numbers"
+ "\nEach full row across must sum to 45, and not repeat numbers"
+ "\nEach full column up & down must sum to 45, and not repeat numbers");
}
});
// add Sudoku puzzle board to the main frame
frame.getContentPane().add(puzzleBoard);
// make the frame visible
frame.setVisible(true);
} // end SudokuGUI constructor
/**
* This method returns a method which checks the Sudoku puzzle.
* @return will return the method to check the Sudoku puzzle for correct completion or failing.
*/
public boolean testSudoku() {
// returns the mainTest method from the SudokuChecker file to test if a puzzle has passed
return SudokuChecker.sudokuTest(null);
}
/**
* This method is used for user submission of a completed Sudoku puzzle.
* @return will return the correct solution of a puzzle.
*/
public static int[][] submit(){
int[][]result = new int[9][9];
for (int rows = 0; rows < 9; rows++) {
for (int columns = 0; columns < 9; columns++) {
try {
result[rows][columns] = Integer.parseInt(inputBoxes[rows][columns].getText());
} catch (Exception ex) {
result[rows][columns] = -1;
}
}
}
return result;
}
/**
* This method reads in an external file and uses it to populate a Sudoku grid to make a puzzle game to play
* @return will return the puzzle that is to be generated for the user to attempt
*/
public static int[][] readFromFile(){
int[][] array = new int[9][9];
int counter = 0;
try {
// use buffered reader object to read in external input file
BufferedReader inputFile = new BufferedReader(new FileReader("puzzle.txt"));
String lineInFile;
// loop as long as the input file has a line to read
while ((lineInFile = inputFile.readLine())!= null) {
String[] numValues = lineInFile.split(",");
for (int y = 0; y < 9; y++) {
array[counter][y] = Integer.parseInt(numValues[y]);
}
counter++;
}
inputFile.close();
} catch (IOException ex) {
System.out.println("ERROR");
}
return array;
}
/**
* This method writes the completed puzzle to an external file.
* @param array this is the completed puzzle that will be written to an external file.
*/
public static void writeToFile(int[][] array){
try {
PrintWriter addToFile = new PrintWriter(new FileWriter("output.txt"));
for (int rows = 0; rows < 9; rows++) {
String writeNumbers = "";
for (int columns = 0; columns < 9; columns++) {
writeNumbers += array[rows][columns] + " ";
}
// remove the last comma that prints after the last number in each row of the output file
//writeNumbers = writeNumbers.substring(0, (writeNumbers.length() - 1));
addToFile.println(writeNumbers);
}
addToFile.close();
} catch (IOException ex) {
System.out.println("The following error occurred " + ex);
}
}
/**
* This method generates random numbers from 1 to 9 to be used in a Sudoku puzzle
* @return this will return an array of random generated numbers
*/
public static int[][] numberGenerator(){
int[][] anArray = new int[9][9];
for (int rows = 0; rows < 9; rows++) {
for (int columns = 0; columns < 9; columns++) {
anArray[rows][columns] = array[rows][columns];
}
}
int num = 41;
while (num > 0) {
int x = (int)(Math.random() * 9);
int y = (int)(Math.random() * 9);
if (anArray[x][y] != 0) {
anArray[x][y] = 0;
num--;
}
}
return anArray;
}
/**
* This is the main method that completes all the logic
* @param args the command line arguments
*/
public static void main(String[] args) {
//SudokuGenerator.main(null);
array = readFromFile();
sudoku = numberGenerator();
// print the puzzle with the correct solution to the console
for (int rows = 0; rows < 9; rows++) {
for (int columns = 0; columns < 9; columns++) {
System.out.print(array[rows][columns] + " ");
}
System.out.println();
}
new SudokuGUI();
}
} // end class SudokuGUI
然后这是应该进行所有检查/测试的代码......
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class SudokuChecker {
private static int[] anArray = new int[9];
// array to hold the completed sudoku puzzle
private static int[][] sudoku = new int[9][9];
/**
* This method will check the rows of a 9x9 grid for any duplicate numbers.
* @param array the 9x9 array (grid) of which the rows will be checked for duplicate numbers.
* @return will return a positive number if the check passes and there are no duplicates.
*/
private static int checkRows (int[][] array) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++)
anArray[j] = array[i][j];
if (checkPuzzle(anArray) == 0) {
return 0;
}
}
return 1;
}
/**
* This method is the main checker for the entire puzzle. Checks to make sure there are no repeating numbers, and
* that everything is summed up according to the Sudoku rules.
* @param array the array that will be checked for correctness.
* @return will return a positive value if everything passes.
*/
private static int checkPuzzle (int[] array) {
int x;
for (int i = 0; i < 9; i++) {
x = array[i];
// searches for any duplicate numbers
for (int j = i + 1; j < 9; j++) {
if (array[j] == x) {
return 0;
}
}
}
return 1;
}
/**
* This method will check the columns of a 9x9 grid for any duplicate numbers.
* @param array the 9x9 array (grid) of which the columns will be checked for duplicate numbers.
* @return will return a positive number if the check passes and there are no duplicates.
*/
private static int checkColumns (int[][] array) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++)
anArray[j] = array[j][i];
if (checkPuzzle(anArray) == 0) {
return 0;
}
}
return 1;
}
/**
* This method will check both the rows and columns of a 9x9 grid for any duplicate numbers.
* @param array the 9x9 array (grid) of which the rows and columns will be checked for duplicate numbers.
* @return will return a positive number if the check passes and there are no duplicates in either rows or columns.
*/
private static int checkInputBoxes (int[][] array) {
//column and row loops set the starting index for each sub-square.
int i,
j,
column,
row,
k;
for (column = 0; column <= 6; column += 3) {
for (row = 0; row <= 6; row += 3) {
for (k = 0, i = 0; i < 3; i++) {
for (j = 0; j < 3; j++)
anArray[k++] = array[row + i][column + j];
}
if (checkPuzzle(anArray) == 0) {
return 0;
}
}
}
return 1;
}
/**
* This method reads in an external text file.
* The file that is being read in the output file generated from SudokuGUI which contains a completed Sudoku puzzle.
* This method can be passed into another method to check that the completed Sudoku puzzle is correct and passes.
*/
public static int[][] readFromFile() {
int[][] array = new int[9][9];
int x = 0;
try {
// use buffered reader object to read in external input file
BufferedReader inputFile = new BufferedReader(new FileReader("output.txt"));
String lineInFile;
// loop as long as the input file has a line to read
while ((lineInFile = inputFile.readLine()) != null) {
String[] numValues = lineInFile.split(" ");
for (int y = 0; y < 9; y++)
array[x][y] = Integer.parseInt(numValues[y]);
x++;
}
inputFile.close();
} catch (IOException ex) {
System.out.println("ERROR");
}
return array;
}
/**
* This method takes in an external file that contains a user completed Sudoku puzzle, and checks to see if the
* puzzle contains the correct solution, and passes all the rules of rows and columns summing to 45, respectively,
* and not repeating any numbers. Each 3x3 colored block must also sum to 45, and not contain repeating numbers.
* @param array the array that contains the user completed Sudoku puzzle.
* @return will return a passed puzzle or a failed puzzle.
*/
public static boolean sudokuTest(String[] array) {
sudoku = readFromFile();
// the puzzle has passed
if ((checkRows(sudoku) == 0) || (checkColumns(sudoku) == 0) || (checkInputBoxes(sudoku) == 0)) {
return false;
}
// the puzzle has failed
return true;
}
} // end class SudokuChecker
同样,我知道很多,所以如果有人愿意提供帮助,那绝对是惊人的!!!再次感谢...