Problème Débutant en Java

AEROTOWER -  
 AEROTOWER -
Bonjour,

Je suis débutante dans la programmation.

Je dois élaborer un programme en Java permettant de remplir n'importe quelle grille de Sudoku définie à partir d'un fichier .txt spécifiant la grille à remplir.

En entrée, le programme lira le fichier texte contenant la grille à compléter. En sortie, le programme affichera la grille complétée.

S'il existe plusieurs solutions pour la grille de départ, le programme devra fournir deux solutions seulement.

J'ai réalisé le programme suivant :

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
 
public class Principale20 {
 
    public static void main(String[] args) throws IOException {
         
        BufferedReader in = new BufferedReader(new FileReader("fichier/monSudoku grille1.txt")); //lieu où ce trouve le fichier .txt
 
        String line = in.readLine(); //on enregistre les lignes lues dans la variable line
 
        while (line!= null) { //tant qu'il y a quelque chose dans line on lit
 
            if( line.startsWith("#")) { //si line commence pas"#"
 
                line = in.readLine();//on passe à la ligne suivante
 
            }else {//sinon
 
                System.out.println(line);//on écrit la ligne dans la console....ou ailleurs ; )
 
                line=in.readLine();//on passe à la ligne suivante
 
            }
 
        }
 
        in.close(); //on ferme le lecteur
         
         
        SudokuTest2 sudo1= new SudokuTest2(args[0]);
        System.out.print(sudo1);
        System.out.println("Is legal ?  ");
        System.out.println("Is OK ?  ");
        sudo1.solver();
        System.out.print(sudo1);
 
    }
}

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
 
 
public class SudokuTest2 {
 
    public static final int N=9;
    int[][] grille;
 
    // Constructeur instancie avec une String
    public SudokuTest2(String nomDeFichier){
    }
     
    // Methode pour lire la grille a partir d'un fichier
    private void readGrilleFromFile(String nomDeFichier) {
        int[][] input=new int [N][N];
        try {
            StringBuffer sbuf = new StringBuffer();
            String str;
            BufferedReader in = new BufferedReader(new FileReader(nomDeFichier));
             
            str = in.readLine();
             
            int i=0;
            while (str != null) {
                for (int j=0;j<str.trim().split(" ").length;j++){
                    input[i][j]=Integer.parseInt(str.trim().split(" ")[j]);
                }
             
                str = in.readLine();
                i++;
            }
            grille=input;
        } catch (IOException e) {
            System.err.println(e);
            System.out.println("Fichier " +nomDeFichier+" inexistant...");
        }
      
    }
     
    private int[][] grille1;
    public static final int VIDE = 0; // cellule vide
    public static final int TAILLE = 9; // taille de la grille
 
    public SudokuTest2(int[][] tableau) {
        this.grille = new int[TAILLE][TAILLE];
 
        for (int i = 0; i < TAILLE; i++) {
            for (int j = 0; j < TAILLE; j++) {
                this.grille[i][j] = tableau[i][j];
            }
        }
    }
 
    // Nombre de possibilité dans une rangée
    private boolean ligne(int r, int n) {
        for (int i = 0; i < TAILLE; i++)
            if (grille1[r][i] == n)
                return true;
 
        return false;
    }
 
    // Nombre de possibilité dans une collone
    private boolean colonne(int c, int n) {
        for (int i = 0; i < TAILLE; i++)
            if (grille1[i][c] == n)
                return true;
 
        return false;
    }
 
    // Nombre de possibilité dans une sous-grille
    private boolean sousGrille(int r, int c, int n) {
        int ligne = r - r % 3;
        int colonne = c - c % 3;
 
        for (int i = ligne; i < ligne + 3; i++)
            for (int j = colonne; j < colonne + 3; j++)
                if (grille1[i][j] == n)
                    return true;
 
        return false;
    }
 
    // On vérifie que le nombre est présent sur une ligne et une colonne et dans une
    // sous-grille
    private boolean x(int r, int c, int n) {
        return !ligne(r, n) && !colonne(c, n) && !sousGrille(r, c, n);
    }
 
    // Méthode de résolution
 
    public boolean solver() {
        for (int ligne = 0; ligne < TAILLE; ligne++) {
            for (int colonne = 0; colonne < TAILLE; colonne++) {
                 
                 
                if (grille1[ligne][colonne] == VIDE) {
                     
                    for (int n = 1; n <= TAILLE; n++) {
                        if (x(ligne, colonne, n)) {
                             
                            grille1[ligne][colonne] = n;
 
                            if (solver()) {
                                return true;
                            } else {
                                grille1[ligne][colonne] = VIDE;
                            }
                        }
                    }
 
                    return false;
                }
            }
        }
 
        return true;
    }
 
