Ejemplo n.º 1
0
        // Methode permettant de retourner si deux tableau sont égaux
        public override bool Equals(object obj)
        {
            bool equal = true;

            if (obj != null)
            {
                EvaluableBoard board = (EvaluableBoard)obj;
                foreach (Cell cell in board)
                {
                    int posI, posJ;
                    board.Board.FindCellByValue(out posI, out posJ, cell.Value);
                    if (cell.Value != "-")
                    {
                        if (Board.Structure[posI, posJ].Value != "-1" && board.Board.Structure[posI, posJ].Value != "-1")
                        {
                            if (Board.Structure[posI, posJ].Value != cell.Value)
                            {
                                equal = false;
                            }
                        }
                    }
                }
            }
            else
            {
                equal = false;
            }
            return(equal);
        }
Ejemplo n.º 2
0
        // Méthode permettant de dupliquer un board en rompant
        // les effet de bord dus au type référence des tableaux
        public static EvaluableBoard CopyBoard(EvaluableBoard board)
        {
            EvaluableBoard result = new EvaluableBoard(board.Score);

            Cell[,] structure = new Cell[board.Size, board.Size];
            // On replace au bon endroit toute les cellules
            foreach (Cell cell in board)
            {
                Cell newCell = new Cell(cell.Value);
                int  posI, posJ;
                board.Board.FindCellByValue(out posI, out posJ, cell.Value);
                structure[posI, posJ] = newCell;
            }
            // On s'occupe de replaer les trous
            Cell emptyOne = new Cell("-");
            Cell emptyTwo = new Cell("-");
            int  e1i, e1j, e2i, e2j;

            board.Board.FindEmptyOne(out e1i, out e1j);
            board.Board.FindEmptyTwo(out e2i, out e2j);
            structure[e1i, e1j] = emptyOne;
            structure[e2i, e2j] = emptyTwo;
            // On créer le duplicata
            result.Board = new Board(structure);
            result.Size  = result.Board.Structure.GetLength(0);
            return(result);
        }
Ejemplo n.º 3
0
 public EvaluableBoard(Board board)
 {
     Previous = null;
     Board    = board;
     Size     = board.Structure.GetLength(0);
     Score    = 0;
 }
Ejemplo n.º 4
0
        public override List <Board> Solve(EvaluableBoard board)
        {
            // Mise en place du seuil à partir du noeud de départ
            Size         = board.Board.Structure.GetLength(0);
            _destination = Functions.CreateTarget(Size);
            int threshold = Heuristic.EvaluateBoard(board.Board, _destination.Board);

            //Setting the StartNode for this iteration
            EvaluableBoard start = board;

            while (true)
            {
                // Départ de la fonction récursive sur le premier noeud
                EvaluableBoard temp      = Search(start, 0, threshold);
                int            tempScore = temp.Score;
                if (temp.Equals(_destination))
                {
                    openCount   = _openSet.Count;
                    closedCount = _closedSet.Count;
                    return(Unpile(temp));
                }
                threshold  = tempScore;
                _openSet   = new List <EvaluableBoard>();
                _closedSet = new List <EvaluableBoard>();
            }
        }
Ejemplo n.º 5
0
        // Boucle de résoution
        public override List <Board> Solve(EvaluableBoard board)
        {
            // Etape d'initialisation
            _openSet   = new List <EvaluableBoard>();
            _closedSet = new List <EvaluableBoard>();
            Size       = board.Board.Structure.GetLength(0);
            _openSet.Add(board);
            EvaluableBoard result;

            // Boucle de résolution en ligne
            for (int rank = 0; rank < (Size * Size) - Size * 2; rank++)
            {
                _currentBoard = UnderStep(rank);
            }
            bool lineOne = true;
            int  start   = Size * Size - Size * 2;

            // Ensuite on place les deux dernières ligne par colonnes
            for (int rank = start; rank < start + Size; rank++)
            {
                _currentBoard = UnderStep(rank);
                int step = rank + Size;
                if (step < Size * Size - 2)
                {
                    _currentBoard = UnderStep(step);
                }
            }
            return(Unpile(_currentBoard));
        }
