1、題目要求完成數獨遊戲界面功能,代碼已實現如下題目要求:java
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 + "\t"); } 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 + "\t"); } 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; } }
2、遊戲界面實現效果:git
一、遊戲界面設計:用戶填完數獨棋盤,點擊提交按鈕提交後程序會顯示成功和失敗(見截圖),若是屢次失敗能夠查看當前棋盤的答案顯示,並進入下一輪遊戲。數組
二、正確反饋:dom
三、錯誤反饋:ide
3、心得體會:佈局
第一次作小遊戲的GUI界面,網上查了不少資料,也找了一些基礎的視頻來學習,花費時間較多,最後遊戲的結果還算滿意。主要學習了Javax的組件,如:Container c = getContentPane(),由於JAVAX組件不能直接加到JFRAME上,須要用JFRAM的getContentPane 得到其組件層(javax組件5層之一),而它返回的是個容器,因此用Container c來保存等等,作的過程當中發現自身不足較多,後續還須要更多的學習和練習。學習
4、代碼已上傳到Coding.net,能夠下載。ui
https://coding.net/u/dhlg_201810812007/p/task3/git/tree/masterthis
JPanelspa