IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

huits reines en C++ - recherche en profondeur d'abord -


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 163
    Points : 102
    Points
    102
    Par défaut huits reines en C++ - recherche en profondeur d'abord -
    bsr ,

    j'essaye de résoudre le problème des huits reines par la méthode de recherche en prof d'abord ( en utilisant une pile ) , voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
     
    #include <iostream>
    #include <stack>
    #include "econio.h"
     
    using namespace std;
     
    class Etat 
    {
      public:
     
    	Etat(); // constructeur par défaut 
    	//Etat(const Etat &e); // constructeur de copie
    	void obtenirEchiquierVide();
    	void afficherEchiquier();
    	bool estSolution();
    	bool estPositionValide(int,int);
     
    	int Echiquier[8][8];
     
    };
     
    void Successeurs(Etat &,int,int);
     
    stack < Etat > Etats;
     
    int main( int argc , char **argv )
    {
    	Etat e;
    	bool SolTrouvee = false;
    	unsigned int nb_succ = 0; // successeur initial à zero
     
    	while(SolTrouvee==false)
    	{
    		if(e.estSolution()) 
    			SolTrouvee = true;	
    		Successeurs(e,0,0);
    		Etats.pop();
    		e.afficherEchiquier();
    		getch();
    	}
     
    	return 0;
     
    }
     
    void Successeurs(Etat &e,int i,int j)
    { // la fct récursive qui génère les successeurs
     
    	if(e.estSolution())
    		return;
    	if(i<8)
    	{
     
     
    		if(j<8)
    		{
    			if(e.estPositionValide(i,j))
    			{ // successeur trouvé
    				e.Echiquier[j][i] = 1;
    				Etats.push(e);
    				e.Echiquier[j][i] = 0;
    			}
    			Successeurs(e,j,i+1);
    		}
     
    		else
    			Successeurs(e,j+1,0);
     
     
    	}
     
    }
     
    Etat::Etat()
    {
    	obtenirEchiquierVide();
    }
     
    void  Etat::obtenirEchiquierVide()
    {
     
    	for(unsigned int i=0;i<8;i++)
    	{
    		for(unsigned int j=0;j<8;j++)
    		{
    			Echiquier[i][j] = 0;
    		}
    	}
     
    }
     
    void Etat::afficherEchiquier()
    {
     
    	for(unsigned int i=0;i<8;i++)
    	{
    		for(unsigned int j=0;j<8;j++)
    		{
    			cout<< Echiquier[i][j];
    		}
     
    		cout<<endl;
    	}
    }
     
    bool Etat::estPositionValide( int numColonne , int numLigne )
    {
    	unsigned int nbrePoints = 0; // pr qu'une position soit valide , il faut que nbrePoints reste à zero
    	unsigned int compteurDame = 0; // compte , le nbre de dames sur une ligne / colonne / diagonale 
     
    	// on teste d'abord qu'il n'y a pas de dame sur la case
    	if(Echiquier[ numLigne ][ numColonne ] == 1)
    	{
    		cout<<" test 1 "<<endl;
    		++nbrePoints;
    	}
     
    	// on verifie qu'il n'y a pas de dame sur la portée d'une autre dame
    	for(unsigned int j=0;j < 8;++j)
    	{			
    		// portée : ligne 
    		if(Echiquier[ numLigne ][ j ] == 1)
    		{
    			cout<<" test 2 "<<endl;
    			++compteurDame;
    		}
     
    		// portée : colonne 
    		if(Echiquier[ j ][ numColonne ] == 1)
    		{
    			cout<<" test 3 "<<endl;
    			++compteurDame;
    		}
     
    	}
     
    	// portée : diagonale 
    	unsigned int i =  numLigne ;
    	unsigned int k =  numColonne;
    	// 1ère , sous diagonale possible ( en haut à droite )
    	while((i>0 && i<8)&&(k>0&&k<8) && compteurDame == 0)
    	{
    		--i;
    		++k;
    		if(Echiquier[ i ][ k ] == 1)
    		{
    			cout<<" test 4 "<<endl;
    			++compteurDame;
    		}
    	}
     
    	i = numLigne;
    	k = numColonne;
     
    	// 2ème , sous diagonale possible ( en haut à gauche )
    	while((i>0 && i<8)&&(k>0 && k<8) && compteurDame == 0)
    	{
    		--i;
    		--k;
    		if(Echiquier[ i ][ k ] == 1)
    		{
    			cout<<" test 5 "<<endl;
    			++compteurDame;
    		}
    	}
     
    	i = numLigne;
    	k = numColonne;
     
    	// 3ème sous diagonale possible ( en bas à droite )
    	while((i>0 && i<8 )&&(k>0 && k<8) && compteurDame == 0)
    	{
    		++i;
    		++k;
    		if(Echiquier[ i ][ k ] == 1)
    		{
    			cout<<" test 6 "<<endl;
    			++compteurDame;
    		}
    	}
     
    	i = numLigne;
    	k = numColonne;
     
    	// 4ème et dernière , sous diagonale possible ( en bas à gauche )
    	while((i>0 && i<8)&&(k>0 && k<8) && compteurDame == 0)
    	{
     
    		++i;
    		--k;
    		if(Echiquier[ i ][ k ] == 1)
    		{
    			cout<<" test 7 "<<endl;
    			++compteurDame;
    		}
     
    	}
     
    	if(compteurDame == 0)
    		return true;
     
    	return false;
    }
     
    bool Etat::estSolution()
    {
    	unsigned int compteurDame = 0;
    	// premier test : ya t'il 8 dames sur l'échiquier ?
    	for(unsigned int i = 0;i<8;++i)
    	{
    		for(unsigned int j = 0;j<8;++j)
    		{
    			if(Echiquier[ i ][ j ] == 1)
    				compteurDame++;
    		}
    	}
    	if(compteurDame != 8 ) 
    		return false;
    	// deuxième test : sont elles , bien positionnées ?
     
    	for(unsigned int q=0;q<7;++q)
    	{
    		for(unsigned int s=0;s<7;++s)
    		{
     
    			// 1 er test : case par case suivant une ligne
    			if(Echiquier[q][s] == 1 && Echiquier[q][s+1] == 1)
    				return false;
     
    			// 2 ème test : case par case suivant une colonne
    			if(Echiquier[q][s] == 1 && Echiquier[q+1][s] == 1)
    				return false;
     
    			// 3ème test : case par case suivant une même diagonale
    			if(Echiquier[q][s] == 1 && Echiquier[q+1][s+1] == 1)
    				return false;
    		}
    	}
     
    	return true;
    }
    d'abord est ce que ma fct récursive Successeurs , est correcte ?
    Autre chose ( surtout ça ) j'ai un problème avec ma pile , regardez ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    stack < Etat > Etats;
     
    int main( int argc , char **argv )
    {
    	Etat e;
    	bool SolTrouvee = false;
    	unsigned int nb_succ = 0; // successeur initial à zero
    	Etats.push(e);
    	while(SolTrouvee==false)
    	{
    		if(e.estSolution()) 
    			SolTrouvee = true;	
    		Successeurs(e,0,0);
    		Etats.pop();
     
    	}
     
    	return 0;
     
    }
    de cette manière là , ça marche pas du tout comme prévu , les élements desempilés n'affectent pas mon objet de la classe Etat , en gros si je veux tester un element desempilé ça foire car Etats.pop(); n'affecte pas e. aussi , la récursion a l'air de foirer un peu , car ça m'affiche que des échiquiers vides avec l'impression qu'aucune position valide n'a été trouvée ! ( test 7 ( cf : le code de la fct estPositionValide(..); )
    c la première fois que j'utilise cette méthode de résolution , et je suis pas très habitué des fct récursives .

    Merci pour votre aide
    http://amokrane-chentir.blogspot.com { Software engineering, .NET technologies, Imagine cup..}

  2. #2
    Membre éclairé Avatar de reggae
    Profil pro
    Inscrit en
    Août 2005
    Messages
    773
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2005
    Messages : 773
    Points : 795
    Points
    795
    Par défaut
    Il y a un truc qui m'intrigue:pourquoi quand tu crées un objet de type:
    tu vides tout ton échiquier?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Etat::Etat()
    {
       obtenirEchiquierVide();
    }
    :

  3. #3
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 163
    Points : 102
    Points
    102
    Par défaut
    hmm , ben je trouvais ça logique au départ d'initialiser mon Echiquier à zero non ? ( le vidage de l'échiquier se fait au niveau du constructeur )
    http://amokrane-chentir.blogspot.com { Software engineering, .NET technologies, Imagine cup..}

  4. #4
    Membre éclairé Avatar de reggae
    Profil pro
    Inscrit en
    Août 2005
    Messages
    773
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2005
    Messages : 773
    Points : 795
    Points
    795
    Par défaut
    Moi je l'aurais pas fait a niveau du constructeur...
    Au début du main j'aurais simplement appelé la fonction obtenirEchiquierVide(); .

  5. #5
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 163
    Points : 102
    Points
    102
    Par défaut
    ok je vais modifier ça , mais pourquoi proceder comme ça plutot que dans le constructeur ? après tt je ne crée qu'un seul objet ! non ?
    http://amokrane-chentir.blogspot.com { Software engineering, .NET technologies, Imagine cup..}

  6. #6
    Membre éclairé Avatar de reggae
    Profil pro
    Inscrit en
    Août 2005
    Messages
    773
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2005
    Messages : 773
    Points : 795
    Points
    795
    Par défaut
    Oui c'est vrai, mais pour la compréhension c'est mieux.
    Si la personne qui lit le code pour le modifier voit que le constructeur efface les données de l'échiquier, il ne va rien y comprendre, il va se demander en quoi l'objet est impliqué dans cette opérataion...
    Par contre si tu le mets au début il va comprendre.

    Tu as raison, de toute manière le résultat est le même.

  7. #7
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 163
    Points : 102
    Points
    102
    Par défaut
    ok

    sinon , une idée sur le pb peut être ma fct récursive Successeurs(...) qui est mal écrite ? ( faudrait executer pr voir ce qu'il en est) et surtout pr ma pile , comment faire en sorte que je puisse récuperer la valeur popée ( désempilée ^^) via mon objet ? ( là j'ai écris n'importe quoi dans mon while , juste pr dire que je n'en ai aucune idée ) .

    thx pr tout !
    http://amokrane-chentir.blogspot.com { Software engineering, .NET technologies, Imagine cup..}

  8. #8
    Membre éclairé Avatar de reggae
    Profil pro
    Inscrit en
    Août 2005
    Messages
    773
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2005
    Messages : 773
    Points : 795
    Points
    795
    Par défaut
    PS:
    ne sert à rien

  9. #9
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 163
    Points : 102
    Points
    102
    Par défaut
    Citation Envoyé par reggae
    PS:
    ne sert à rien
    ouep , merci de me le rappeller , c juste que ça me sert qd je teste l'algo étape par étape : je mets des getch(); partout
    http://amokrane-chentir.blogspot.com { Software engineering, .NET technologies, Imagine cup..}

  10. #10
    Membre éclairé Avatar de reggae
    Profil pro
    Inscrit en
    Août 2005
    Messages
    773
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2005
    Messages : 773
    Points : 795
    Points
    795
    Par défaut
    Sinon la recherche est en cours .
    Chez toi aussi le programme ne sors jamais de la boucle qui se trouve dans le main() ? Continue-t-il également indéfiniment?

  11. #11
    Membre éclairé Avatar de reggae
    Profil pro
    Inscrit en
    Août 2005
    Messages
    773
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2005
    Messages : 773
    Points : 795
    Points
    795
    Par défaut
    J'ai remplacé ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
     for(unsigned int q=0;q<7;++q)
       {
          for(unsigned int s=0;s<7;++s)
          {
     
             // 1 er test : case par case suivant une ligne
             if(Echiquier[q][s] == 1 && Echiquier[q][s+1] == 1)
                return false;
     
             // 2 ème test : case par case suivant une colonne
             if(Echiquier[q][s] == 1 && Echiquier[q+1][s] == 1)
                return false;
     
             // 3ème test : case par case suivant une même diagonale
             if(Echiquier[q][s] == 1 && Echiquier[q+1][s+1] == 1)
                return false;
          }
       }
    par ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
       for(unsigned int q=0;q<7;++q)                    // Q=COLONNE, s=ligne
       {
          // 1 er test : case par case suivant une ligne
          for(unsigned int s=0;s<7;++s)                 
          {
     
     
             if(Echiquier[q][s] != 0)
                return false;
          }
          }
       // 2 ème test : case par case suivant une colonne
       for(unsigned int s=0;s<7;++s)     
       {
            for(unsigned int q=0;q<7;++q)
            {  
             if(Echiquier[q][s] != 0)
                return false;
             }
       //3ème test: comme les 2 précédents
    }
    Tu m'arrête si je me trompe mais pour moi c'est plus logique et plus clair d'opérer de la même manière que la deuxième soluce.

  12. #12
    Membre éclairé Avatar de reggae
    Profil pro
    Inscrit en
    Août 2005
    Messages
    773
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2005
    Messages : 773
    Points : 795
    Points
    795
    Par défaut
    2ème chose: le coup de la boucle sans fin c'est résolu:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       if(compteurDame != 8 )
          return false;
       // deuxième test : sont elles , bien positionnées ?
    devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if(compteurDame != 8 )
          return true;
       // deuxième test : sont elles , bien positionnées ?
    Assez logique

  13. #13
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 163
    Points : 102
    Points
    102
    Par défaut
    pr la première c une question de goût , et niveau complexité ( en temps ) c pareil :O(n²) , mais peut être que je me trompe ?

    pr la deuxième remarque , s'il ya pas 8 dames sur l'échiquier c que l'état n'est pas une solution de mon problème , d'où le return false; , c logique non ?
    sinon , oui j'ai le même pb que chez toi ça tourne indéfiniment !

    et t 'as vu il execute le code du test 7 !

    en tout cas merci de passer du temps sur mon code c sympa
    http://amokrane-chentir.blogspot.com { Software engineering, .NET technologies, Imagine cup..}

  14. #14
    Membre éclairé Avatar de reggae
    Profil pro
    Inscrit en
    Août 2005
    Messages
    773
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2005
    Messages : 773
    Points : 795
    Points
    795
    Par défaut
    pr la deuxième remarque , s'il ya pas 8 dames sur l'échiquier c que l'état n'est pas une solution de mon problème , d'où le return false; , c logique non ?
    Mais au début il y a forcément moins de 8 dames sur le plateau. Donc si il retourne false, tu n'as aucune chance de pouvoir placer quoi que ce soit vu qu'un return sort automatiquement de la fonction.
    Donc aucune manière d'avoir un true->la boucle s'exécute indéfiniment.

  15. #15
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 163
    Points : 102
    Points
    102
    Par défaut
    Je ne suis pas convaincu lol ! dans mon while je fais un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(e.estSolution())
    donc , s'il retourne un false le if ne sera pas executé , vois pas ou est le pb ?
    http://amokrane-chentir.blogspot.com { Software engineering, .NET technologies, Imagine cup..}

  16. #16
    Membre éclairé Avatar de reggae
    Profil pro
    Inscrit en
    Août 2005
    Messages
    773
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2005
    Messages : 773
    Points : 795
    Points
    795
    Par défaut
    Alors voila, j'ai résolu en partie le prob, je n'ai pas pris en compte les diagonales, c'est d'ailleurs signalé dans les commentaires te ça sera facile d'y remédier!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
     
     
    #include <iostream>
    #include <stack>
     
     
    using namespace std;
     
    class Etat
    {
      public:
     
       Etat(); // constructeur par défaut
       //Etat(const Etat &e); // constructeur de copie
       void obtenirEchiquierVide();
       void afficherEchiquier();
       bool estSolution();
       bool estPositionValide(int,int);
     
       int Echiquier[8][8];
     
    };
     
    void Successeurs(Etat &,int,int);
     
    stack < Etat > Etats;
     
    int main()
    {
       Etat e;
       bool SolTrouvee = false;
       unsigned int nb_succ = 0; // successeur initial à zero
     
       while(SolTrouvee==false)
       {
          if(e.estSolution())
          SolTrouvee = true;   
          Successeurs(e,0,0);
          Etats.pop();
          e.afficherEchiquier();
          system("pause");
       }
     
       return 0;
     
    }
     
    void  Successeurs(Etat &e,int i,int j)
    { // la fct récursive qui génère les successeurs
     
     
     
       if(i<8)
       {
     
     
          if(j<8)
          {
             if(e.estPositionValide(i,j))
             { // successeur trouvé
     
                e.Echiquier[j][i] = 1;
                Etats.push(e);
     
             }
             Successeurs(e,j,i+1);
          }
     
          else
             Successeurs(e,j+1,0);
     
     
       }
     
    }
     
    Etat::Etat()
    {
       obtenirEchiquierVide();
    }
     
    void  Etat::obtenirEchiquierVide()
    {
     
       for(unsigned int i=0;i<8;i++)
       {
          for(unsigned int j=0;j<8;j++)
          {
             Echiquier[i][j] = false;
          }
       }
     
    }
     
    void Etat::afficherEchiquier()
    {
     
       for(unsigned int i=0;i<8;i++)
       {
          for(unsigned int j=0;j<8;j++)
          {
             cout<< Echiquier[i][j];
          }
     
          cout<<endl;
       }
    }
     
    bool Etat::estPositionValide( int numColonne , int numLigne )
    {
       unsigned int nbrePoints = 0; // pr qu'une position soit valide , il faut que nbrePoints reste à zero
       unsigned int compteurDame = 0; // compte , le nbre de dames sur une ligne / colonne / diagonale
     
       // on teste d'abord qu'il n'y a pas de dame sur la case
       if(Echiquier[ numLigne ][ numColonne ] == 1)
       {
          cout<<" test 1 "<<endl;
          ++nbrePoints;
       }
     
       // on verifie qu'il n'y a pas de dame sur la portée d'une autre dame
       for(unsigned int j=0;j < 8;++j)
       {         
          // portée : ligne
          if(Echiquier[ numLigne ][ j ] == 1)
          {
             cout<<" test 2 "<<endl;
             ++compteurDame;
          }
     
          // portée : colonne
          if(Echiquier[ j ][ numColonne ] == 1)
          {
             cout<<" test 3 "<<endl;
             ++compteurDame;
          }
     
       }
     
     
     
       if(compteurDame == 0)
          return true;
       return false;
    }
     
    bool Etat::estSolution()
    {
       unsigned int compteurDame = 0;
       // premier test : ya t'il 8 dames sur l'échiquier ?
       for(unsigned int i = 0;i<8;++i)
       {
          for(unsigned int j = 0;j<8;++j)
          {
             if(Echiquier[ i ][ j ] == 1)
                compteurDame++;
          }
       }
       if(compteurDame != 8 )
          return true;
       // deuxième test : sont elles , bien positionnées ?
       for(unsigned int q=0;q<7;++q)                    // Q=COLONNE, s=ligne
       {
          // 1 er test : case par case suivant une ligne
          for(unsigned int s=0;s<7;++s)                 
          {
     
     
             if(Echiquier[q][s] != 0)
                return false;
          }
          }
       // 2 ème test : case par case suivant une colonne
       for(unsigned int s=0;s<7;++s)     
       {
            for(unsigned int q=0;q<7;++q)
            {  
             if(Echiquier[q][s] != 0)
                return false;
             }
       // 3ème test
    }
       return true;
    }
    Il faut encore que tu vérifies le tout. Mais on est presque au bout!!!

  17. #17
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 163
    Points : 102
    Points
    102
    Par défaut
    Re, je me suis replongé sur le code en fin d'après midi , et finalement j'y suis arrivé ^^

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
     
    #include <iostream>
    #include <stack>
    #include "econio.h"
     
    using namespace std;
     
    #define TAILLE_ECHIQUIER 8
     
    class Etat 
    {
      public:
     
    	Etat(); // constructeur par défaut 
    	//Etat(const Etat &e); // constructeur de copie
    	void obtenirEchiquierVide();
    	void afficherEchiquier();
    	bool estSolution();
    	bool estPositionValide(int,int);
     
    	int Echiquier[TAILLE_ECHIQUIER][TAILLE_ECHIQUIER];
     
    };
     
    void Successeurs(Etat &,int,int);
     
    stack < Etat > Etats;
     
    int main( int argc , char **argv )
    {
    	Etat e;
    	bool SolTrouvee = false;
    	unsigned int nb_succ = 0; // successeur initial à zero
    	Etats.push(e); // on empile le premier état dans la pile 
    	while(SolTrouvee==false)
    	{
     
    		//getch();
    		if(e.estSolution()) 
    		{
    			cout<<" test du main  solution !!"<<endl;
    			e.afficherEchiquier();
    			SolTrouvee = true;	 // solution trouvée , on sort du while
    		}
     
    		Successeurs(e,0,0); // sinon on génère les successeurs de l'état en cours
    		e = Etats.top(); // on regarde au sommet de la pile
    		Etats.pop(); // on désempile , un état 
     
    	}
    	// on affiche l'état solution
     
    	return 0;
     
    }
     
    void Successeurs(Etat &e,int i,int j)
    { // la fct récursive qui génère les successeurs
     
    	if(e.estSolution())
    		return;
    	if(i<TAILLE_ECHIQUIER)
    	{
     
     
    		if(j<TAILLE_ECHIQUIER)
    		{
    			if(e.estPositionValide(i,j))
    			{ // successeur trouvé
    				e.Echiquier[i][j] = 1;
    				Etats.push(e);
    				e.Echiquier[i][j] = 0;
    			}
    			Successeurs(e,i,j+1);
    		}
     
    		else
    			Successeurs(e,i+1,0);
     
     
    	}
     
    }
     
    Etat::Etat()
    {
    	obtenirEchiquierVide();
    }
     
    void  Etat::obtenirEchiquierVide()
    {
     
    	for(unsigned int i=0;i<TAILLE_ECHIQUIER;i++)
    	{
    		for(unsigned int j=0;j<TAILLE_ECHIQUIER;j++)
    		{
    			Echiquier[i][j] = 0;
    		}
    	}
     
    }
     
    void Etat::afficherEchiquier()
    {
     
    	for(unsigned int i=0;i<TAILLE_ECHIQUIER;i++)
    	{
    		for(unsigned int j=0;j<TAILLE_ECHIQUIER;j++)
    		{
    			cout<< Echiquier[i][j];
    		}
     
    		cout<<endl;
    	}
    }
     
    bool Etat::estPositionValide( int numLigne , int numColonne )
    {
    	unsigned int nbrePoints = 0; // pr qu'une position soit valide , il faut que nbrePoints reste à zero
    	unsigned int compteurDame = 0; // compte , le nbre de dames sur une ligne / colonne / diagonale 
     
    	// on teste d'abord qu'il n'y a pas de dame sur la case
    	if(Echiquier[ numLigne ][ numColonne ] == 1)
    		++nbrePoints;
     
     
    	// on verifie qu'il n'y a pas de dame sur la portée d'une autre dame
    	for(unsigned int j=0;j <TAILLE_ECHIQUIER;++j)
    	{			
    		// portée : ligne 
    		if(Echiquier[ numLigne ][ j ] == 1)
    			++compteurDame;
     
     
    		// portée : colonne 
    		if(Echiquier[ j ][ numColonne ] == 1)
    			++compteurDame;
     
     
    	}
     
    	// portée : diagonale 
    	unsigned int i =  numLigne ;
    	unsigned int k =  numColonne;
    	// 1ère , sous diagonale possible ( en haut à droite )
    	while((i>0 && i < (TAILLE_ECHIQUIER-1))&&(k>=0 && k < (TAILLE_ECHIQUIER-1)) && compteurDame == 0)
    	{
    		--i;
    		++k;
    		if(Echiquier[ i ][ k ] == 1)
    			++compteurDame;
     
    	}
     
    	i = numLigne;
    	k = numColonne;
     
    	// 2ème , sous diagonale possible ( en haut à gauche )
    	while((i>0 && i<(TAILLE_ECHIQUIER-1))&&(k>0 && k<(TAILLE_ECHIQUIER-1)) && compteurDame == 0)
    	{
    		--i;
    		--k;
    		if(Echiquier[ i ][ k ] == 1)
    			++compteurDame;
     
    	}
     
    	i = numLigne;
    	k = numColonne;
     
    	// 3ème sous diagonale possible ( en bas à droite )
    	while((i>=0 && i<(TAILLE_ECHIQUIER-1))&&(k>=0 && k<(TAILLE_ECHIQUIER-1)) && compteurDame == 0)
    	{
    		++i;
    		++k;
    		if(Echiquier[ i ][ k ] == 1)
    			++compteurDame;
     
    	}
     
    	i = numLigne;
    	k = numColonne;
    	//cout<<" avant d\'entrer dans le while "<<" i :"<<i<<" k "<<k<<endl;
    	// 4ème et dernière , sous diagonale possible ( en bas à gauche )
    	while((i>=0 && i<(TAILLE_ECHIQUIER-1))&&(k>=0 && k<(TAILLE_ECHIQUIER-1)) && compteurDame == 0)
    	{
     
    		++i;
    		--k;
    		if(Echiquier[ i ][ k ] == 1)
    			++compteurDame;
    	}
     
    	if(compteurDame == 0)
    		return true;
     
    	return false;
    }
     
    bool Etat::estSolution()
    {
    	unsigned int compteurDame = 0;
    	// premier test : ya t'il 8 dames sur l'échiquier ?
    	for(unsigned int i = 0;i<TAILLE_ECHIQUIER;++i)
    	{
    		for(unsigned int j = 0;j<TAILLE_ECHIQUIER;++j)
    		{
    			if(Echiquier[ i ][ j ] == 1)
    				compteurDame++;
    		}
    	}
    	if(compteurDame != TAILLE_ECHIQUIER) 
    		return false;
    	// deuxième test : sont elles , bien positionnées ?
     
    	for(unsigned int q=0;q<(TAILLE_ECHIQUIER-1);++q)
    	{
    		for(unsigned int s=0;s<(TAILLE_ECHIQUIER-1);++s)
    		{
     
    			// 1 er test : case par case suivant une ligne
    			if(Echiquier[q][s] == 1 && Echiquier[q][s+1] == 1)
    				return false;
     
    			// 2 ème test : case par case suivant une colonne
    			if(Echiquier[q][s] == 1 && Echiquier[q+1][s] == 1)
    				return false;
     
    			// 3ème test : case par case suivant une même diagonale
    			if(Echiquier[q][s] == 1 && Echiquier[q+1][s+1] == 1)
    				return false;
    		}
    	}
     
    	return true;
    }
    pr le désempilage , fallait que mon objet pointe au sommet de la pile ( tout bête ) , sinon c pas super optimisé ! il mets environ 11s pr trouver l'état final pr 8 reines , pr 13 reines ça me faisait dans les 2mins ( j'ai même pas pu profiler correctement tellement que ça prenait du temps), pr l'info qd je laissais l'affichage des échiquiers à chaque passage de boucle ça me faisait dans les 25mins de recherche pr 8 reines lol !

    Enfin bref , merci d'avoir passé du temps sur mon code reggae ça fait vraiment plaisir .
    http://amokrane-chentir.blogspot.com { Software engineering, .NET technologies, Imagine cup..}

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Recherche Cobol(s) à prix abordables !
    Par EDELH dans le forum Cobol
    Réponses: 7
    Dernier message: 15/04/2013, 16h51
  2. [Sicstus] n-reines avec de la recherche locale
    Par polochonad dans le forum Prolog
    Réponses: 17
    Dernier message: 13/03/2008, 08h30
  3. [Problème] Programme huit reines
    Par thegreatbato dans le forum C
    Réponses: 20
    Dernier message: 04/05/2006, 22h04
  4. Chemin vers la solution - recherche en profondeur d'abord -
    Par Amokrane dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 11/01/2006, 20h54
  5. algo de recherche en profondeur
    Par sylsau dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 08/02/2005, 22h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo