[Resolu][MY-AL]Recherche de mots dans dico

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par EmileF » 27 Jan 2020 14:20

Tu as répondu très vite, j'ai éditer mon précédent message.

Il me semble que tu changes de direction dès qu'il y a un mot de trouvé
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

djulio74
Messages : 682
Inscription : 19 Déc 2009 22:55

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par djulio74 » 27 Jan 2020 14:28

alors pour le coup des -1, vérifie ton dico.txt, tu dois avoir une ligne vide à la fin, je crois que je l'ai effacé dans le miens.

copie colle le code

Code : Tout sélectionner

using System;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using System.IO;

public class TestMots : MonoBehaviour
{

	private string DICOpath = "C:/Users/djuli/Documents/dico.txt";

	private string[] Dictionnaire;
	private int[][] DicoNumérique;
	private int[] MotsFinal;
	private int MotsFinalCount;
	private string[] MotsFinalString;

	private int TailleGrille = 5;
	private int[] grille;
	private int[] dir;
	private char[] Alpha;
	private int Scroll;
	private int selectionGridInt = 0;


	void Start ()
	{
		InitialiseGrille ();
		InitialiseDico ();
		//PrintGrille ();
		RechercheMot ();
	}

	void Update ()
	{

		if (Input.GetKeyDown ("r")) {
			float tp = Time.realtimeSinceStartup;
			RechercheMot ();
			tp = Time.realtimeSinceStartup - tp;
			print (tp);
			// print les motes trouvés
			for (int i = 0; i < MotsFinalCount; i++) {
				print (Dictionnaire [MotsFinal [i]]);
			}
		}
	}

	void OnGUI (){

		Scroll = (int) GUI.VerticalScrollbar( new Rect( 25,25,20,Screen.height-50), Scroll, 5,0,MotsFinalCount);

		for ( int i = 0 ; i < TailleGrille*TailleGrille ; i ++){
			float startX = Screen.width/2 - TailleGrille*25;
			float startY = Screen.height/2 - TailleGrille*25;
			int ligne = i % TailleGrille ;
			int colonne = i / TailleGrille ;

			GUI.Box (new Rect (ligne*50+startX, colonne*50 +startY ,50,50),  char.ToUpper (Alpha [grille [i] - 1]).ToString () + " , " + i  ) ;

		}

		for ( int i = 0 ; i < MotsFinalCount ; i ++){
			if( (i-Scroll)*27.0f +25.0f > 0 && (i-Scroll)*27.0f +25.0f< Screen.height){				
				GUI.Box (new Rect (50, (i-Scroll)*27.0f +25.0f ,200,25), Dictionnaire[ MotsFinal[i]]);
			}
		}


	}

	void InitialiseGrille ()
	{

		grille = new int[TailleGrille * TailleGrille];
		char[] A = "ANTICONSTITUTIONNELLEMENT".ToCharArray ();
		for (int i = 0; i < TailleGrille; i++) {
			for (int j = 0; j < (TailleGrille + 1) / 2; j++) {
				grille [i + 2 * j * TailleGrille] = char.ToUpper (A [i + 2 * j * TailleGrille]) - 64;
			}
		}
		for (int i = 0; i < TailleGrille; i++) {
			for (int j = 0; j < TailleGrille / 2; j++) {
				grille [(j + 1) * 2 * TailleGrille - 1 - i] = char.ToUpper (A [(2 * j + 1) * TailleGrille + i]) - 64;
			}
		}
		dir = new int[8] {
			1,
			1 + TailleGrille,
			TailleGrille,
			TailleGrille - 1,
			-1,
			-1 - TailleGrille,
			-TailleGrille,
			1 - TailleGrille
		};

		Alpha = "abcdefghijklmnopqrstuvwxyzé".ToCharArray ();
	}

	void InitialiseDico ()
	{

		if (File.Exists (DICOpath) == true) {
			StreamReader dico = File.OpenText (DICOpath);
			Dictionnaire = dico.ReadToEnd ().Split ("\n" [0]);
			Debug.LogError ("Dictionnaire trouvé  :" + Dictionnaire.Length + " mots");
		} else {
			Debug.LogError ("Attention dictionnaire non trouvé");
			return;
		}
		DicoNumérique = new int[Dictionnaire.Length][];
		for (int i = 0; i < Dictionnaire.Length; i++) {
			DicoNumérique [i] = new int[Dictionnaire [i].Length - 1];
			for (int j = 0; j < Dictionnaire [i].Length - 1; j++) {
				DicoNumérique [i] [j] = char.ToUpper (Dictionnaire [i] [j]) - 64;
			}
		}
	}

