document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. import java.util.Arrays;
  2. import java.util.Random;
  3.  
  4. public class Sudoku {
  5.  
  6.     public static final int[][] VALID_BOARD_9X9 = {
  7.         {4, 3, 5, 8, 7, 6, 1, 2, 9},
  8.         {8, 7, 6, 2, 1, 9, 3, 4, 5},
  9.         {2, 1, 9, 4, 3, 5, 7, 8, 6},
  10.         {5, 2, 3, 6, 4, 7, 8, 9, 1},
  11.         {9, 8, 1, 5, 2, 3, 4, 6, 7},
  12.         {6, 4, 7, 9, 8, 1, 2, 5, 3},
  13.         {7, 5, 4, 1, 6, 8, 9, 3, 2},
  14.         {3, 9, 2, 7, 5, 4, 6, 1, 8},
  15.         {1, 6, 8, 3, 9, 2, 5, 7, 4}};
  16.     public static final int[][] VALID_BOARD_6X6 = {
  17.         {1, 2, 3, 4, 5, 6},
  18.         {4, 5, 6, 1, 2, 3},
  19.         {2, 3, 4, 5, 6, 1},
  20.         {5, 6, 1, 2, 3, 4},
  21.         {3, 4, 5, 6, 1, 2},
  22.         {6, 1, 2, 3, 4, 5}};
  23.     public static final int GRID_6X6 = 6;
  24.     public static final int GRID_9X9 = 9;
  25.     public static final int GAME_MODE_EXPERT = 75;
  26.     public static final int GAME_MODE_MEDIUM = 60;
  27.     public static final int GAME_MODE_EASY = 50;
  28.     public static final int GAME_MODE_EASYER = 4;
  29.     public static final int DEFAULT_TOLERANCE = 5;
  30.     public static final String SET_VALUE_9X9 = "123456789";
  31.     public static final String SET_VALUE_6X6 = "123456";
  32.     private int[][] puzzle;
  33.     private Random random = new Random();
  34.  
  35.     // Create a copy of 2D array.
  36.     private int[][] copyOf(int[][] original) {
  37.         int[][] copy = new int[original.length][];
  38.         for (int i = 0; i < original.length; i++) {
  39.             copy[i] = Arrays.copyOf(original[i], original[i].length);
  40.         }
  41.         return copy;
  42.     }
  43.  
  44.     // Swap rows of an 2D array.
  45.     private int[][] swapRows(int[][] board, int row1, int row2) {
  46.         for (int j = 0; j < board.length; j++) {
  47.             int temp = board[row1][j];
  48.             board[row1][j] = board[row2][j];
  49.             board[row2][j] = temp;
  50.         }
  51.         return board;
  52.     }
  53.  
  54.     // Swap columns of an 2D array.
  55.     private int[][] swapCols(int[][] board, int col1, int col2) {
  56.         for (int i = 0; i < board.length; i++) {
  57.             int temp = board[i][col1];
  58.             board[i][col1] = board[i][col2];
  59.             board[i][col2] = temp;
  60.         }
  61.         return board;
  62.     }
  63.  
  64.     // This method swaps rows and columns of an valid board.
  65.     // Swaping process for rows must be done same horizontal grid and
  66.     // also for column swaping process must be in vertical grid.
  67.     private int[][] swapRowsAndCols(int[][] board) {
  68.  
  69.         int range = board.length == GRID_9X9 ? 7 : 5;
  70.         // define number of rows per horizontal group.
  71.         int rowsInGrid = board.length == GRID_9X9 ? 3 : 2;
  72.         // For both 9X9 and and 9X6 number of columns in vertical grid is 3.
  73.         int colsInGrid = 3;
  74.  
  75.         for (int a = 0; a < range; a += rowsInGrid) {
  76.             int row[] = getTwoRanNum(a, rowsInGrid);
  77.             swapRows(board, row[0], row[1]);
  78.         }
  79.  
  80.         for (int a = 0; a < range; a += colsInGrid) {
  81.             int[] col = getTwoRanNum(a, colsInGrid);
  82.             swapCols(board, col[0], col[1]);
  83.         }
  84.         return board;
  85.     }
  86.  
  87.     // Swap only horizontal groups.
  88.     private int[][] swapGrids(int[][] board) {
  89.         int firstgrid = 1 + random.nextInt(3);
  90.         int secondgrid = 1 + random.nextInt(3);
  91.         int numRowsInGrid = board.length == GRID_9X9 ? 3 : 2;
  92.  
  93.         if ((firstgrid == 1 && secondgrid == 2) || (firstgrid == 2 && secondgrid == 1)) {
  94.             for (int i = 0; i < numRowsInGrid; i++) {
  95.                 swapRows(board, i, i + numRowsInGrid);
  96.             }
  97.         } else if ((firstgrid == 2 && secondgrid == 3) || (firstgrid == 3 && secondgrid == 2)) {
  98.             for (int i = numRowsInGrid; i < numRowsInGrid * 2; i++) {
  99.                 swapRows(board, i, i + numRowsInGrid);
  100.             }
  101.         } else if ((firstgrid == 1 && secondgrid == 3) || (firstgrid == 3 && secondgrid == 1)) {
  102.             for (int i = 0; i < numRowsInGrid; i++) {
  103.                 swapRows(board, i, i + (numRowsInGrid * 2));
  104.             }
  105.         }
  106.         return board;
  107.     }
  108.  
  109.     // swap numbers for each rows.
  110.     private int[][] swapNums(int[][] board) {
  111.         int[] num = getTwoRanNum(1, board.length);
  112.         for (int i = 0; i < board.length; i++) {
  113.             for (int j = 0; j < board.length; j++) {
  114.                 if (board[i][j] == num[0]) {
  115.                     board[i][j] = num[1];
  116.                 } else if (board[i][j] == num[1]) {
  117.                     board[i][j] = num[0];
  118.                 }
  119.             }
  120.         }
  121.         return board;
  122.     }
  123.  
  124.     // provide two random number as an array with length two.
  125.     private int[] getTwoRanNum(int min, int tolerance) {
  126.         int a[] = new int[2];
  127.         a[0] = min + random.nextInt(tolerance);
  128.         a[1] = min + random.nextInt(tolerance);
  129.         return a;
  130.     }
  131.  
  132.     // Create an validsudoku board.
  133.     private int[][] createBoard(int[][] board) {
  134.         for (int i = 0; i < 10; i++) {
  135.             swapRowsAndCols(board);
  136.             swapGrids(board);
  137.             swapNums(board);
  138.         }
  139.         return board;
  140.     }
  141.  
  142.     // Hide some numbers to create puzzle.
  143.     private int[][] createPuzzle(int[][] board, int mode) {
  144.         this.puzzle = copyOf(board);
  145.         int numOfEmptyBlock = getNumberOfEmptyBlock(board, mode);
  146.         for (int i = 0; i < numOfEmptyBlock; i++) {
  147.             int[] rowcol = getTwoRanNum(0, board.length);
  148.             this.puzzle[rowcol[0]][rowcol[1]] = 0;
  149.         }
  150.         return copyOf(this.puzzle);
  151.     }
  152.  
  153.     // Define number of empty blocks according to game mode.
  154.     private int getNumberOfEmptyBlock(int[][] board, int mode) {
  155.         int numOfEmptyBlock = 0;
  156.         int numOfBlock = board.length * board[0].length;
  157.  
  158.         if (GAME_MODE_EASYER <= mode && mode <= GAME_MODE_EXPERT) {
  159.             numOfEmptyBlock = (int) Math.floor((mode * numOfBlock) / 100);
  160.         } else {
  161.             numOfEmptyBlock = (int) Math.floor((GAME_MODE_MEDIUM * numOfBlock) / 100);
  162.         }
  163.         int tolerance = (int) Math.floor(((numOfBlock - numOfEmptyBlock) * 5) / 100);
  164.         numOfEmptyBlock += random.nextInt(tolerance + 1); // to avoid negetive
  165.  
  166.         return numOfEmptyBlock;
  167.     }
  168.  
  169.     // Check Is the sollution correct or Incorrect.
  170.     public boolean check(int[][] board) {
  171.         boolean isCorrect = true;
  172.         int numOfRowsInGrid = board.length == 9 ? 3 : 2;
  173.         final String setValues = board.length == 9 ? SET_VALUE_9X9 : SET_VALUE_6X6;
  174.         // check rows
  175.         for (int i = 0; i < board.length; i++) {
  176.             String set = setValues;
  177.             for (int j = 0; j < board.length; j++) {
  178.                 set = set.replace("" + board[i][j], "");
  179.             }
  180.             if (!set.isEmpty()) {
  181.                 isCorrect = false;
  182.                 return isCorrect;
  183.             }
  184.         }
  185.  
  186.         // check columns
  187.         for (int j = 0; j < board.length; j++) {
  188.             String set = setValues;
  189.             for (int i = 0; i < board.length; i++) {
  190.                 set = set.replace("" + board[i][j], "");
  191.             }
  192.             if (!set.isEmpty()) {
  193.                 isCorrect = false;
  194.                 return isCorrect;
  195.             }
  196.         }
  197.  
  198.         //check Horizontal and vertical grids
  199.         for (int hg = 0; hg < board.length; hg += numOfRowsInGrid) {
  200.             for (int vg = 0; vg < board[0].length; vg += 3) {
  201.                 String set = setValues;
  202.                 for (int i = hg; i < (hg + numOfRowsInGrid); i++) {
  203.                     for (int j = vg; j < vg + 3; j++) {
  204.                         set = set.replace("" + board[i][j], "");
  205.                     }
  206.                 }
  207.                 if (!set.isEmpty()) {
  208.                     isCorrect = false;
  209.                     return isCorrect;
  210.                 }
  211.             }
  212.         }
  213.  
  214.         return isCorrect;
  215.     }
  216.  
  217.     public int[][] getNewPuzzle(int grid, int gameMode) {
  218.         if (grid == GRID_9X9) {
  219.             return createPuzzle(createBoard(VALID_BOARD_9X9), gameMode);
  220.         } else if (grid == GRID_6X6) {
  221.             return createPuzzle(createBoard(VALID_BOARD_6X6), gameMode);
  222.         }
  223.  
  224.         return createPuzzle(createBoard(VALID_BOARD_9X9), gameMode);
  225.     }
  226.  
  227.     public int[][] resetPuzzle() {
  228.         return puzzle;
  229.     }
  230.  
  231.     private void printArray(int[][] a) {
  232.         for (int i = 0; i < a.length; i++) {
  233.             for (int j = 0; j < a[i].length; j++) {
  234.                 System.out.print(a[i][j] + "\\t");
  235.             }
  236.             System.out.println();
  237.         }
  238.         System.out.println();
  239.     }
  240. }
  241.  
');