[JAVA] Arbre lexicographique, jeu Pendu

80chris Messages postés 18 Statut Membre -  
 80chris -
Bonjour à tous, je suis étudiant en 3ème année d'informatique à Amiens et j'ai a réaliser un projet qui consiste en la création d'un pendu. J'ai comme consigne d'utiliser un arbre lexicographique comme base de donnée afin de stocker mes mots.

Je vous présente donc mon code :

package Model;

import java.io.*;



public class ArbreLexicographique {
	private  Noeud courant;
	private  Noeud tete;
	private char lettre;



	public ArbreLexicographique() {

		Noeud[] fils= new Noeud[30];
		this.tete= new Noeud('\u0000', false, 1, fils);
		this.courant=tete;
		this.RemplirArbre();


	}

	private void ajouterMot(String mot){
		int i, nbFils;
		System.out.println(mot);
		if (mot.equals("")){

			courant.setMot(true);	
			this.courant=tete;
			
			
		}
		else
			lettre=mot.charAt(0);
		if (possedeFils(this.courant.getFils(), this.lettre)){
			i=chercherFils(this.courant.getFils(), this.lettre);
			this.courant = this.courant.getFils()[i];
			System.out.println(mot);
			if (mot.equals("")){

				courant.setMot(true);	
				this.courant=tete;
			}
			else {
				mot=mot.substring(1,mot.length());
				ajouterMot(mot);	
			}
		}
		else {

			nbFils = nbFils(this.courant.getFils());
			Noeud[] fils;
			this.courant.getFils()[nbFils]= new Noeud(lettre, false, this.courant.getNiveau()+1, fils= new Noeud[30]);
			i=chercherFils(this.courant.getFils(), lettre);
			this.courant = this.courant.getFils()[i];
			if (mot.equals("")){

				courant.setMot(true);	
				this.courant=tete;
			}
			else {
				mot=mot.substring(1,mot.length());
				ajouterMot(mot);
			}
		}

	}

	String GenererMotAleatoire() {
		int random, random2, i;
		this.courant=tete;
		char [] mot = null;
		String mot2 = null;
		random=nbAleatoire(1, 6);
		for (i=0; i<random; i++){
			random2=nbAleatoire(0, nbFils(courant.getFils()));
			System.out.println(random2);
			char[] cs = mot;
			cs[i]= courant.getFils()[random2].getLettre();
			if (courant.getFils()[i].isMot()){
				mot2= new String(cs);
			}
			courant= courant.getFils()[random2];
		}
		return mot2;
	}

	private int nbAleatoire(int lower, int higher){
		int random = (int)(Math.random() * (higher-lower)) + lower;
		return random;
	}


	private boolean possedeFils(Noeud[] fils, char c){
		int i;
		Boolean bool=false;
		for (i=0; i<fils.length; i++){
			if(fils[i]== null){
				continue;
			}
			else if(fils[i].getLettre() == c){
				bool=true;
			}
		}
		return bool;
	}

	private int chercherFils(Noeud[] fils, char c){
		int i, j;
		j=0;

		for (i=0; i<fils.length; i++){
			if(fils[i]== null){
				continue;
			}
			else if(fils[i].getLettre() == c){
				j=i;
			}
		}
		return j;
	}

	private int nbFils (Noeud[] fils){
		int i, cpt;
		cpt=0;
		for (i=0; i<fils.length; i++){
			if (fils[i] != null ){
				cpt++;
			}
		}
		return cpt;
	}

	private void RemplirArbre(){
		String fichier ="C:/Documents and Settings/Propriétaire.VIN-1D00C6226C7/Bureau/eclipse-java-indigo-SR1-win32/Pendu/src/Model/dico.txt";


		try{

			InputStream ips=new FileInputStream(fichier); 
			InputStreamReader ipsr=new InputStreamReader(ips);
			BufferedReader br=new BufferedReader(ipsr);
			String ligne;
			int i=0;
			while ((ligne=br.readLine())!=null){
				this.ajouterMot(ligne);
				i++;
				System.out.println(i);
				
			}
			br.close(); 
		}		
		catch (Exception e){
			e.printStackTrace();
		}
	}		


	public Noeud getCourant() {
		return courant;
	}