	void PrintGrille ()
	{
		for (int i = 0; i < TailleGrille; i++) {	
			string ligne = "";
			for (int j = 0; j < TailleGrille; j++) {
				ligne += char.ToUpper (Alpha [grille [i * TailleGrille + j] - 1]).ToString () + " ";
			}
			print (ligne);
		}
	}

	void RechercheMot ()
	{
		MotsFinal = new int[10];
		MotsFinalCount = 0;
		int[] MotsBase = new int[DicoNumérique.Length];
		for (int i = 0; i < MotsBase.Length; i++) {
			MotsBase [i] = i;
		}

		for (int i = 0; i < grille.Length; i++) {			
			MotAvecLettre (0, i, MotsBase);
		}

		MotsFinalString = new string[MotsFinalCount];
		for ( int i = 0 ; i < MotsFinalCount ; i++){
			MotsFinalString[i]  = Dictionnaire[MotsFinal[i]];
		}
	}
	void RechercheMotButton (int Case)
	{
		MotsFinal = new int[10];
		MotsFinalCount = 0;
		int[] MotsBase = new int[DicoNumérique.Length];
		for (int i = 0; i < MotsBase.Length; i++) {
			MotsBase [i] = i;
		}

		MotAvecLettre (0, Case, MotsBase);


		MotsFinalString = new string[MotsFinalCount];
		for ( int i = 0 ; i < MotsFinalCount ; i++){
			MotsFinalString[i]  = Dictionnaire[MotsFinal[i]];
		}
	}

	void MotAvecLettre (int pos, int Case, int[] mots)
	{
		int MotsTrouvésCount = 0;
		int[] MotsTrouvés = new int[mots.Length];
		int lettre = grille [Case];

		for (int i = 0; i < mots.Length; i++) {
			if (DicoNumérique [mots [i]].Length > pos && DicoNumérique [mots [i]] [pos] == lettre) {
				MotsTrouvés [MotsTrouvésCount] = mots [i];
				MotsTrouvésCount++;
			}
			if (DicoNumérique [mots [i]].Length == pos + 1 && DicoNumérique [mots [i]] [pos] == lettre) {
				
				MotsFinal [MotsFinalCount] = mots [i];
				MotsFinalCount += 1;
				if (MotsFinal.Length == MotsFinalCount) {
					Array.Resize (ref MotsFinal, MotsFinalCount + 10);
				}
			}
		}
		Array.Resize (ref MotsTrouvés, MotsTrouvésCount);

		if (MotsTrouvésCount > 0) {
			
			for (int i = 0; i < dir.Length; i++) {
				int CaseSuivante = Case + dir [i];
				int colonne = (Case) % TailleGrille + dir [i] % TailleGrille;
				int ligne = (CaseSuivante) / TailleGrille;

				if ( ligne >= 0 && ligne < TailleGrille && colonne >= 0 && colonne < TailleGrille && CaseSuivante >= 0 && CaseSuivante < TailleGrille * TailleGrille) {
					MotAvecLettre (pos + 1, CaseSuivante, MotsTrouvés);
				
				}
			}
		}
	}
}
et verifie juste que t'ai pas de ligne vide dans ton dico. normalement ça affiche la grille à l'ecrn, avec les lettres et l'index de la case de la grille, et la liste des mots avec slider.
mais toujours l'erreur des mots en double.

PS : avec ce script tel quel, et ton fichier dico.txt, ça devrait te trouver tout les mots, même long.

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par EmileF » 27 Jan 2020 14:44

Super, c'est incroyable la différence de temps.

J'ai collé-copié ton code et juste modifié pour utiliser le TextAsset

