Advertisement
Guest User

Untitled

a guest
Mar 2nd, 2013
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.06 KB | None | 0 0
  1. /*******************************************************************************
  2.  * Main.java                                                                   *
  3.  *******************************************************************************/
  4. package sudokiller;
  5.  
  6. /**
  7.  * Sudoku game solver.
  8.  * It creates a GUI with a default puzzle; you can replace it with the puzzle
  9.  * you want to solve. Then click the 'Start' button (or type 'ALT-s') to get the
  10.  * solution.
  11.  *
  12.  * @author Daniele Mazzocchio
  13.  * @version 1.0
  14.  */
  15. public class Main {
  16.    
  17.     /**
  18.      * Creates the GUI with a default puzzle.
  19.      * @params args Command-line arguments (unused)
  20.      */
  21.     public static void main(String[] args) {
  22.         int[][] board = {{0, 6, 0, 1, 0, 4, 0, 5, 0},
  23.                          {0, 0, 8, 3, 0, 5, 6, 0, 0},
  24.                          {2, 0, 0, 0, 0, 0, 0, 0, 1},
  25.                          {8, 0, 0, 4, 0, 7, 0, 0, 6},
  26.                          {0, 0, 6, 0, 0, 0, 3, 0, 0},
  27.                          {7, 0, 0, 9, 0, 1, 0, 0, 4},
  28.                          {5, 0, 0, 0, 0, 0, 0, 0, 2},
  29.                          {0, 0, 7, 2, 0, 6, 9, 0, 0},
  30.                          {0, 4, 0, 5, 0, 8, 0, 7, 0}};
  31.        
  32.         new SwingSudoKiller(new SwingSudokuBoard(board));
  33.     }  
  34. }
  35.  
  36.  
  37. /*******************************************************************************
  38.  * SudokuBoard.java                                                            *
  39.  *******************************************************************************/
  40. package sudokiller;
  41.  
  42. /**
  43.  * This is the base class for implementing a Sudoku board.
  44.  * It mostly is a two-dimensional <code>int<code> array and provides
  45.  * basic methods for getting/setting cells contents. Board cells are identified
  46.  * by their row and column and are zero-indexed.
  47.  *
  48.  * @author Daniele Mazzocchio
  49.  * @version 1.0
  50.  */
  51. public class SudokuBoard {
  52.     final int EMPTY = 0;      // Empty cells marker
  53.     final int size;           // Size of the board (number of rows and columns)
  54.     final int box_size;       // Size of the inner boxes
  55.  
  56.     private int[][] board;    // 2D array representing the game board
  57.  
  58.     /**
  59.      * Creates an empty board.
  60.      * @param size Number of rows and columns of the board.
  61.      */
  62.     public SudokuBoard(int size) {
  63.         board = new int[size][size];
  64.         this.size = size;
  65.         this.box_size = (int) Math.sqrt(size);
  66.     }
  67.    
  68.     /**
  69.      * Creates and initializes the board.
  70.      * @param board Array to initialize the board contents.
  71.      */
  72.     public SudokuBoard(int[][] board) {
  73.         this(board.length);
  74.         this.board = board;
  75.     }
  76.    
  77.     /**
  78.      * Puts a number into a specific cell.
  79.      * @param num Number to put into the board cell.
  80.      * @param row Cell's row.
  81.      * @param col Cell's column.
  82.      */
  83.     public void setCell(int num, int row, int col) {
  84.         board[row][col] = num;
  85.     }
  86.  
  87.     /**
  88.      * Returns the number contained in a specific cell.
  89.      * @param row Cell's row.
  90.      * @param col Cell's column.
  91.      * @return The number contained in the cell.
  92.      */
  93.     public int getCell(int row, int col) {
  94.         return board[row][col];
  95.     }
  96. }
  97.  
  98.  
  99. /*******************************************************************************
  100.  * SudoKiller.java                                                             *
  101.  *******************************************************************************/
  102. package sudokiller;
  103.  
  104. /**
  105.  * This is the base class for implementing a Sudoku solver.
  106.  * It provides a simple method for guessing the solution, but lets subclasses
  107.  * decide how to display it.
  108.  *
  109.  * @author Daniele Mazzocchio
  110.  * @version 1.0
  111.  */
  112. abstract class SudoKiller {
  113.     private SudokuBoard sb;    // Puzzle to solve;
  114.  
  115.     /**
  116.      * Initializes the game board.
  117.      * @param sb The puzzle to solve.
  118.      */
  119.     public SudoKiller(SudokuBoard sb) {
  120.         this.sb = sb;
  121.     }
  122.    
  123.     /**
  124.      * Check if a number is, according to Sudoku rules, a legal candidate for
  125.      * the given cell.
  126.      * @param num Number to check.
  127.      * @param row Cell's row.
  128.      * @param col Cell's column.
  129.      * @return <code>false<code> if <code>num<code> already appears in the row,
  130.      *         column or box the cell belongs to or <code>true<code> otherwise.
  131.      */
  132.     private boolean check(int num, int row, int col) {
  133.         int r = (row / sb.box_size) * sb.box_size;
  134.         int c = (col / sb.box_size) * sb.box_size;
  135.        
  136.         for (int i = 0; i < sb.size; i++) {
  137.             if (sb.getCell(row, i) == num ||
  138.                 sb.getCell(i, col) == num ||
  139.                 sb.getCell(r + (i % sb.box_size), c + (i / sb.box_size)) == num) {
  140.                 return false;
  141.             }
  142.         }
  143.         return true;
  144.     }
  145.    
  146.     /**
  147.      * Test all candidate numbers for a given cell until the board is complete.
  148.      * @param row Cell's row.
  149.      * @param col Cell's column.
  150.      * @return <code>false<code> if no legal numbers are found for this cell.
  151.      */
  152.     public boolean guess(int row, int col) {
  153.         int nextCol = (col + 1) % sb.size;
  154.         int nextRow = (nextCol == 0) ? row + 1 : row;
  155.        
  156.         try {
  157.             if (sb.getCell(row, col) != sb.EMPTY)
  158.                 return guess(nextRow, nextCol);
  159.         }
  160.         catch (ArrayIndexOutOfBoundsException e) {
  161.                 return true;
  162.         }
  163.  
  164.         for (int i = 1; i <= sb.size; i++) {
  165.             if (check(i, row, col)) {
  166.                 sb.setCell(i, row, col);
  167.                 if (guess(nextRow, nextCol)) {
  168.                     return true;
  169.                 }
  170.             }
  171.         }
  172.         sb.setCell(sb.EMPTY, row, col);
  173.         return false;
  174.     }
  175. }
  176.  
  177.    
  178. /*******************************************************************************
  179.  * SwingSudokuBoard.java                                                       *
  180.  *******************************************************************************/
  181. package sudokiller;
  182.  
  183. import java.awt.*;
  184. import javax.swing.*;
  185.  
  186. /**
  187.  * This class represents a graphical Sudoku board.
  188.  * It is mostly a two-dimensional <code>JTextField<code> array
  189.  * providing all the functionality of a <code>SudokuBoard<code> object.
  190.  * Board cells are identified by their row and column and are zero-indexed.
  191.  *
  192.  * @author Daniele Mazzocchio
  193.  * @version 1.0
  194.  */
  195. public class SwingSudokuBoard extends SudokuBoard {
  196.     private JTextField[][] cells;          // Graphical game board
  197.     private JPanel panel = new JPanel();   // Container
  198.  
  199.     /**
  200.      * Draws an empty board.
  201.      * @param size Number of rows and columns of the board.
  202.      */
  203.     public SwingSudokuBoard(int size) {
  204.         super(size);
  205.         cells = new JTextField[size][size];
  206.         panel.setLayout(new GridLayout(size, size));
  207.         for (int row = 0; row < size; row++) {
  208.             for (int col = 0; col < size; col++)  {
  209.                 cells[row][col] = new JTextField(1);
  210.                 panel.add(cells[row][col]);
  211.             }
  212.         }
  213.     }
  214.  
  215.     /**
  216.      * Draws and initializes the board.
  217.      * @param board Array to initialize the board contents.
  218.      */
  219.     public SwingSudokuBoard(int[][] board) {
  220.         this(board.length);
  221.         for (int row = 0; row < size; row++) {
  222.             for (int col = 0; col < size; col++) {
  223.                 setCell(board[row][col], row, col);
  224.             }
  225.         }
  226.     }
  227.    
  228.     /**
  229.      * Puts a number into a specific text field.
  230.      * @param num Number to put into the text field (cell).
  231.      * @param row Cell's row.
  232.      * @param col Cell's column.
  233.      */
  234.     public void setCell(int num, int row, int col) {
  235.         super.setCell(num, row, col);
  236.         String text = (num == EMPTY) ? "" : String.valueOf(num);
  237.         cells[row][col].setText(text);
  238.     }
  239.    
  240.     /**
  241.      * Returns the number contained in a specific text field (cell).
  242.      * @param row Cell's row.
  243.      * @param col Cell's column.
  244.      * @return The number contained in the cell.
  245.      */
  246.     public int getCell(int row, int col) {
  247.         int cell;
  248.  
  249.         try {
  250.             cell = Integer.parseInt(cells[row][col].getText());
  251.         }
  252.         catch (NumberFormatException e) {
  253.             cell = EMPTY;
  254.         }
  255.         return cell;
  256.     }
  257.    
  258.     /**
  259.      * Returns the JPanel containing the board.
  260.      * @return Returns the board container.
  261.      */
  262.     public JPanel getPanel() {
  263.         return panel;
  264.     }
  265. }
  266.  
  267.  
  268. /*******************************************************************************
  269.  * SwingSudoKiller.java                                                        *
  270.  *******************************************************************************/
  271. package sudokiller;
  272.  
  273. import java.awt.*;
  274. import java.awt.event.*;
  275. import javax.swing.*;
  276.  
  277. /**
  278.  * Graphical Sudoku game solver.
  279.  * The user should fill the board with the puzzle to solve and click the
  280.  * 'Start' button (or type 'ALT-s') to get the solution.
  281.  *
  282.  * @author Daniele Mazzocchio
  283.  * @version 1.0
  284.  */
  285. public class SwingSudoKiller extends SudoKiller {
  286.  
  287.     /**
  288.      * Draw the game board.
  289.      * @param ssb The puzzle to solve.
  290.      */
  291.     public SwingSudoKiller(SwingSudokuBoard ssb) {
  292.         super(ssb);
  293.         final JPanel panel = ssb.getPanel();
  294.  
  295.         Runnable runner = new Runnable() {
  296.             public void run() {
  297.                 final JFrame frame = new JFrame("SudoKiller");
  298.                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  299.  
  300.                 ActionListener al = new ActionListener() {
  301.                     public void actionPerformed(ActionEvent ae) {
  302.                         if (! guess(0, 0))
  303.                             JOptionPane.showMessageDialog(frame, "Solution not found!");
  304.                     }
  305.                 };
  306.                 frame.setLayout(new GridBagLayout());
  307.                 addComponent(frame, panel, 0, 0, 1, 1);
  308.                
  309.                 JButton b = new JButton("Start!");
  310.                 b.setMnemonic(KeyEvent.VK_S);
  311.                 b.addActionListener(al);
  312.                 addComponent(frame, b, 0, 1, 1, 1);
  313.  
  314.                 frame.setSize(240, 280);
  315.                 frame.setVisible(true);
  316.             }
  317.         };
  318.         EventQueue.invokeLater(runner);
  319.     }
  320.    
  321.     /**
  322.      * Add a component to the GUI.
  323.      * @param container Container to add the component to.
  324.      * @param component The component to be added.
  325.      * @param gridx Horizontal cell position inside the grid.
  326.      * @param gridy Vertical cell position inside the grid.
  327.      * @param gridwidth Number of cells in a row for the text field.
  328.      * @param gridheight Number of cells in a column for the text field.
  329.      */
  330.     private static void addComponent(Container container, Component component,
  331.         int gridx, int gridy, int gridwidth, int gridheight) {
  332.         Insets insets = new Insets(0, 0, 0, 0);
  333.         GridBagConstraints gbc = new GridBagConstraints(gridx, gridy, gridwidth,
  334.                 gridheight, 1, 1, GridBagConstraints.CENTER,
  335.                 GridBagConstraints.BOTH, insets, 0, 0);
  336.         container.add(component, gbc);
  337.     }
  338. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement