数独拼图检查未通过

时间:2015-12-07 01:48:12

标签: java arrays

所以我制作了一个数独谜题应用程序,它有一个问题。

除了实际检查每行和每列的总和之外,一切正常。

现在,带有谜题编号的外部文件被读入并随机填充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

同样,我知道很多,所以如果有人愿意提供帮助,那绝对是惊人的!!!再次感谢...

0 个答案:

没有答案