Code : Tout sélectionner

    
    public TextAsset dico;
    
    void InitialiseDico()
    {

        //if (File.Exists(DICOpath) == true)
        //{
        //    StreamReader dico = File.OpenText(DICOpath);
        //    Dictionnaire = dico.ReadToEnd().Split("\n"[0]);
        //    Debug.LogError("Dictionnaire trouvé  :" + Dictionnaire.Length + " mots");
        //}
        //else
        //{
        //    Debug.LogError("Attention dictionnaire non trouvé");
        //    return;
        //}

        Dictionnaire = dico.text.Split("\n"[0]);

        DicoNumérique = new int[Dictionnaire.Length][];
        for (int i = 0; i < Dictionnaire.Length; i++)
        {
            DicoNumérique[i] = new int[Dictionnaire[i].Length - 1];
            for (int j = 0; j < Dictionnaire[i].Length - 1; j++)
            {
                DicoNumérique[i][j] = char.ToUpper(Dictionnaire[i][j]) - 64;
            }
        }
    }
Tout marche bien et j'ai tous les mots

Il y a toujours des doubles, mais je pense que ce doit être du au fait que plusieurs mots peuvent se lire a partir de directions différentes.

Par contre avec ta méthode ça devient plutôt difficile de rechercher si un mot existe déjà dans la liste, non?
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

djulio74
Messages : 682
Inscription : 19 Déc 2009 22:55

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par djulio74 » 27 Jan 2020 14:50

Les mots en double sont en partie à cause il arrive que ça passe d'un bord à l'autre opposé de la grille, je regarde ça ce soir.
Idem pour retrouver les mots en double s'il en reste, c'est tout "bête" lol

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par EmileF » 27 Jan 2020 15:01

Djulio a écrit :Idem pour retrouver les mots en double s'il en reste, c'est tout "bête" lol
Ca c'est vrai :mrgreen: :mrgreen:

J'ai ajouté une petite fonction pour éliminer les doubles:

Code : Tout sélectionner

    
    private bool VerifieSiUnique(int mot)
    {
        for (int j = 0; j < MotsFinalCount; j++)
        {
            if (MotsFinal[j] == mot)
            {
                return false;
            }
        }
        return true;
    }
Ca marche, mais Il en reste encore, ce sont des doubles qui sont dans le dico.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par EmileF » 27 Jan 2020 15:44

Voilà, avec cette ligne au chargement du dico on élimine les doublons

Code : Tout sélectionner

        
        Dictionnaire = dico.text.Split("\n"[0]).ToList().Distinct().ToArray();
Il est possible qu'on ajoute une petite seconde, mais il n'y a pas de fumée sans feu.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par EmileF » 27 Jan 2020 15:50

Denier petit point Ce 'c' qui se promène par la sans raison, en fait,
il était dans le dico entre adamantin et adamantine.
Va savoir ce qu'il foutait là :rougefaché:

He bien maintenant, je vais adapter ton script à mon jeu, et je peux enlever ma barre de progression.

Merci Djulio
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

djulio74
Messages : 682
Inscription : 19 Déc 2009 22:55

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par djulio74 » 27 Jan 2020 20:04

Bon allé une derniere petite mise a jour.
En fait dans le recherche de la case suivante, on pouvait passer de la 0 à la 4 (donc début de ligne à fin de même ligne), et l’erreur était là.
J'ai donc changé l'array de la direction qui était des int pour avoir juste la case suivante par des vector2int qui donnent directement le changement de colonne et de ligne pour savoir si on est bien dans la grille.
J'ai aussi tout comme toi ajouté une condition pour l'ajout des doublons. En plus que ce soit des doublons dans le dico, ce sont aussi des doublons car il y a plusieurs façon d’écrire un seul mot en se promenant sur la grille.

J'ai aussi rajouté la possibilité de trouver juste le mots a partir d'une seule case de la grille, en cliquant dessus, et le bouton "rechercher tout" au lieu de presser "r".

As-tu vu aussi qu'en ajoutant asssez de lettre a "A" dans initialisegrille() tu pouvait augmenter la taille de la grille, tant que le nombre de lettre de "A" est supérieur ou égale a tailleGrille x tailleGrille? ;)

Code : Tout sélectionner

using System;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using System.IO;

public class TestMots : MonoBehaviour
{

	private string DICOpath = "C:/Users/djuli/Documents/dico.txt";