	public void setCourant(Noeud courant) {
		this.courant = courant;
	}

	public Noeud getTete() {
		return tete;
	}

	public void setTete(Noeud tete) {
		this.tete = tete;
	}

	public char getLettre() {
		return lettre;
	}

	public void setLettre(char lettre) {
		this.lettre = lettre;
	}
}


J'ai un fichier texte contenant tout les mots de la langue francaise. A partir de celui-ci, j'utilise une fonction qui permet de lire le fichier ligne par ligne (voir la fonction remplirArbre()) et d'ajouter le mot correspondant à l'arbre (voir la fonction ajouterMot()). Cependant j'ai un soucis, Dans la fonction qui doit me permettre de générer un mot aléatoirement et qui est stocké dans l'arbre, j'ai une java.lang.NullPointerException. Elle se situe dans la fonction GénererMotAléatoire() à cette ligne :

cs[i]= courant.getFils()[random2].getLettre();


Le noeud en question est vide, c'est pour cela que je ne peux pas appliquer getLettre. Pourtant grâce a Random2 j'ai bien le nombre de fils du noeud père et donc je ne peux pas déborder sur une case suivante du tableau qui serait à null.

Je pense donc que le problème vient de l'ajout des mots qui ne se fait pas comme je le souhaite. J'ai essayer de faire des modifications mais sans succès, j'aimerais bien un petit coup de main.
A voir également:

3 réponses

KX Messages postés 19031 Statut Modérateur 3 020
 
J'avoue, je n'ai pas lu tout le code (je le ferais peut-être plus tard si ça coince toujours), mais dans un premier temps essaye ceci pour identifier le problème :

try
{
    cs[i]= courant.getFils()[random2].getLettre();
}
catch (NullPointerException e)
{
     System.err.println("courant = "+courant);
     System.err.println("Fils = "+courant.getFils());
     System.err.println("random2 = "+random2);
     System.err.println("random2 = "+random2);
     System.err.println("[] = "+courant.getFils()[random2]);
     System.err.println("lettre = "+courant.getFils()[random2].getLettre());
}

C'est normal que ça plante encore, mais le point intéressant est de savoir quel affichage est effectué juste avant le message d'erreur.
1
80chris Messages postés 18 Statut Membre
 
J'ai ce résultat :

