private void EtablirPlanDAction() { /* Calcul du nombre de poussières */ List <int> poussieres = new List <int>(); List <int> bijoux = new List <int>(); for (int i = 0; i < 100; i++) { if (_bdi.Carte[i] == (int)ObjetCase.POUSSIERE || _bdi.Carte[i] == (int)ObjetCase.POUSSIEREBIJOUX) { poussieres.Add(i); } if (_bdi.Carte[i] == (int)ObjetCase.BIJOUX || _bdi.Carte[i] == (int)ObjetCase.POUSSIEREBIJOUX) { bijoux.Add(i); } } Etat etatInitial = new Etat(_bdi.Position, (ObjetCase)_bdi.Carte[_bdi.Position], poussieres, bijoux); _bdi.PlanDAction = _exploration.Explorer(etatInitial, _bdi.NbActions, _bdi.TestBut); }
// Fonction générique d'exploration // Retourne null en cas d'erreur public Queue Explorer(Etat etatInitial, int nbAction, Func <Etat, Etat, bool> testBut) { /* Création du graphe */ Graphe arbreRecherche = new Graphe(etatInitial); /* Initialisation de la frange */ List <Noeud> frange = new List <Noeud> { arbreRecherche.Racine }; /* Boucle de construction de la frange */ // En cas d'échec, retourne un plan d'action vide while (true) { // Cas d'échec if (frange.Count == 0) { return(null); } // Test de but Noeud noeud = frange.First(); frange.RemoveAt(0); if (testBut(noeud.EtatNoeud, etatInitial) || noeud.Profondeur == nbAction) { return(arbreRecherche.SequenceActions(noeud)); } // Expansion du noeud DejaVisites.Add(noeud.EtatNoeud); foreach (Noeud n in noeud.FonctionSuccession()) { frange = InsererNoeud(frange, n); noeud.AjouterEnfant(n); } } }
/* Constructeur du noeud : correspond à MAKE-NODE(..) */ // Le noeud parent est null pour le noeud racine // Parent : le noeud parent // Action : l'action effectuée par le parent public Noeud(Etat e, Noeud parent, Action action) { if (e == null) { throw new ArgumentNullException("e"); } EtatNoeud = e; Parent = parent; _listeEnfants = new List <Noeud>(); ActionParent = action; Heuristique = -1; if (parent != null) { Profondeur = Parent.Profondeur + 1; CoutChemin = Parent.CoutChemin + 1; // Une action = 1 unité d'énergie } // Cas de la racine else { Profondeur = 0; CoutChemin = 0; } }
/*---------------------------------*/ /* Desires */ /*---------------------------------*/ // Objectif : aspirer toutes les poussières // L'objectif est formulé sous la forme d'une fonction de test de but public bool TestBut(Etat etat, Etat etatInitial) { return(etat.ListePoussiere.Count() < etatInitial.ListePoussiere.Count() || etat.ListeBijoux.Count() < etatInitial.ListeBijoux.Count() || etat.ListePoussiere.Count() == 0); }
/* Constructeur du graphe */ // Prend en paramètre l'état initial pour l'exploration et l'ensemble de la grille public Graphe(Etat etatInitial) { Racine = new Noeud(etatInitial, null, Action.RIEN); }
// Fonction de succession des états /* En considérant le couple (position x, état de la pièce) : * - <(x, BIJOU), RAMASSER> -> (x, VIDE) * - <(x, POUSSIEREBIJOU), RAMASSER> -> (x, POUSSIERE) * - <(x, POUSSIERE), ASPIRER> -> (x, VIDE) * - <(x, VIDE), HAUT> -> (x-10, ObjetCase[x-10]) * - <(x, VIDE), BAS> -> (x+10, ObjetCase[x+10]) * - <(x, VIDE), GAUCHE> -> (x-1, ObjetCase[x-1]) * - <(x, VIDE), DROITE> -> (x+1, ObjetCase[x+1]) * Les autres possibilités sont illégales. */ public List <Noeud> FonctionSuccession() { List <Noeud> successeurs = new List <Noeud>(); Etat etat; Noeud noeud; switch (EtatNoeud.EtatPiece) { case ObjetCase.BIJOUX: { List <int> listeBijoux = new List <int>(EtatNoeud.ListeBijoux); listeBijoux.Remove(EtatNoeud.Position); etat = new Etat(EtatNoeud.Position, ObjetCase.VIDE, EtatNoeud.ListePoussiere, listeBijoux); noeud = new Noeud(etat, this, Action.RAMASSER); successeurs.Add(noeud); break; } case ObjetCase.POUSSIEREBIJOUX: { List <int> listeBijoux = new List <int>(EtatNoeud.ListeBijoux); listeBijoux.Remove(EtatNoeud.Position); etat = new Etat(EtatNoeud.Position, ObjetCase.POUSSIERE, EtatNoeud.ListePoussiere, listeBijoux); noeud = new Noeud(etat, this, Action.RAMASSER); successeurs.Add(noeud); break; } case ObjetCase.POUSSIERE: { List <int> listePoussiere = new List <int>(EtatNoeud.ListePoussiere); listePoussiere.Remove(EtatNoeud.Position); etat = new Etat(EtatNoeud.Position, ObjetCase.VIDE, listePoussiere, EtatNoeud.ListeBijoux); noeud = new Noeud(etat, this, Action.ASPIRER); successeurs.Add(noeud); break; } case ObjetCase.VIDE: { // Haut if (EtatNoeud.Position >= 10) { int pos = EtatNoeud.Position - 10; ObjetCase piece = ObjetCase.VIDE; if (EtatNoeud.ListePoussiere.Exists(x => x == pos) && EtatNoeud.ListeBijoux.Exists(x => x == pos)) { piece = ObjetCase.POUSSIEREBIJOUX; } else if (EtatNoeud.ListePoussiere.Exists(x => x == pos)) { piece = ObjetCase.POUSSIERE; } else if (EtatNoeud.ListeBijoux.Exists(x => x == pos)) { piece = ObjetCase.BIJOUX; } etat = new Etat(pos, piece, EtatNoeud.ListePoussiere, EtatNoeud.ListeBijoux); noeud = new Noeud(etat, this, Action.HAUT); successeurs.Add(noeud); } // Bas if (EtatNoeud.Position < 90) { int pos = EtatNoeud.Position + 10; ObjetCase piece = ObjetCase.VIDE; if (EtatNoeud.ListePoussiere.Exists(x => x == pos) && EtatNoeud.ListeBijoux.Exists(x => x == pos)) { piece = ObjetCase.POUSSIEREBIJOUX; } else if (EtatNoeud.ListePoussiere.Exists(x => x == pos)) { piece = ObjetCase.POUSSIERE; } else if (EtatNoeud.ListeBijoux.Exists(x => x == pos)) { piece = ObjetCase.BIJOUX; } etat = new Etat(pos, piece, EtatNoeud.ListePoussiere, EtatNoeud.ListeBijoux); noeud = new Noeud(etat, this, Action.BAS); successeurs.Add(noeud); } // Gauche if ((EtatNoeud.Position % 10) != 0) { int pos = EtatNoeud.Position - 1; ObjetCase piece = ObjetCase.VIDE; if (EtatNoeud.ListePoussiere.Exists(x => x == pos) && EtatNoeud.ListeBijoux.Exists(x => x == pos)) { piece = ObjetCase.POUSSIEREBIJOUX; } else if (EtatNoeud.ListePoussiere.Exists(x => x == pos)) { piece = ObjetCase.POUSSIERE; } else if (EtatNoeud.ListeBijoux.Exists(x => x == pos)) { piece = ObjetCase.BIJOUX; } etat = new Etat(pos, piece, EtatNoeud.ListePoussiere, EtatNoeud.ListeBijoux); noeud = new Noeud(etat, this, Action.GAUCHE); successeurs.Add(noeud); } // Droite if (((EtatNoeud.Position + 1) % 10) != 0) { int pos = EtatNoeud.Position + 1; ObjetCase piece = ObjetCase.VIDE; if (EtatNoeud.ListePoussiere.Exists(x => x == pos) && EtatNoeud.ListeBijoux.Exists(x => x == pos)) { piece = ObjetCase.POUSSIEREBIJOUX; } else if (EtatNoeud.ListePoussiere.Exists(x => x == pos)) { piece = ObjetCase.POUSSIERE; } else if (EtatNoeud.ListeBijoux.Exists(x => x == pos)) { piece = ObjetCase.BIJOUX; } etat = new Etat(pos, piece, EtatNoeud.ListePoussiere, EtatNoeud.ListeBijoux); noeud = new Noeud(etat, this, Action.DROITE); successeurs.Add(noeud); } break; } } return(successeurs); }