2013-06-15 2 views
3

J'ai travaillé sur un générateur de puzzle sudoku en Java, j'ai écrit cette classe pour générer le puzzle, mais il ne génère pas correctement le puzzle. Voici un exemple de ce que je reçois:Java générateur de sudoku ne fonctionne pas correctement

puzzle

Comme vous pouvez le voir ce n'est pas une solution valable sudoku. Mais en regardant mon code, je ne comprends pas pourquoi il ne génère pas un puzzle valide. Quelqu'un peut-il expliquer pourquoi cela ne fonctionne pas correctement?

package sudoku; 

import java.util.Random; 

public class Puzzle { 

    // number generator 
    Random gen = new Random(); 

    // 9x9 puzzle 
    int puzzle[][] = new int[9][9]; 

    public int[][] generate() { 

     // add each number to the board 
     for (int x = 0; x < 9; x++) { 
      for (int y = 0; y < 9; y++) { 

       boolean isValid = false; 

       // keep generating new numbers until a valid number is found 
       while (isValid == false) { 

        // generate random number 1-9 
        int num = gen.nextInt(9) + 1; 

        // check if number is valid 
        if (checkRow(num, x) == true || checkCol(num, y) == true 
          || checkSection(num, x, y) == true) { 

         // add number to the board 
         puzzle[x][y] = num; 

         // exit loop 
         isValid = true; 
        } 
       } 
      } 
     } 

     return puzzle; 
    } 

    // check each element of the row for num, if num is found return false 
    private boolean checkRow(int num, int row) { 

     boolean valid = true; 
     for (int i = 0; i < 9; i++) { 
      if (puzzle[row][i] == num) { 
       valid = false; 
       break; 
      } 
     } 

     return valid; 
    } 

    // check each element of the column for num, if num is found return false 
    private boolean checkCol(int num, int col) { 

     boolean valid = true; 
     for (int i = 0; i < 9; i++) { 
      if (puzzle[i][col] == num) { 
       valid = false; 
       break; 
      } 
     } 

     return valid; 
    } 

    // check each element of the section for num, if num is found return false 
    private boolean checkSection(int num, int xPos, int yPos) { 

     int[][] section = new int[3][3]; 
     section = getSection(xPos, yPos); 

     boolean valid = true; 
     for (int i = 0; i < 3; i++) { 
      for (int j = 0; j < 3; j++) { 
       if (section[i][j] == num) { 
        valid = false; 
        break; 
       } 
      } 
     } 

     return valid; 
    } 

    // return the 3x3 section the given coordinates are in 
    private int[][] getSection(int xPos, int yPos) { 

     int xIndex = 0; 
     int yIndex = 0; 
     int[][] section = new int[3][3]; 

     // get x index 
     if (xPos == 0 || xPos == 3 || xPos == 6) { 
      xIndex = xPos; 
     } else if (xPos == 1 || xPos == 4 || xPos == 7) { 
      xIndex = xPos - 1; 
     } else if (xPos == 2 || xPos == 5 || xPos == 8) { 
      xIndex = xPos - 2; 
     } 

     // get y index 
     if (yPos == 0 || yPos == 3 || yPos == 6) { 
      yIndex = yPos; 
     } else if (yPos == 1 || yPos == 4 || yPos == 7) { 
      yIndex = yPos - 1; 
     } else if (yPos == 2 || yPos == 5 || yPos == 8) { 
      yIndex = yPos - 2; 
     } 

     int i = 0; 
     int j = 0; 
     // extract section from puzzle 
     for (int x = xIndex; x < 3; x++) { 
      for (int y = yIndex; y < 3; y++) { 
       section[x][y] = puzzle[i][j]; 
       i++; 
      } 
      j++; 
     } 

     return section; 

    } 
} 
+1

Votre classe est entièrement écrite, sans aucune trace d'orientation de l'objet. Vous pouvez trouver que votre algorithme est plus facile à résoudre si vous le modulez en objets, chacun étant ses propres méthodes pour tester et se construire. Les noms dans votre projet sont Puzzle, Sections, Squares; peut-être Colonne et Ligne et Chiffre. Ceux-ci ressemblent à des cours. Au lieu de déboguer une énorme procédure monolithique, il serait plus facile de déboguer le comportement des modules individuels. – scottb

+1

Ce n'est pas une erreur mais dans 'if (someCondition == true)' la partie '== true' est redondante, simple' if (someCondition) 'est suffisant. – Pshemo

Répondre

5

Il ne suffit pas qu'une ligne, une colonne ou une section soit valide. Ils doivent tous être valides. Alors, changez cette ligne:

if (checkRow(num, x) == true || checkCol(num, y) == true || checkSection(num, x, y) == true) 

avec

if (checkRow(num, x) == true && checkCol(num, y) == true && checkSection(num, x, y) == true) 

ou tout simple

if (checkRow(num, x) && checkCol(num, y) && checkSection(num, x, y)) { 
2

Il pourrait y avoir d'autres erreurs, mais cette ligne est manifestement erronée:

if (checkRow(num, x) == true || checkCol(num, y) == true 
         || checkSection(num, x, y) == true) { 

Vous devez utiliser && (booléen ET) ici au lieu de || (booléen OU).

Questions connexes