Ejemplo n.º 6
0
        // Evaluation de l'heuristique humaine
        private int Eval(EvaluableBoard board, int step)
        {
            int score = 0;
            int optI, optJ, currI, currJ;

            if (step < (Size * Size) - Size * 2)
            {
                for (int i = 0; i < step; i++)
                {
                    // Recherche de la position optimale
                    Functions.pos2coord(out optI, out optJ, i, Size);
                    // Recherche de la position courante
                    board.Board.FindCellByValue(out currI, out currJ, Convert.ToString(i));
                    // Prise ne compte de la distance case destination
                    score += 20 * (Math.Abs(optI - currI) + Math.Abs(optJ - currJ));
                }
            }
            else
            {
                for (int i = 0; i < (Size * Size) - Size * 2; i++)
                {
                    // Recherche de la position optimale
                    Functions.pos2coord(out optI, out optJ, i, Size);
                    // Recherche de la position courante
                    board.Board.FindCellByValue(out currI, out currJ, Convert.ToString(i));
                    // Prise ne compte de la distance case destination
                    score += 20 * (Math.Abs(optI - currI) + Math.Abs(optJ - currJ));
                }
            }
            // Prise en compte de la case courante a placer
            Functions.pos2coord(out optI, out optJ, step, Size);
            board.Board.FindCellByValue(out currI, out currJ, Convert.ToString(step));
            score += 8 * (Math.Abs(optI - currI) + Math.Abs(optJ - currJ));

            // Recherche des trous
            int hole1I, hole1J, hole2I, hole2J;

            board.Board.FindEmptyOne(out hole1I, out hole1J);
            board.Board.FindEmptyTwo(out hole2I, out hole2J);

            // Prise en compte de la distance trou case à placer
            score += 3 * (Math.Abs(hole1I - currI) + Math.Abs(hole1J - currJ));
            score += 3 * (Math.Abs(hole2I - currI) + Math.Abs(hole2J - currJ));


            // Prise en compte de la distance trou destination
            int distH1 = Math.Abs(optI - hole1I) + Math.Abs(optJ - hole1J);
            int distH2 = Math.Abs(optI - hole2I) + Math.Abs(optJ - hole2J);

            //score += 5 * distH1;
            //score += 5 * distH2;
            score += 5 * Math.Min(distH1, distH2);
            return(score);
        }
Ejemplo n.º 7
0
        // Methode permettant de récupérer le chemin de résolution
        public List <Board> Unpile(EvaluableBoard board)
        {
            List <Board> result = new List <Board>();

            while (board != null)
            {
                result.Add(board.Board);
                //Console.WriteLine(board.Board);
                board = board.Previous;
            }
            return(result);
        }
Ejemplo n.º 8
0
        // Fonction de création des enfants spécifiques
        public static List <EvaluableBoard> CreateChild(EvaluableBoard board, int step)
        {
            List <EvaluableBoard> neighbours = new List <EvaluableBoard>();
            int        size = board.Board.Structure.GetLength(0);
            List <int> values;

            // Valeurs possibles
            if (size == 3)
            {
                values = new List <int>()
                {
                    0, 1, 2, 3, 6, 4, 5
                }
            }
            ;
            else
            {
                values = new List <int>()
                {
                    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 20, 16, 21, 17, 22, 18, 19
                }
            };
            int maxIndex = values.IndexOf(step);

            foreach (Cell cell in board)
            {
                if (cell.Value != "-")
                {
                    int index = values.IndexOf(Convert.ToInt32(cell.Value));
                    // On interdit les mouvements au case déjà placées
                    if (index >= maxIndex)
                    {
                        int i, j;
                        board.Board.FindCellByValue(out i, out j, cell.Value);
                        if (cell.IsMovable())
                        {
                            foreach (Cell.Moves move in cell.AvailableMoves)
                            {
                                EvaluableBoard neighbour = CopyBoard(board);
                                neighbour.Cost = board.Cost;
                                neighbour.Board.Move(neighbour.Board.Structure[i, j], move);
                                neighbour.Previous = board;
                                neighbours.Add(neighbour);
                            }
                        }
                    }
                }
            }
            return(neighbours);
        }

        #endregion
    }