    public void affichage() {
        for (int i = 0; i < TAILLE; i++) {
            for (int j = 0; j < TAILLE; j++) {
                System.out.print(" " + grille1[i][j]);
            }
 
            System.out.println();
        }
 
        System.out.println();
    }
     
}


Dans la console j'ai le résultat suivant :

123456789
.6.....3.
.7.....4.
789123456
.........
.........
456789123
.........
.........
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Principale20.main(Principale20.java:33)


Pouvez-vous m'aider s'il vous plait, je m'arrive pas à m'en sortir avec ce script.
A voir également:

7 réponses

KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Bonjour,

Le message d'erreur est assez explicite, faut il encore savoir le lire.
java.lang.ArrayIndexOutOfBoundsException: 0
at Principale20.main(Principale20.java:33)

ArrayIndexOutOfBoundsException est un type d'exception concernant l'accès à une valeur de tableau en dehors des indices possibles. Le 0 qui suit correspond à l'indice incorrect.

Principale20.main correspond aux noms de la classe et de la méthode où s'est produite l'erreur à l'exécution et Principale20.java:33 au fichier de code et au numéro de ligne correspondante.

Il suffit donc d'aller chercher la ligne 33 de Principale20.java, c'est
SudokuTest2 sudo1= new SudokuTest2(args[0]);
qui est effectivement dans la méthode main.

Le problème de tableau à l'indice 0 est donc lié à la valeur
args[0]
qui n'existe pas, ce qui signifie que le tableau
args
est vide alors qu'on devrait avoir une valeur.

Vu le constructeur de SudokuTest2, c'est un nom de fichier qui est attendu, celui que le programme est censé lire.
Au début de ton programme tu as écrit en dur la valeur
"fichier/monSudoku grille1.txt"
pour ce nom de fichier. Je pense que c'est cette valeur là qu'il faudrait remettre aussi en paramètre de ce constructeur.

La ligne 33 à remplacer serait donc :
SudokuTest2 sudo1= new SudokuTest2("fichier/monSudoku grille1.txt");
1
AEROTOWER
 
Après avoir fait la modification que tu m'as donné, j'ai eu le message suivant dans la console :



123456789
.6.....3.
.7.....4.
789123456
.........
.........
456789123
.........
.........
SudokuTest2@15db9742Is legal ?
Is OK ?
Exception in thread "main" java.lang.NullPointerException
at SudokuTest2.solver(SudokuTest2.java:100)
at Principale20.main(Principale20.java:37)
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
À la ligne 100 de SudokuTest2.java tu as
if (grille1[ligne][colonne] == VIDE)
, le NullPointerException signifie que tu as une valeur null dans un contexte qui l'interdit.
En l'occurrence ici tu dois avoir grille1[ligne] qui vaut null (au moins pour une valeur de ligne), donc null[colonne] plante...

Il serait intéressant que tu affiches grille1 pour voir son contenu exact, cela te permettra de trouver où est le null qui pose problème.
System.out.println(java.util.Arrays.deepToString(grille1))
;
0
AEROTOWER
 
Bonjour,