courant = Model.Noeud@cdfc9c
Fils = [LModel.Noeud;@1837697
random2 = 4
random2 = 4
[] = Model.Noeud@1decdec
lettre = s


Pour courant et fils c'est assez bizarre comme renvoie ou non ?
0
80chris Messages postés 18 Statut Membre
 
Donc le getLettre renvoie bien une valeur
0
KX Messages postés 19031 Statut Modérateur 3 020
 
Pour l'affichage c'est normal, c'est parce que la méthode toString n'a pas été redéfinie dans la classe Noeud. Par contre ce qui est bizarre, c'est qu'il ne semble pas que ça plante ici...
Est-ce que ce ne serait pas "cs" qui vaudrait null alors ?
0
80chris Messages postés 18 Statut Membre > 80chris Messages postés 18 Statut Membre
 
J'ai changer la valeur de mon tableau. Je lui est affecté 30 cases pour dire être large. Et je n'ai plus d'erreur. C'était un oubli idiot en fait. Merci !
0
80chris Messages postés 18 Statut Membre
 
Il n'empeche que mon générerAléatoire est pas bon. 1 fois sur 3 j'ai une exception qui se lance.

Je récupère ceci lors d'une erreur :

courant = Model.Noeud@1837697
Fils = [LModel.Noeud;@1decdec
random2 = 0
random2 = 0
[] = null
0
80chris Messages postés 18 Statut Membre
 
Ma structure de donnée est un arbre lexicographique, chaque noeud contiendra une lettre et leur fils les lettres suivantes. En suivant un chemin et en ajoutant les lettres on obtient un mot. Pour modéliser ca, j'ai créer un type Noeud qui a comme attribut
un char, et un tableau de Noeud qui permettra de stocker les fils.

package Model;



public class Noeud {
	private char lettre;
	private boolean mot;
	int Niveau;
	
	private Noeud[] fils;

	public Noeud[] getFils() {
		return fils;
	}
	public void setFils(Noeud[] fils) {
		this.fils = fils;
	}
	public Noeud(char lettre, boolean mot, int niveau, Noeud[] fils) {
		this.lettre = lettre;
		this.mot = mot;
		this.Niveau = niveau;
		this.fils=fils;
			}
	public char getLettre() {
		return lettre;
	}
	public void setLettre(char lettre) {
		this.lettre = lettre;
	}
	public boolean isMot() {
		return mot;
	}
	public void setMot(boolean mot) {
		this.mot = mot;
	}
	public int getNiveau() {
		return Niveau;
	}
	public void setNiveau(int niveau) {
		Niveau = niveau;
	}
	
	


}
0
80chris
 
J'ai apporté quelques améliorations à mon code mais j'ai de nouveaux des problèmes. J'ai de nouveau une NullPointerException :

<code type="java">Exception in thread "main" java.lang.NullPointerException
at Model.ArbreLexicographique.GenererMotAleatoire(ArbreLexicographique.java:94)
at Model.Word.initWord(Word.java:17)
at Model.Word.<init>(Word.java:13)
at Model.Model.<init>(Model.java:23)
at Vue.Main.main(Main.java:20)
</code>

J'ai fais des changements dans ma classe arbre et noeud :

package Model;

import java.io.*;



public class ArbreLexicographique {
	private  Noeud courant;
	private  Noeud tete;
	private char lettre;



	public ArbreLexicographique() {

		Noeud[] fils= new Noeud[30];
		this.tete= new Noeud('\u0000', false, 1, fils);
		this.courant=tete;
		this.RemplirArbre();


	}

	private void ajouterMot(String mot){
		int i, nbFils;
		System.out.println(mot);
		if (mot.equals("")){

			courant.setMot(true);	
			this.courant=tete;


		}
		else {
			lettre=mot.charAt(0);
			if (possedeFils(this.courant.getFils(), this.lettre)){
				System.out.println("le noeud "+courant+" possède un fils qui contient la lettre "+lettre);
				i=chercherIndiceFils(this.courant.getFils(), this.lettre);
				this.courant = this.courant.getFils()[i];
				if (!(mot.equals(""))){
					mot=mot.substring(1,mot.length());
					ajouterMot(mot);

				}
				else {
					courant.setMot(true);	
					this.courant=tete;
				}
			}
			else {
				System.out.println("le noeud "+courant+" ne possède pas de fils qui contient la lettre "+lettre);
				nbFils = nbFils(this.courant.getFils());
				Noeud[] fils;
				courant.addNoeud(new Noeud(lettre, false, this.courant.getNiveau()+1, fils= new Noeud[26]));
				i=chercherIndiceFils(this.courant.getFils(), lettre);
				this.courant = this.courant.getFils()[i];
				if (!(mot.equals(""))){
					mot=mot.substring(1,mot.length());
					ajouterMot(mot);

				}
				else {
					courant.setMot(true);	
					this.courant=tete;
				}
			}
		}

	}

	String GenererMotAleatoire() {
		int random, random2, i;
		this.courant=tete;
		String mot2 = null;
		random=nbAleatoire(7, 7);
		System.out.println("la taille alétoire du mot choisi est "+random);
		for (i=0; i<random; i++){
			random2=nbAleatoire(0, nbFils(courant.getFils()));
			System.out.println("le noeud courant possede " +nbFils(courant.getFils())+" fils" );
			System.out.println("le fils choisit dans le tableau est le fils "+random2);
			char[] cs = new char[random];
			try {
				cs[i]= courant.getFils()[i].getLettre();
			}
			catch (NullPointerException e)
			{
				System.err.println("courant = "+courant);
				System.err.println("Fils = "+courant.getFils());
				System.err.println("random = "+random);
				System.err.println("random2 = "+random2);
				System.err.println("[] = "+courant.getFils()[random2]);
				/*System.err.println("lettre = "+courant.getFils()[random2].getLettre());*/
			}
			if (courant.getFils()[i].isMot()){
				mot2= new String(cs);
			}
			courant= courant.getFils()[random2];
		}
		return mot2;
	}

	private int nbAleatoire(int lower, int higher){
		int random = (int)(Math.random() * (higher-lower)) + lower;
		return random;
	}

	private boolean estDansArbre (String mot){
		boolean est=false;
		int i;

		if ("".equals(mot) && (courant.isMot()==true)) {
			est=true;
		}
		else {
			if (courant.isMot()==false){
				courant.setMot(true);
				est=true;
			}
			else{
				lettre=mot.charAt(0);
				mot=mot.substring(1,mot.length());
			}
			if (possedeFils(courant.getFils(), lettre)){
				i=chercherIndiceFils(courant.getFils(), lettre);
				courant = courant.getFils()[i];
				estDansArbre(mot);
			}
			else
				est=false;
		}
		return est;
	}

	private boolean possedeFils(Noeud[] fils, char c){
		int i;
		Boolean bool=false;
		for (i=0; i<fils.length; i++){
			if(fils[i]== null){
				continue;
			}
			else if(fils[i].getLettre() == c){
				bool=true;
			}
		}
		System.out.println("la lettre "+c+" vaut "+bool+" dans le tableau "+fils);
		return bool;
	}

	private int chercherIndiceFils(Noeud[] fils, char c){
		int i, j;
		j=0;

		for (i=0; i<fils.length; i++){
			if(fils[i]== null){
				continue;
			}
			else if(fils[i].getLettre() == c){
				j=i;
			}
		}
		return j;
	}

	private int nbFils (Noeud[] fils){
		int i, cpt;
		cpt=0;
		for (i=0; i<fils.length; i++){
			if (fils[i] != null ){
				cpt++;
			}
		}
		return cpt;
	}

	private void RemplirArbre(){
		String fichier ="C:/Documents and Settings/Propriétaire.VIN-1D00C6226C7/Bureau/eclipse-java-indigo-SR1-win32/Pendu/src/Model/dico.txt";


		try{

			InputStream ips=new FileInputStream(fichier); 
			InputStreamReader ipsr=new InputStreamReader(ips);
			BufferedReader br=new BufferedReader(ipsr);
			String ligne;
			int i=0;
			while ((ligne=br.readLine())!=null){
				this.ajouterMot(ligne);
				i++;
				System.out.println("ajout du mot numero "+i);

			}
			br.close(); 
		}		
		catch (Exception e){
			e.printStackTrace();
		}
	}		


	public Noeud getCourant() {
		return courant;
	}

	public void setCourant(Noeud courant) {
		this.courant = courant;
	}

	public Noeud getTete() {
		return tete;
	}

	public void setTete(Noeud tete) {
		this.tete = tete;
	}

	public char getLettre() {
		return lettre;
	}

	public void setLettre(char lettre) {
		this.lettre = lettre;
	}
}


Classe Noeud

package Model;



public class Noeud {
	private char lettre;
	private boolean mot;
	int Niveau;
	int nbNoeud;

	private Noeud[] fils;

	public Noeud[] getFils() {
		return fils;
	}
	public void setFils(Noeud[] fils) {
		this.fils = fils;
	}
	public Noeud(char lettre, boolean mot, int niveau, Noeud[] fils) {
		this.lettre = lettre;
		this.mot = mot;
		this.Niveau = niveau;
		this.fils=fils;
		this.nbNoeud=0;
	}

	public void addNoeud(Noeud noeud) { 
		if (nbNoeud >= fils.length) throw new RuntimeException("On ne peut plus ajouter de noeuds"); 
		this.fils[nbNoeud++] = noeud; 
	}

	public Noeud getNoeud(int i) { 
		if (i > nbNoeud) 
			throw new RuntimeException("plop"); 
		return fils[i]; 
	}
	public char getLettre() {
		return lettre;
	}
	public void setLettre(char lettre) {
		this.lettre = lettre;
	}
	public boolean isMot() {
		return mot;
	}
	public void setMot(boolean mot) {
		this.mot = mot;
	}
	public int getNiveau() {
		return Niveau;
	}
	public void setNiveau(int niveau) {
		Niveau = niveau;
	}




}


J'aimerais bien un petit coup de main si possible. Je pense avoir presque fini mon pendu. Il faut juste que le remplissage des mots dans l'arbre soit correct.

Merci d'avance ! ;)
0