Ejemplo n.º 9
0
        public bool FindPast(EvaluableBoard board)
        {
            bool result = false;

            foreach (EvaluableBoard oldBoard in _closedSet)
            {
                if (oldBoard.Equals(board))
                {
                    result = true;
                }
            }
            return(result);
        }
Ejemplo n.º 10
0
 // Fonction de résolution intermédiaire qui applique A* entre deux états quelconques
 EvaluableBoard UnderStep(int rank)
 {
     _destination = new EvaluableBoard(CreateStep(Size, rank));
     while (_openSet.Count > 0)
     {
         _currentBoard = _openSet[0];
         if (_currentBoard.Equals(_destination))
         {
             closedCount += _closedSet.Count;
             openCount   += _openSet.Count;
             // Si on est à la dernière étape, on renvoit le résultat
             if (rank == Size * Size - 3)
             {
                 return(_currentBoard);
             }
             // Sinon on nettoie le solver pour la prochaine étape
             else
             {
                 _openSet            = new List <EvaluableBoard>();
                 _closedSet          = new List <EvaluableBoard>();
                 _currentBoard.Cost  = 0;
                 _currentBoard.Score = 0;
                 _openSet.Add(_currentBoard);
                 return(_currentBoard);
             }
         }
         List <EvaluableBoard> holder = CreateChild(_currentBoard, rank);
         foreach (EvaluableBoard testBoard in holder)
         {
             if (FindPast(testBoard) || FindBest(testBoard))
             {
             }
             else
             {
                 testBoard.Cost += 1;
                 // Evaluation d'une heuristique humaine spécifique
                 int thisHumanHeuri = Eval(testBoard, rank);
                 testBoard.Score = testBoard.Cost + thisHumanHeuri;
                 _openSet.Add(testBoard);
             }
         }
         _closedSet.Add(_currentBoard);
         _openSet.Remove(_currentBoard);
         _openSet = _openSet.OrderBy(b => b.Score).ToList();
     }
     return(null);
 }