J'ai essayé ce que tu n'as dit, et ça ne fonctionne pas.
Le problème que j'ai c'est que j'aimerais prendre les valeurs dans mon fichier .txt pour ensuite les intégrer dans mon programme. Et c'est là que ça coince.
Je ne sais pas comment faire.
Si tu as une idée, elle serait la bienvenue
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Quel est l'affichage obtenu pour la grille complète (avec le deepToString) au début de la méthode solver ?

    // Méthode de résolution
 
    public boolean solver() {
        System.out.println(java.util.Arrays.deepToString(grille1));
        for (int ligne = 0; ligne < TAILLE; ligne++) {
            for (int colonne = 0; colonne < TAILLE; colonne++) {
0
AEROTOWER
 
J'ai fait quelques modifications sur la méthode main

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Principale20 {

 public static void main(String[] args) throws IOException {
  
  BufferedReader in = new BufferedReader(new FileReader("fichier/monSudoku grille1.txt")); //lieu où ce trouve le fichier .txt

  String line = in.readLine(); //on enregistre les lignes lues dans la variable line

  while (line!= null) { //tant qu'il y a quelque chose dans line on lit

   if( line.startsWith("#")) { //si line commence pas"#" 

    line = in.readLine();//on passe à la ligne suivante

   }else {//sinon

    System.out.println(line);//on écrit la ligne dans la console....ou ailleurs ; )

    line=in.readLine();//on passe à la ligne suivante

   }

  }

  in.close(); //on ferme le lecteur
  
  SudokuTest2 sudoku = new SudokuTest2("fichier/monSudoku grille1.txt");
  System.out.println("Grille à résoudre");
  sudoku.affichage();

  // we try resolution
  if (sudoku.solver()) {
   System.out.println("Solution du Sudoku");
   sudoku.affichage();
  } else {
   System.out.println("Pas de solution pour cette grille");
  
} 

}
}

et avec avec le deepToString au début de la méthode solver, j'obtiens dans la console le résultat suivant :
123456789
.6.....3. 
.7.....4. 
789123456 
......... 
......... 
456789123 
......... 
.........
Grille à résoudre
Exception in thread "main" java.lang.NullPointerException
 at SudokuTest2.affichage(SudokuTest2.java:127)
 at Principale20.main(Principale20.java:34)
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
"avec le deepToString au début de la méthode solver, j'obtiens dans la console le résultat suivant"
Il n'y a pas d'affichage de deepToString dans ce que tu as mis, parce qu'avec ton nouveau main() ton programme plante plus tôt, à cause de la méthode affichage().

Le mieux serait peut-être de mettre le deepToString également au début de la méthode affichage, mais cela renforce bien l'idée que ta grille contient des null...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
AEROTOWER
 
Ma grille de début est la suivante :

# -----------------------
# Fichier grille1.txt 
# -- Exemple de fichier de definition d'une grille
# -----------------------
123456789
.6.....3. 
.7.....4. 
789123456 
......... 
......... 
456789123 
......... 
......... 
#    -------------------------
#    | 1 2 3 | 4 5 6 | 7 8 9 |
#    | . 6 . | . . . | . 3 . |
#    | . 7 . | . . . | . 4 . |
#    -------------------------
#    | 7 8 9 | 1 2 3 | 4 5 6 |
#    | . . . | . . . | . . . |
#    | . . . | . . . | . . . |
#    -------------------------
#    | 4 5 6 | 7 8 9 | 1 2 3 |
#    | . . . | . . . | . . . |
#    | . . . | . . . | . . . |
#    ------------------------- 


Je ne sais vraiment plus quoi faire, rien ne fonctionne dans mon programme
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Vu l'état de ton programme, le mieux est peut-être de tout recommencer avec de meilleures bases

Un début de code, qui permet la lecture du fichier et l'affichage de la grille :

import java.io.IOException;
import java.nio.file.*;
import java.util.Arrays;

public class Sudoku {
    private static final int SIZE = 9;
    private static final String COMMENT_PREFIX = "#";
    private static final int EMPTY = 0;

    private final int[][] values;

    public Sudoku(Path filePath) throws IOException {
        values = Files.lines(filePath).map(String::trim).filter(Sudoku::isLineCorrect).map(Sudoku::readLine).toArray(int[][]::new);
        if (values.length != SIZE)
            throw new IllegalArgumentException(values.length + " lines found, " + SIZE + " expected " + this);
    }

    private static boolean isLineCorrect(final String trimLine) {
        return trimLine.length() == SIZE && !trimLine.startsWith(COMMENT_PREFIX);
    }

    private static int[] readLine(final String trimLine) {
        return trimLine.chars().map(Sudoku::readValue).toArray();
    }

    private static int readValue(int character) {
        return (character >= '1' && character <= '9') ? (character - '0') : EMPTY;
    }

    @Override
    public String toString() {
        return Arrays.deepToString(values);
    }

    public static void main(String[] args) throws IOException {
        System.out.println(new Sudoku(Paths.get("E:/grille1.txt")));
    }
}
0
AEROTOWER
 
Merci beaucoup KX, je vais essayer de continuer mon programme avec le début que tu m'as donné.
J'ai bien pour le moment l'affichage de la grille de sudoku.
0
AEROTOWER
 
Ca y est ! ça a fonctionné !! merci KX !

voici le code :

import java.io.IOException;
import java.nio.file.*;
import java.util.Arrays;

public class SudokuTest3 {
    private static final int SIZE = 9;
    private static final String COMMENT_PREFIX = "#";
    private static final int EMPTY = 0;
    public static final int TAILLE = 9;

    private final int[][] values;
    public SudokuTest3(int[][] tableau) {
  this.values = new int[TAILLE][TAILLE];
  for (int i = 0; i < TAILLE; i++) {
   for (int j = 0; j < TAILLE; j++) {
    this.values[i][j] = tableau[i][j];
   
    }
 }
    }
    
    
    public SudokuTest3(Path filePath) throws IOException {
        values = Files.lines(filePath).map(String::trim).filter(SudokuTest3::isLineCorrect).map(SudokuTest3::readLine).toArray(int[][]::new);
        if (values.length != SIZE)
            throw new IllegalArgumentException(values.length + " lines found, " + SIZE + " expected " + this);
    }

    private static boolean isLineCorrect(final String trimLine) {
        return trimLine.length() == SIZE && !trimLine.startsWith(COMMENT_PREFIX);
    }

    private static int[] readLine(final String trimLine) {
        return trimLine.chars().map(SudokuTest3::readValue).toArray();
    }

    private static int readValue(int character) {
        return (character >= '1' && character <= '9') ? (character - '0') : EMPTY;
    }

    @Override
    public String toString() {
        return Arrays.deepToString(values);
    }

 // Nombre de possibilité dans une rangée
  private boolean ligne(int r, int n) {
   for (int i = 0; i < TAILLE; i++)
    if (values[r][i] == n)
     return true;

   return false;
  }

  // Nombre de possibilité dans une collone
  private boolean colonne(int c, int n) {
   for (int i = 0; i < TAILLE; i++)
    if (values[i][c] == n)
     return true;

   return false;
  }

  // Nombre de possibilité dans une sous-grille
  private boolean sousGrille(int r, int c, int n) {
   int ligne = r - r % 3;
   int colonne = c - c % 3;

   for (int i = ligne; i < ligne + 3; i++)
    for (int j = colonne; j < colonne + 3; j++)
     if (values[i][j] == n)
      return true;

   return false;
  }

  // On vérifie que le nombre est présent sur une ligne et une colonne et dans une
  // sous-grille
  private boolean x(int r, int c, int n) {
   return !ligne(r, n) && !colonne(c, n) && !sousGrille(r, c, n);
  }
    
 // Méthode de résolution

  public boolean solver() {
   for (int ligne = 0; ligne < TAILLE; ligne++) {
    for (int colonne = 0; colonne < TAILLE; colonne++) {
     
     
     if (values[ligne][colonne] == EMPTY) {
      
      for (int n = 1; n <= TAILLE; n++) {
       if (x(ligne, colonne, n)) {
        
        values[ligne][colonne] = n;

        if (solver()) { 
         return true;
        } else { 
         values[ligne][colonne] = EMPTY;
        }
       }
      }

      return false; 
     }
    }
   }

   return true; 
  }

  public void affichage() {
   for (int i = 0; i < TAILLE; i++) {
    for (int j = 0; j < TAILLE; j++) {
     System.out.print(" " + values[i][j]);
    }

    System.out.println();
   }

   System.out.println();
  }
    
    public static void main(String[] args) throws IOException {
 
        SudokuTest3 sudoku = new SudokuTest3(Paths.get("fichier/monSudoku grille1.txt"));
  System.out.println("Grille à résoudre");
  sudoku.affichage();
  
  // we try resolution
  if (sudoku.solver()) {
   System.out.println("Solution du Sudoku");
   sudoku.affichage();
  } else {
   System.out.println("Pas de solution pour cette grille");
    }
 }
}


et j'ai dans la console le résultat suivant :

Grille à résoudre
 1 2 3 4 5 6 7 8 9
 0 6 0 0 0 0 0 3 0
 0 7 0 0 0 0 0 4 0
 7 8 9 1 2 3 4 5 6
 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0
 4 5 6 7 8 9 1 2 3
 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0

Solution du Sudoku
 1 2 3 4 5 6 7 8 9
 5 6 4 8 9 7 2 3 1
 9 7 8 2 3 1 6 4 5
 7 8 9 1 2 3 4 5 6
 2 3 1 5 6 4 8 9 7
 6 4 5 9 7 8 3 1 2
 4 5 6 7 8 9 1 2 3
 3 1 2 6 4 5 9 7 8
 8 9 7 3 1 2 5 6 4
0