	private string[] Dictionnaire;
	private int[][] DicoNumérique;
	private int[] MotsFinal;
	private int MotsFinalCount;
	private string[] MotsFinalString;

	private int TailleGrille = 5;
	private int[] grille;
	private Vector2Int[] dir;
	private char[] Alpha;
	private int Scroll;

	void Start ()
	{
		InitialiseGrille ();
		InitialiseDico ();
		RechercheMot ();
	}		

	void OnGUI (){

		Scroll = (int) GUI.VerticalScrollbar( new Rect( 25,25,20,Screen.height-50), Scroll, 5,0,MotsFinalCount);
		float startX = Screen.width/2 - TailleGrille*25;
		float startY = Screen.height/2 - TailleGrille*25; 

		for ( int i = 0 ; i < TailleGrille*TailleGrille ; i ++){
			
			int colonne = i % TailleGrille ;
			int ligne = i / TailleGrille ;

			if(GUI.Button (new Rect (colonne*50+startX, ligne*50 +startY ,50,50),  char.ToUpper (Alpha [grille [i] - 1]).ToString () + " , " + i  ) ){
				RechercheMotButton(i);
			}
		}

		for ( int i = 0 ; i < MotsFinalCount ; i ++){
			if( (i-Scroll)*27.0f +25.0f > 10 && (i-Scroll)*27.0f +25.0f< Screen.height-50){				
				GUI.Box (new Rect (50, (i-Scroll)*27.0f +25.0f ,200,25), Dictionnaire[ MotsFinal[i]]);
			}
		}

		if(GUI.Button (new Rect (startX, startY+TailleGrille*50+10 ,TailleGrille*50,30),  "RECHERCHER TOUT"  ) ){
			RechercheMot();
		}
	}

	void InitialiseGrille ()
	{

		grille = new int[TailleGrille * TailleGrille];
		char[] A = "ANTICONSTITUTIONNELLEMENTANTICONSTITUTIONNELLEMENT".ToCharArray ();
		for (int i = 0; i < TailleGrille; i++) {
			for (int j = 0; j < (TailleGrille + 1) / 2; j++) {
				grille [i + 2 * j * TailleGrille] = char.ToUpper (A [i + 2 * j * TailleGrille]) - 64;
			}
		}
		for (int i = 0; i < TailleGrille; i++) {
			for (int j = 0; j < TailleGrille / 2; j++) {
				grille [(j + 1) * 2 * TailleGrille - 1 - i] = char.ToUpper (A [(2 * j + 1) * TailleGrille + i]) - 64;
			}
		}
		dir = new Vector2Int[8]{
			new Vector2Int(1,0),
			new Vector2Int(1,1),
			new Vector2Int(0,1),
			new Vector2Int(-1,1),
			new Vector2Int(-1,0),
			new Vector2Int(-1,-1),
			new Vector2Int(0,-1),
			new Vector2Int(1,-1)
		};

		Alpha = "abcdefghijklmnopqrstuvwxyzé".ToCharArray ();
	}

	void InitialiseDico ()
	{

		if (File.Exists (DICOpath) == true) {
			StreamReader dico = File.OpenText (DICOpath);
			Dictionnaire = dico.ReadToEnd ().Split ("\n" [0]);
			Debug.LogError ("Dictionnaire trouvé  :" + Dictionnaire.Length + " mots");
		} else {
			Debug.LogError ("Attention dictionnaire non trouvé");
			return;
		}
		DicoNumérique = new int[Dictionnaire.Length][];
		for (int i = 0; i < Dictionnaire.Length; i++) {
			DicoNumérique [i] = new int[Dictionnaire [i].Length - 1];
			for (int j = 0; j < Dictionnaire [i].Length - 1; j++) {
				DicoNumérique [i] [j] = char.ToUpper (Dictionnaire [i] [j]) - 64;
			}
		}
	}

