用 Java 实现数独游戏
最编程
2024-06-01 19:25:13
...
数独游戏:
窗体+逻辑实现类
public class SudokuGame extends JFrame { private final JTextField[][] cells; private int[][] solution; private int[][] puzzle; public SudokuGame() { setTitle("Sudoku Game"); setSize(800, 800); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new BorderLayout()); JPanel sudokuPanel = new JPanel(new GridLayout(9, 9)); cells = new JTextField[9][9]; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { cells[i][j] = new JTextField(1); cells[i][j].setFont(new Font("serilf", Font.BOLD, 40)); cells[i][j].setHorizontalAlignment(JTextField.CENTER); int ii = i; int jj = j; cells[i][j].addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent e) { if (e.getKeyChar() - 48 != solution[ii][jj]) { cells[ii][jj].setBackground(Color.red); } else { printCells(ii, jj); } } @Override public void keyPressed(KeyEvent e) { int len = cells[ii][jj].getText().length(); if (len > 0) { cells[ii][jj].setText(""); } } @Override public void keyReleased(KeyEvent e) { boolean flag = false; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (!Integer.toString(solution[i][j]).equals(cells[i][j].getText())) { flag = true; break; } } if (flag) break; } if (!flag) { JLabel message = new JLabel("恭喜你挑战成功!!!"); ImageIcon icon = new ImageIcon(); JOptionPane.showMessageDialog(sudokuPanel, message, "挑战成功", 3, icon); } } }); printCells(i, j); sudokuPanel.add(cells[i][j]); } } add(sudokuPanel, BorderLayout.CENTER); JPanel buttonPanel = getjPanel(); add(buttonPanel, BorderLayout.SOUTH); generatePuzzle(); while (!issolvable()) { generatePuzzle(); } setPuzzle(); } private JPanel getjPanel() { JPanel buttonPanel = new JPanel(new GridLayout(1, 2)); JButton solveButton = new JButton("显示答案"); solveButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { setSolution(); } }); JButton tryAgain = new JButton("换一个"); tryAgain.addActionListener((e) -> { generatePuzzle(); while (!issolvable()) { generatePuzzle(); } setPuzzle(); }); buttonPanel.add(solveButton); buttonPanel.add(tryAgain); return buttonPanel; } private void printCells(int i, int j) { switch (i / 3) { case 0: case 2: switch (j / 3) { case 0: case 2: cells[i][j].setBackground(Color.blue); break; case 1: cells[i][j].setBackground(Color.green); break; default: break; } break; case 1: switch (j / 3) { case 0: case 2: cells[i][j].setBackground(Color.green); break; case 1: cells[i][j].setBackground(Color.blue); break; default: break; } break; default: break; } } private void generatePuzzle() { // 创建一个新的数独谜题 SudokuGenerator generator = new SudokuGenerator(); puzzle = generator.generateSudokuPuzzle(); } private static class SudokuSolver { public boolean solveSudoku(int[][] board) { int row = -1; int col = -1; boolean isEmpty = true; // 找到未填充的位置 for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (board[i][j] == 0) { row = i; col = j; isEmpty = false; break; } } if (!isEmpty) { break; } } // 如果没有未填充的位置,数独已解决 if (isEmpty) { return true; } // 尝试填充数字 for (int num = 1; num <= 9; num++) { if (isSafe(board, row, col, num)) { board[row][col] = num; if (solveSudoku(board)) { return true; } board[row][col] = 0; // 回溯 } } return false; } private boolean isSafe(int[][] board, int row, int col, int num) { // 检查行 for (int i = 0; i < 9; i++) { if (board[row][i] == num) { return false; } } // 检查列 for (int i = 0; i < 9; i++) { if (board[i][col] == num) { return false; } } // 检查小九宫格 int startRow = row - row % 3; int startCol = col - col % 3; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i + startRow][j + startCol] == num) { return false; } } } return true; } } private void setPuzzle() { for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (puzzle[i][j] != 0) { cells[i][j].setText(Integer.toString(solution[i][j])); cells[i][j].setEditable(false); } else { cells[i][j].setText(""); } } } } private void setSolution() { for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { cells[i][j].setText(Integer.toString(solution[i][j])); } } } public boolean issolvable() { // 实现数独求解逻辑 SudokuSolver solver = new SudokuSolver(); solution = new int[9][9]; for (int i = 0; i < 9; i++) { System.arraycopy(puzzle[i], 0, solution[i], 0, 9); } return solver.solveSudoku(solution); } public static void main(String[] args) { SudokuGame game = new SudokuGame(); game.setVisible(true); } }
随机生成数组类
import java.util.Random; public class SudokuGenerator { private static final int SIZE = 9; private int[][] puzzle; public SudokuGenerator() { puzzle = new int[SIZE][SIZE]; } public int[][] generateSudokuPuzzle() { fillDiagonal(); // 填充对角线的 3x3 子网格 fillRemaining(0, 3); // 从左上角的 3x3 子网格开始填充 puzzle = generatePuzzleWithHiddenNumbers(60);//参数是要掩盖的数字个数 return puzzle; } private void fillDiagonal() { Random random = new Random(); for (int i = 0; i < SIZE; i += 3) { fillSubGrid(i, i, random); } } private void fillSubGrid(int row, int col, Random random) { int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 9}; shuffleArray(nums, random); int index = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { puzzle[row + i][col + j] = nums[index++]; } } } private void shuffleArray(int[] array, Random random) { for (int i = array.length - 1; i > 0; i--) { int index = random.nextInt(i + 1); int temp = array[index]; array[index] = array[i]; array[i] = temp; } } private boolean isValid(int row, int col, int num) { for (int i = 0; i < SIZE; i++) { if (puzzle[row][i] == num || puzzle[i][col] == num) { return false; } } int subGridStartRow = row - row % 3; int subGridStartCol = col - col % 3; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (puzzle[subGridStartRow + i][subGridStartCol + j] == num) { return false; } } } return true; } private boolean fillRemaining(int row, int col) { if (col == SIZE) { col = 0; row++; if (row == SIZE) { return true; } } if (puzzle[row][col] != 0) { return fillRemaining(row, col + 1); } Random random = new Random(); int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 9}; shuffleArray(nums, random); for (int i = 0; i < SIZE; i++) { if (isValid(row, col, nums[i])) { puzzle[row][col] = nums[i]; if (fillRemaining(row, col + 1)) { return true; } puzzle[row][col] = 0; } } return false; } public int[][] generatePuzzleWithHiddenNumbers(int numToHide) { int[][] puzzleWithHiddenNumbers = deepCopy(puzzle); Random random = new Random(); while (numToHide > 0) { int row = random.nextInt(SIZE); int col = random.nextInt(SIZE); if(puzzleWithHiddenNumbers[row][col] != 0) { puzzleWithHiddenNumbers[row][col] =0; numToHide--; } } return puzzleWithHiddenNumbers; } private int[][] deepCopy(int[][] original) { int[][] copy = new int[original.length][]; for (int i = 0; i < original.length; i++) { copy[i] = original[i].clone(); } return copy; } }
改进:
通过调整掩盖数字的个数来实现调整难度的功能,
增加消耗时间的显示
提示单个数字的功能
上一篇: 九宫格数独游戏的 Python 实现
下一篇: 个人项目实践(数独)
推荐阅读
-
[JAVA]用 Java 连接数据库并实现查询员工信息功能
-
用 JAVA 实现大写金额到小写金额的转换
-
用Python实现2048小游戏(终端升级版)相比上篇 增添了撤回功能和历史最高分数的统计
-
Java 实现2048游戏之详细教程
-
通过使用Java来实现2048小游戏,并直接使用(无需其他操作)
-
玩了一盘Java实现的2048小游戏,竟然一次都没赢,大家觉得我这个水平如何?
-
【Java编程】用简单的100行代码实现2048小游戏
-
Java 8新特性探究(十三)JavaFX 8新特性以及开发2048游戏-JavaFX历史## 跟java在服务器端和web端成绩相比,桌面一直是java的软肋,于是Sun公司在2008年推出JavaFX,弥补桌面软件的缺陷,请看下图JavaFX一路走过来的改进 从上图看出,一开始推出时候,开发者需使用一种名为JavaFX Script的静态的、声明式的编程语言来开发JavaFX应用程序。因为JavaFX Script将会被编译为Java bytecode,程序员可以使用Java代码代替。 JavaFX 2.0之后的版本摒弃了JavaFX Script语言,而作为一个Java API来使用。因此使用JavaFX平台实现的应用程序将直接通过标准Java代码来实现。 JavaFX 2.0 包含非常丰富的 UI 控件、图形和多媒体特性用于简化可视化应用的开发,WebView可直接在应用中嵌入网页;另外 2.0 版本允许使用 FXML 进行 UI 定义,这是一个脚本化基于 XML 的标识语言。 从JDK 7u6开始,JavaFx就与JDK捆绑在一起了,JavaFX团队称,下一个版本将是8.0,目前所有的工作都已经围绕8.0库进行。这是因为JavaFX将捆绑在Java 8中,因此该团队决定跳过几个版本号,迎头赶上Java 8。 ##JavaFx8的新特性 ## ###全新现代主题:Modena 新的Modena主题来替换原来的Caspian主题。不过在Application的start方法中,可以通过setUserAgentStylesheet(STYLESHEET_CASPIAN)来继续使用Caspian主题。 参考http://fxexperience.com/2013/03/modena-theme-update/ ###JavaFX 3D 在JavaFX8中提供了3D图像处理API,包括Shape3D (Box, Cylinder, MeshView, Sphere子类),SubScene, Material, PickResult, LightBase (AmbientLight 和PointLight子类),SceneAntialiasing等。Camera类也得到了更新。从JavaDoc中可以找到更多信息。 ###富文本 强化了富文本的支持 ###TreeTableView ###日期控件DatePicker 增加日期控件 ###用于 CSS 结构的公共 API
-
猜数字游戏-用C语言实现【干货分享,包含源码】
-
用Java编写可实现俄罗斯方块游戏