Ejemplo n.º 11
0
        public bool FindBest(EvaluableBoard board)
        {
            bool result = false;

            foreach (EvaluableBoard currentBoard in _openSet)
            {
                if (board.Equals(currentBoard) && currentBoard.Cost <= board.Cost)
                {
                    result = true;
                }
                else if (board.Equals(currentBoard) && currentBoard.Cost > board.Cost)
                {
                    currentBoard.Cost = board.Cost;
                }
            }
            return(result);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Implémentation de l'algorithme A*
        /// </summary>
        /// <param name="board"> tableau de départ à résoudre </param>
        /// <returns></returns>
        public override List <Board> Solve(EvaluableBoard board)
        {
            // Création de la liste des ouvert vides
            _openSet = new List <EvaluableBoard>();
            int size = board.Size; // taille de l'example à résoudre

            _destination = Functions.CreateTarget(size);
            _openSet.Add(board);
            List <Board> result = new List <Board>(); // Initialisation du chemin

            // Boucle de résolution
            while (_openSet.Count > 0)
            {
                _currentBoard = _openSet[0];            // On récupère le meilleur élément
                if (_currentBoard.Equals(_destination)) // Si on est arrivé, on arrête
                {
                    openCount   = _openSet.Count;
                    closedCount = _closedSet.Count;
                    result      = Unpile(_currentBoard);
                    return(result);
                }
                // Sinon on créer les voisins
                List <EvaluableBoard> holder = CreateChild(_currentBoard);
                foreach (EvaluableBoard testBoard in holder)
                {
                    if (FindPast(testBoard) || FindBest(testBoard))
                    {
                    }                                                 // Si le voisin à déjà été évalué on ne le considère pas
                    else
                    {
                        // On applique les mesure de cout et d'heuristique à l'enfant et on l'ajoute à la liste
                        testBoard.Cost += 1;
                        testBoard.Score = testBoard.Cost + Heuristic.EvaluateBoard(testBoard.Board, _destination.Board);
                        _openSet.Add(testBoard);
                    }
                }
                // On enlève le noeud courrant des ouvert et on la joute à l aliste des fermés
                _closedSet.Add(_currentBoard);
                _openSet.Remove(_currentBoard);
                // On ordonne la liste pour garder les meilleurs en premier
                _openSet = _openSet.OrderBy(b => b.Score).ToList();
            }
            openCount   = _openSet.Count;
            closedCount = _closedSet.Count;
            return(result);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Fonction récursive au coeur de l'algorithme IDA*
        /// permet d'évaluer les parcours potentiels vers la solution
        /// </summary>
        /// <param name="currEval"></param>
        /// <param name="cost"></param>
        /// <param name="threshold"></param>
        /// <returns></returns>
        public EvaluableBoard Search(EvaluableBoard currEval, int cost, int threshold)
        {
            // Evaluation du cout récursif
            int f = cost + Heuristic.EvaluateBoard(currEval.Board, _destination.Board);

            _openSet.Add(currEval);
            // Si le score dépasse le seuil on coupe la branche
            if (f > threshold)
            {
                currEval.Score = f;
                return(currEval);
            }
            if (currEval.Equals(_destination))
            {
                return(currEval);
            }
            int min = int.MaxValue;
            // Recherche et evaluaiton des voisins
            List <EvaluableBoard> holder = CreateChild(currEval);

            foreach (EvaluableBoard child in holder)
            {
                child.Score = cost + Heuristic.EvaluateBoard(child.Board, _destination.Board);
            }
            holder = holder.OrderBy(b => b.Score).ToList();
            foreach (EvaluableBoard child in holder)
            {
                _openSet.Remove(currEval);
                _closedSet.Add(currEval);
                // Appel récrsif on évalue chaque enfant dans la fonction de recherche
                EvaluableBoard temp      = Search(child, cost + 1, threshold);
                int            tempScore = temp.Score;
                if (temp.Equals(_destination))
                {
                    return(temp);
                }
                if (tempScore < min)
                {
                    min = tempScore;
                }
            }
            currEval.Score = min;
            return(currEval);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Méthode retournant les voisins d'un état spécifique
        /// </summary>
        public static List <EvaluableBoard> CreateChild(EvaluableBoard board)
        {
            List <EvaluableBoard> neighbours = new List <EvaluableBoard>();

            // On regarde si les cellules peuvent bouger
            foreach (Cell cell in board)
            {
                int i, j;
                board.Board.FindCellByValue(out i, out j, cell.Value);
                if (cell.IsMovable())
                {
                    // Pour chaque mouvement possible, on crée un tableau ou on effectue le mouvement
                    foreach (Cell.Moves move in cell.AvailableMoves)
                    {
                        EvaluableBoard neighbour = CopyBoard(board);
                        neighbour.Cost = board.Cost;
                        neighbour.Board.Move(neighbour.Board.Structure[i, j], move);
                        neighbour.Previous = board;
                        neighbours.Add(neighbour);
                    }
                }
            }
            return(neighbours);
        }
Ejemplo n.º 15
0
        }                                         // L'algorithme de résolution à besoin d'une estimation du coup
        #endregion

        #region AbstractsToOverride
        /// <summary>
        /// La fonction ou s'implémente l'algorithme de résolution choisi
        /// </summary>
        /// <param name="board"> tableau cible à résoudre </param>
        /// <returns></returns>
        public abstract List <Board> Solve(EvaluableBoard board);
Ejemplo n.º 16
0
 public EvaluableBoard(int score)
 {
     Previous = null;
     Score    = score;
 }