	void RechercheMot ()
	{
		MotsFinal = new int[10];
		MotsFinalCount = 0;
		int[] MotsBase = new int[DicoNumérique.Length];
		for (int i = 0; i < MotsBase.Length; i++) {
			MotsBase [i] = i;
		}

		for (int i = 0; i < grille.Length; i++) {			
			MotAvecLettre (0, i, MotsBase);
		}

		MotsFinalString = new string[MotsFinalCount];
		for ( int i = 0 ; i < MotsFinalCount ; i++){
			MotsFinalString[i]  = Dictionnaire[MotsFinal[i]];
		}
	}
	void RechercheMotButton (int Case)
	{
		MotsFinal = new int[10];
		MotsFinalCount = 0;
		int[] MotsBase = new int[DicoNumérique.Length];
		for (int i = 0; i < MotsBase.Length; i++) {
			MotsBase [i] = i;
		}

		MotAvecLettre (0, Case, MotsBase);

		MotsFinalString = new string[MotsFinalCount];
		for ( int i = 0 ; i < MotsFinalCount ; i++){
			MotsFinalString[i]  = Dictionnaire[MotsFinal[i]];
		}
	}

	void MotAvecLettre (int pos, int Case, int[] mots)
	{
		int MotsTrouvésCount = 0;
		int[] MotsTrouvés = new int[mots.Length];
		int lettre = grille [Case];

		for (int i = 0; i < mots.Length; i++) {
			if (DicoNumérique [mots [i]].Length > pos && DicoNumérique [mots [i]] [pos] == lettre) {
				MotsTrouvés [MotsTrouvésCount] = mots [i];
				MotsTrouvésCount++;
			}
			if (DicoNumérique [mots [i]].Length == pos + 1 && DicoNumérique [mots [i]] [pos] == lettre) {
				bool exist = false;
				for ( int c = 0 ; c < MotsFinalCount ; c ++){
					if ( MotsFinal[c] == mots[i]){
						exist = true;
					}
				}
				if ( exist == false){
					MotsFinal [MotsFinalCount] = mots [i];
					MotsFinalCount += 1;
					if (MotsFinal.Length == MotsFinalCount) {
						Array.Resize (ref MotsFinal, MotsFinalCount + 10);
					}
				}
			}
		}
		Array.Resize (ref MotsTrouvés, MotsTrouvésCount);

		if (MotsTrouvésCount > 0) {

			for (int i = 0; i < dir.Length; i++) {
				
				int colonne = Case % TailleGrille + dir [i].y;
				int ligne = Case / TailleGrille + dir[i].x;
				int CaseSuivante = colonne + ligne*TailleGrille;

				if (ligne >= 0 && ligne < TailleGrille && colonne >= 0 && colonne < TailleGrille ) {
					MotAvecLettre (pos + 1, CaseSuivante, MotsTrouvés);

				}
			}
		}
	}
}

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par EmileF » 27 Jan 2020 21:45

Djulio a écrit : En fait dans le recherche de la case suivante, on pouvait passer de la 0 à la 4 (donc début de ligne à fin de même ligne), et l’erreur était là.
Bon , ok, je n'avais pas regardé ça. Dans mon script j'en avais tenu compte mais t'a façon de faire est bien plus propre.

Djulio a écrit : J'ai aussi tout comme toi ajouté une condition pour l'ajout des doublons. En plus que ce soit des doublons dans le dico, ce sont aussi des doublons car il y a plusieurs façon d’écrire un seul mot en se promenant sur la grille.
Mais je crois qu'il faut aussi tenir compte des doublons dans le dico car s'il ont des index différents la vérification des doublons ne les verra pas.

Djulio a écrit : J'ai aussi rajouté la possibilité de trouver juste le mots a partir d'une seule case de la grille, en cliquant dessus, et le bouton "rechercher tout" au lieu de presser "r".
C'est sympa comme option mais je pense que j'en aurai pas besoin pour mon jeu.
Djulio a écrit : As-tu vu aussi qu'en ajoutant asssez de lettre a "A" dans initialisegrille() tu pouvait augmenter la taille de la grille, tant que le nombre de lettre de "A" est supérieur ou égale a tailleGrille x tailleGrille?
Dans mon jeu A est généré aléatoirement en tenant compte des lettres du scrabbles pour avoir plus de A ou de E que de Z ou de Q. Et j'ai gardé l'option de générer des grilles de tailles différentes.

Merci Djulio de m'avoir consacré tant de temps pour m'aider, et je regrette de ne pas pouvoir en faire autant en retour. :pleur4:

merci
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

Répondre

Revenir vers « (C#) CSharp »