Partage
  • Partager sur Facebook
  • Partager sur Twitter

Débutant en Java - Elaboration d'un programme

Sudoku

8 mai 2020 à 14:15:18

Bonjour,

Je suis débutante dans la programmation, et j'ai un Tp à rendre.

Je dois élaborer un programme en Java permettant de remplir n'importe quelle grille de Sudoku définie à partir d'un fichier texte 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();
	}
	
}

et il affiche : 

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 suis totalement bloquée.

-
Edité par Maggy83 10 mai 2020 à 12:45:31

  • Partager sur Facebook
  • Partager sur Twitter
9 mai 2020 à 15:30:00

Salut,

Tu lis le fichier dans la méthode main ou dans la classe SudokuTest2 ? Il faut choisir.

  • Partager sur Facebook
  • Partager sur Twitter
9 mai 2020 à 15:32:46

Bonjour,

Mauvais titre

Le titre est un élément important qui ne doit pas être négligé. N'oubliez pas cette règle simple : le titre idéal résume la question que vous allez poser en une petite phrase. Il doit permettre aux visiteurs de se repérer facilement dans le forum visité et d'identifier le sujet à sa seule lecture.

Vous pouvez utiliser divers préfixes comme [Erreur], [MySQL], [Compatibilité], etc... Aussi, pensez à consulter les règles propres à chaque forum (visibles dans les topics épinglés en haut des sections).

De plus, choisir un bon titre permet de rendre plus faciles les recherches des autres membres.

Les titres de type "besoin d'aide" ou "problème" ne sont pas tolérés.

Pour modifier votre titre, éditez le premier message de votre sujet.

(titre originel : Problème Débutant en Java)

Liens conseillés

  • Partager sur Facebook
  • Partager sur Twitter
9 mai 2020 à 19:13:13

Ton code est un peu spécial, au départ tu lis le fichier mais tu ne stock pas le contenu du fichier à chaque fois ta variable line est écrasée par la valeur de la ligne suivante. Et après une fois ton fichier lu, tu prend le premier argument passé au programme, qui n’existe pas d'ou l’erreur.
  • Partager sur Facebook
  • Partager sur Twitter
10 mai 2020 à 12:49:16

Bonjour,

J'ai essayé de retravailler mon code après les conseils que vous m'avez donnés, mais je n'y parviens 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.

C'est là que ça coince ; je ne sais pas comment faire.

Votre aide serait la bienvenue.

  • Partager sur Facebook
  • Partager sur Twitter
10 mai 2020 à 15:31:19

Il faut modifier ton constructeur pour qu'il appelle le readGrilleFromFile :

    public SudokuTest2(String nomDeFichier){
        this.readGrilleFromFile(nomDeFichier);
    }

Par contre il faut appeler ton programme avec le nom du fichier en argument.

Tout ce qui est au début de ta méthode main tu peux le virer.

  • Partager sur Facebook
  • Partager sur Twitter
10 mai 2020 à 16:41:34

J'ai modifié mon constructeur comme tu me l'as suggéré.

Et j'ai donc fait des modifications dans la méthode main 

import java.io.IOException;

public class Principale20 {

	public static void main(String[] args) throws IOException {
		
		

		
		
		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 j'ai obtenu le message suivant dans la console :

Exception in thread "main" java.lang.NumberFormatException: For input string: "#"
	at java.lang.NumberFormatException.forInputString(Unknown Source)
	at java.lang.Integer.parseInt(Unknown Source)
	at java.lang.Integer.parseInt(Unknown Source)
	at SudokuTest2.readGrilleFromFile(SudokuTest2.java:29)
	at SudokuTest2.<init>(SudokuTest2.java:13)
	at Principale20.main(Principale20.java:12)




-
Edité par Maggy83 10 mai 2020 à 16:41:59

  • Partager sur Facebook
  • Partager sur Twitter
10 mai 2020 à 17:01:40

Tu as des # dans ton fichier, donc quand il essaie de lire un chiffre avec Integer.parseInt il jette une exception c'est normal.

Utilises le code qui était dans ton main au début pour éliminer les lignes avec des # en le rajoutant dans readGrilleFromFile :

 
            if( line.startsWith("#")) { //si line commence pas"#"
 
                line = in.readLine();//on passe à la ligne suivante
 
            }else {//sinon



  • Partager sur Facebook
  • Partager sur Twitter
10 mai 2020 à 17:21:40

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 |

#    | . . . | . . . | . . . |

#    | . . . | . . . | . . . |

#    ------------------------- 


J'ai remis dans la méthode main, le code pour éliminer les #

Ca ne fonctionne toujours pas ...


J'arrive à lire mon fichier .txt, mais pas à l'intégrer dans mon programme

-
Edité par Maggy83 10 mai 2020 à 17:23:56

  • Partager sur Facebook
  • Partager sur Twitter
10 mai 2020 à 18:12:53

Mais non pas remettre le code dans la méthode main...

Il ne servira à rien ce code dans main puisque après tu ne te sers pas du résultat.

C'est dans la méthode readGrilleFromFile qu'il faut le mettre car c'est elle qui fait le travail...

  • Partager sur Facebook
  • Partager sur Twitter
10 mai 2020 à 19:32:20

Dans la méthode main j'ai mis :

import java.io.BufferedReader;
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");
		
}	

}
}

Ce n 'est pas ça ?

  • Partager sur Facebook
  • Partager sur Twitter
10 mai 2020 à 20:40:24

Non écoute moi bien :

1) dans ton code (la dernière version) tu fais des trucs avec ton fichier, et tu récupères une ligne dans la variable ligne (ligne par ligne). Mais tu ne t'en sers plus après ! Ca ne sert à rien...

Il vaut mieux que tout ton code concernant la lecture du fichier soit dans readGrilleFromFile.

2) Il y a quand même quelque chose d'intéressant dans le début de ton main : le if ... startsWith ... else , qui permet d'éliminer les lignes avec les #. Ca, tu veux le garder pour résoudre ton problème de #. Donc déplace-le dans le code de readGrilleFromFile.

Comme ça (à adapter, je l'ai pas testé) :

    // 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) {
				
				if( line.startsWith("#")) { //si line commence pas"#"
  
					line = in.readLine();//on passe à la ligne suivante
	  
				}else {//sinon
	  
					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...");
        }
      
    }



  • Partager sur Facebook
  • Partager sur Twitter
12 mai 2020 à 18:04:11

Bonjour,

Merci beaucoup FredLass pour ton aide.

J'ai essayé de faire les modifications que tu as apporté à mon programme en l'adaptant ensuite, sans succès.

Du coup j'ai recommencé à zéro et j'ai réussi (avec de l'aide). Mon nouveau programme fonctionne.

  • Partager sur Facebook
  • Partager sur Twitter
11 mai 2023 à 11:56:21

Bonjour @Maggy83,

Je suis intéressé par ton programme est ce que tu voudrais bien le partager avec moi stp ? 

Merci d'avance

-
Edité par ssaranya93420 11 mai 2023 à 11:57:25

  • Partager sur Facebook
  • Partager sur Twitter
11 mai 2023 à 12:01:48

Bonjour,

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération
  • Partager sur Facebook
  • Partager sur Twitter