• 高级软件工程第三次作业:数独游戏界面功能


    一、题目要求完成数独游戏界面功能,代码已实现以下题目要求:

    1. 生成任意数量的数独题目并将数独棋局依次显示,棋盘上总空格数大于30,小于60,每3*3小棋盘中挖空不少于2个。
    2. 数独题目有且仅有唯一解。
    3. 用户可以在界面上通过编辑输入完成数独题目。
    4. 用户完成数独题目后可以得到正确性反馈。
    5. 友好的使用说明
    package shudu;
    
    import javax.swing.*;
    
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import java.util.Random;
    
    public class ShuD extends JFrame 
    {
        private static final long serialVersionUID = 5952689219411916553L; //序列化字段
        private static JTextField a[][] = new JTextField[9][9];  //存储文本框中的数字
        static int ans[][] = new int[9][9];  //存储输入后的两位数组
        SudokuPuzzleGenerator example = new SudokuPuzzleGenerator();
        public int right[][] = example.generatePuzzleMatrix();
        public int rightans[][];
    
        //清空数组
        private int[][] clear(int a[][]) 
        {
            int[][] temp = new int[9][9];
            for (int i = 0; i < 9; i++) 
            {
                for (int j = 0; j < 9; j++) 
                {
                    temp[i][j]=a[i][j];
                }
            }
            Random r = new Random();
            int a1, a2;
            for (int i = 0; i < 100; i++) 
            {
                a1 = r.nextInt(9);
                a2 = r.nextInt(9);
                temp[a1][a2] = 0;
            }
            return temp;
        }
        public ShuD() {
            try {
                File file = new File("sudotiku.txt");
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                PrintStream printStream = new PrintStream(fileOutputStream);
                Container c = getContentPane();
                c.setLayout(new BorderLayout(2, 1));  //边框布局
                JMenuItem jmiOk = new JMenuItem("提交");  //定义菜单
                JMenuItem jmiC = new JMenuItem("答案");
                JMenuItem jmiN = new JMenuItem("下一局");
                JPanel panel = new JPanel();  //定义一个容器
                panel.add(jmiOk);     //将菜单在容器内显示
                panel.add(jmiC);
                panel.add(jmiN);
                JPanel p1 = new JPanel(new GridLayout(9, 9, 5, 5));  //定义9行9列的网格布局
                add(panel, BorderLayout.NORTH);   //将菜单放置在北面
                add(p1, BorderLayout.CENTER);   //将数字放置在正中间
                rightans = clear(right);
    
                for (int k = 0; k < 9; k++) 
                {
                    for (int n = 0; n < 9; n++) 
                    {
                        int ccc = rightans[k][n];
                        if (rightans[k][n] != 0) 
                        {
                            a[k][n] = new JTextField("" + rightans[k][n]);
                            a[k][n].setHorizontalAlignment(JTextField.CENTER);//将数字水平居中
                            a[k][n].setEditable(false);   //只可显示不可修改
                            p1.add(a[k][n]);     //添加文本框
                            printStream.print(ccc + "	");
                        } else {
                            a[k][n] = new JTextField();
                            a[k][n].setHorizontalAlignment(JTextField.CENTER);
                            p1.add(a[k][n]);
                            printStream.print("");
                        }
                    }
                    printStream.println();
                }
                printStream.close();
                add(p1);   //将数字面板显示在容器里}
    
                jmiOk.addActionListener(new ActionListener() 
                {//匿名创建事件监听器
                    public void actionPerformed(ActionEvent e) 
                    {
                        if (gettext() == 1) 
                        {
                            if (judge() == true) 
                            {
                                JOptionPane.showMessageDialog(null, "Your answer is right!", "Result", JOptionPane.INFORMATION_MESSAGE);
                            } 
                            else 
                            {
                                JOptionPane.showMessageDialog(null, "Your answer is wrong!", "Result", JOptionPane.INFORMATION_MESSAGE);
                            }
                        }
    
                    }
    
                });
                jmiC.addActionListener(new ActionListener() 
                {
                    @Override
                    public void actionPerformed(ActionEvent e) 
                    {
                        for (int k = 0; k < 9; k++) 
                        {
                            for (int n = 0; n < 9; n++) 
                            {
                                a[k][n].setText(String.valueOf(right[k][n]));
                            }
                        }
    
    
                    }
                });
    
                jmiN.addActionListener(new ActionListener() 
                {
                    @Override
                    public void actionPerformed(ActionEvent e) 
                    {
    
    
                        right = example.generatePuzzleMatrix();
                        rightans = clear(right);
    
                        for (int k = 0; k < 9; k++) 
                        {
                            for (int n = 0; n < 9; n++) 
                            {
                                int ccc = rightans[k][n];
                                if (rightans[k][n] != 0) 
                                {
                                    a[k][n].setEditable(true);
                                    a[k][n].setText(String.valueOf(rightans[k][n]));
                                    a[k][n].setHorizontalAlignment(JTextField.CENTER);//将数字水平居中
                                    a[k][n].setEditable(false);   //只可显示不可修改
                                    //p1.add(a[k][n]);     //添加文本框
                                    printStream.print(ccc + "	");
                                } else {
                                    a[k][n].setEditable(true);
                                    a[k][n].setText("");
                                    a[k][n].setHorizontalAlignment(JTextField.CENTER);
                                    //p1.add(a[k][n]);
                                    printStream.print("");
                                }
                            }
                            printStream.println();
                        }
                        printStream.close();
                        add(p1);   //将数字面板显示在容器里}
                    }
                });
    
    
            } catch (IOException e) 
            {
    
            }
        }
        //获取文本框的文字
        public int gettext() 
        {
            int i, j;
            for (i = 0; i < 9; i++) 
            {
                for (j = 0; j < 9; j++) 
                {
                    ans[i][j] = 0;
                }
            }
            for (int k = 0; k < 9; k++) 
            {
                for (int n = 0; n < 9; n++) 
                {
                    //异常处理
                    try {
                        //将答案类型转换之后传给ans
                        ans[k][n] = Integer.parseInt(a[k][n].getText());
                        int num = ans[k][n];
                    } catch (NumberFormatException nfe) 
                    {
                        JOptionPane.showMessageDialog(null, " 输入不符合要求,重新输入");
                        return 0;
                    }
                }
            }
            return 1;
        }
        //判断输入的答案是否正确
        public static boolean judge() 
        {
            int i, j, k;
            int[][] answer = ans;
            for (i = 0; i < 9; i++) 
            {
                //判断每列是否有重复数字
                if (judge9(answer[i]) == false)
                    return false;
            }
            //判断每行是否有重复数字
            for (j = 0; j < 9; j++) 
            {
                int[] newAnswerColumn = new int[9];
                for (i = 0; i < 9; i++) 
                {
                    newAnswerColumn[i] = answer[i][j];
                }
                if (judge9(newAnswerColumn) == false)
                    return false;
            }
            //判断每个小九宫格内是否有重复数字
            for (i = 0; i < 3; i++) 
            {
                for (j = 0; j < 3; j++) 
                {
                    k = 0;
                    int[] newAnswer = new int[9];
                    for (int m = i * 3; m < i * 3 + 3; m++) 
                    {
                        for (int n = j * 3; n < j * 3 + 3; n++) 
                        {
                            newAnswer[k] = answer[m][n];
                            k++;
                        }
                    }
                    if (judge9(newAnswer) == false) 
                    {
                        return false;
                    }
                }
            }
            return true;
        }
        public static boolean judge9(int[] answer) 
        {
            int i, j;
            for (i = 0; i < 9; i++) 
            {
                for (j = 0; j < 9; j++)
                {
                    if (i == j)
                        continue;
                    //如果有重复的数字,返回false
                    if (answer[i] == answer[j]) 
                    {
                        return false;
                    }
                }
            }
            //没有重复数字,返回true
            return true;
        }
    
        public static void main(String[] args) 
        {
            JFrame frame = new ShuD();
            frame.setTitle("SuDoku");
            frame.setSize(400, 500);
            frame.setLocationRelativeTo(null);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    }
    package shudu;
    
    import java.util.Random;
    
    public class SudokuPuzzleGenerator 
    {
        private Random random = new Random();
        private static final int MAX_CALL_RANDOM_ARRAY_TIMES = 220;
        private int currentTimes = 0;
        public int[][] generatePuzzleMatrix() 
        {
            int[][] randomMatrix = new int[9][9];
            for (int row = 0; row < 9; row++) 
            {
                if (row == 0) 
                {
                    currentTimes = 0;
                    randomMatrix[row] = buildRandomArray();
                } else 
                {
                    int[] tempRandomArray = buildRandomArray();
                    for (int col = 0; col < 9; col++) 
                    {
                        if (currentTimes < MAX_CALL_RANDOM_ARRAY_TIMES) 
                        {
                            if (!isCandidateNmbFound(randomMatrix, tempRandomArray, row, col)) 
                            {
                                resetValuesInRowToZero(randomMatrix, row);
                                row -= 1;
                                col = 8;
                                tempRandomArray = buildRandomArray();
                            }
                        } else {
                            row = -1;
                            col = 8;
                            resetValuesToZeros(randomMatrix);
                            currentTimes = 0;
                        }
                    }
                }
            }
            return randomMatrix;
        }
    
        private void resetValuesInRowToZero(int[][] matrix, int row) 
        {
            for (int j = 0; j < 9; j++) 
            {
                matrix[row][j] = 0;
            }
        }
        private void resetValuesToZeros(int[][] matrix) 
        {
            for (int row = 0; row < 9; row++) 
            {
                for (int col = 0; col < 9; col++) 
                {
                    matrix[row][col] = 0;
                }
            }
        }
    
        private boolean isCandidateNmbFound(int[][] randomMatrix, int[] randomArray, int row, int col) 
        {
            for (int i = 0; i < 9; i++) 
            {
                randomMatrix[row][col] = randomArray[i];
                if (noConflict(randomMatrix, row, col)) 
                {
                    return true;
                }
            }
            return false;
        }
    
        //判断每列每行有无冲突
        private boolean noConflict(int[][] candidateMatrix, int row, int col) 
        {
            return noConflictInRow(candidateMatrix, row, col) && noConflictInColumn(candidateMatrix, row, col) && noConflictInBlock(candidateMatrix, row, col);
        }
        //判断每行有无冲突
        private boolean noConflictInRow(int[][] candidateMatrix, int row, int col) 
        {
            int currentValue = candidateMatrix[row][col];
            for (int colNum = 0; colNum < col; colNum++) 
            {
                if (currentValue == candidateMatrix[row][colNum]) 
                {
                    return false;
                }
            }
            return true;
        }
        //判断每列有无冲突
        private boolean noConflictInColumn(int[][] candidateMatrix, int row, int col) 
        {
            int currentValue = candidateMatrix[row][col];
            for (int rowNum = 0; rowNum < row; rowNum++) 
            {
                if (currentValue == candidateMatrix[rowNum][col])
                {
                    return false;
                }
            }
            return true;
        }
        private boolean noConflictInBlock(int[][] candidateMatrix, int row, int col) 
        {
            int baseRow = row / 3 * 3;
            int baseCol = col / 3 * 3;
            for (int rowNum = 0; rowNum < 8; rowNum++) 
            {
                if (candidateMatrix[baseRow + rowNum / 3][baseCol + rowNum % 3] == 0) 
                {
                    continue;
                }
                for (int colNum = rowNum + 1; colNum < 9; colNum++) 
                {
                    if (candidateMatrix[baseRow + rowNum / 3][baseCol + rowNum % 3] == candidateMatrix[baseRow
                            + colNum / 3][baseCol + colNum % 3]) 
                    {
                        return false;
                    }
                }
            }
            return true;
        }
        private int[] buildRandomArray() 
        {
            currentTimes++;
            int[] array = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
            int randomInt = 0;
            for (int i = 0; i < 20; i++) 
            {
                randomInt = random.nextInt(8) + 1;
                int temp = array[0];
                array[0] = array[randomInt];
                array[randomInt] = temp;
            }
            return array;
        }
        public int getCurrentTimes() 
        {
            return currentTimes;
        }
        public void setCurrentTimes(int currentTimes) 
        {
            this.currentTimes = currentTimes;
        }
    } 

    二、游戏界面实现效果:

    1、游戏界面设计:用户填完数独棋盘,点击提交按钮提交后程序会显示成功和失败(见截图),如果多次失败可以查看当前棋盘的答案显示,并进入下一轮游戏。

    2、正确反馈:

    3、错误反馈:

    三、心得体会:

         第一次做小游戏的GUI界面,网上查了很多资料,也找了一些基础的视频来学习,花费时间较多,最后游戏的结果还算满意。主要学习了Javax的组件,如:Container c = getContentPane(),因为JAVAX组件不能直接加到JFRAME上,需要用JFRAM的getContentPane 获得其组件层(javax组件5层之一),而它返回的是个容器,所以用Container c来保存等等,做的过程中发现自身不足较多,后续还需要更多的学习和练习。

    四、代码已上传到Coding.net,可以下载。

    https://coding.net/u/dhlg_201810812007/p/task3/git/tree/master

    JPanel

  • 相关阅读:
    SQLServer 2008 还原数据库备份版本不兼容的问题
    全排列函数
    n & 1
    最长公共子序列(LCS)最长递增子序列(LIS)
    unity3DGI
    多继承的缺点
    JSON文件导入Unity3d中是空的的问题
    丑数
    整数中1出现的次数
    检测鼠标是否在UI上unity
  • 原文地址:https://www.cnblogs.com/sugarfei/p/9808606.html
Copyright © 2020-2023  润新知