예제 #1
0
 /// <summary>
 /// Конструктор
 /// </summary>
 /// <param name="parRoot">Родиельский узел</param>
 /// <param name="parLevel">Уровень</param>
 public SolutionThree(Move parMove, SolutionThree parRoot, int parLevel)
 {
     _Root = parRoot;
     _Level = parLevel;
     _Move = parMove;
     _ChildNodes = new List<SolutionThree>();
 }
예제 #2
0
 /// <summary>
 /// Добавить дочерний узел в дерево
 /// </summary>
 /// <param name="parMove"></param>
 public void AddChildNode(Move parMove)
 {
     _ChildNodes.Add(new SolutionThree(parMove, this, _Level + 1));
 }
예제 #3
0
        /// <summary>
        /// Отмена хода
        /// </summary>
        /// <param name="parMove"></param>
        /// <param name="parSolutionThree"></param>
        public override void CancelMove(Move parMove, SolutionThree parSolutionThree)
        {
            _Task.Mirrors = parMove.Mirrors;

            for (int i = 0; i < _Task.Mirrors.Count; i++)
            {
                if ((_Task.Mirrors[i].Left == parMove.ToPos.X) && (_Task.Mirrors[i].Top == parMove.ToPos.Y))
                {
                    parMove.Mirrors[i] = new Square(parMove.FromPos.Y, parMove.FromPos.Y + LasersGame.COORDINATE_RATIO, parMove.FromPos.X, parMove.FromPos.X + LasersGame.COORDINATE_RATIO);

                    _Task.CalculateLaser();
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Оценочная функция
        /// </summary>
        /// <param name="parMove">оцениваемый ход</param>
        /// <param name="parSolutionThree"> узелд дерева из которого совершается ход</param>
        /// <returns>rколичество ходов, прошедших с момента последненго перемещения зеркала, указанного в ходе</returns>
        public override int Estimator(Move parMove, SolutionThree parSolutionThree)
        {
            int rating = MaxAlowableDepth + 1;
            //получаем исходное положение перемещаемого зеркала
            Point mirrorPosition = parMove.FromPos;
            //и узел дерева из которого совершаем ход
            SolutionThree solutionNode = parSolutionThree;

            //пока не добрались до корня дерва поиска
            while (solutionNode.Root != null)
            {
                //если ход, приведший к текущему узлу дерева, перемещал проверяемое зеркало
                if (solutionNode.Move.ToPos == mirrorPosition)
                {
                    //считаем сколько ходов назад это было
                    rating = parSolutionThree.Level - solutionNode.Level + 1;
                    break;
                }
                    //иначе
                else
                {
                    //и перемещаемся вверх по дереву.
                    solutionNode = solutionNode.Root;
                }
            }

            return rating;
        }
예제 #5
0
 /// <summary>
 /// Совершение хода
 /// </summary>
 /// <param name="parMove">Совершаемый ход</param>
 /// <param name="parSolutionThree">узел дерева, из которого совершаем ход</param>
 public override void MakeMove(Move parMove, SolutionThree parSolutionThree)
 {
     //активизируем поле
     _Task.Mirrors = GetMirrorsCopy(parMove.Mirrors);
     //проходим по всем зеркалам
     for (int i = 0; i < _Task.Mirrors.Count; i++)
     {
         //находим зеркало указанное в ходе и совершием ход
         if ((_Task.Mirrors[i].Left == parMove.FromPos.X) && (_Task.Mirrors[i].Top == parMove.FromPos.Y))
         {
             parMove.Mirrors[i] = new Square(parMove.ToPos.Y, parMove.ToPos.Y + LasersGame.COORDINATE_RATIO, parMove.ToPos.X, parMove.ToPos.X + LasersGame.COORDINATE_RATIO);
         }
     }
     _Task.Mirrors = GetMirrorsCopy(parMove.Mirrors);
     //пересчитываем траекторию лазера
     _Task.CalculateLaser();
 }
예제 #6
0
        /// <summary>
        /// Создать первый ход
        /// </summary>
        /// <returns></returns>
        public override Move CreateFirstMove()
        {
            Move firstMove = null;

            if (_Task.Mirrors.Count > 0)
            {
                firstMove = new Move(new Point(-1,-1), new Point (-1,-1), GetMirrorsCopy(_Task.Mirrors));
            }

            return firstMove;
        }
예제 #7
0
        /// <summary>
        /// Поиск по градиенту
        /// </summary>
        /// <param name="parMove">Ход</param>
        /// <param name="parSolutionThree">дерево решений</param>
        /// <returns>true если решение найдено, false в противном случае</returns>
        public bool SteepestRiseSolve(Move parMove, SolutionThree parSolutionThree)
        {
            //решение еще не найдено
            bool complete = false;
            //дерево решений
            SolutionThree solutionThree = parSolutionThree;
            //последний совершенный ход
            Move lastMove = solutionThree.Move;

            //если цель достигнута
            if (GoalIsReached(solutionThree))
            {
                complete = true;
                //записываем длину пути и получаем список ходов
                _Info.PathLenght = solutionThree.Level;
                _Info.MovesToGoal = GetMovesToGoal(solutionThree);
            }
            else
                // ессли тупик
                if (Deadlock(solutionThree))
                {
                    complete = false;
                }
                //если цель не достигнута и ситуация не тупиковая
                else
                {
                    //получаем список возможных ходщв
                    List<Move> availableMoves = GetAvailableMoves(solutionThree);

                    //упорядочиваем список возможных ходов согласно оценочной функции
                    SortMoves(availableMoves, solutionThree);

                    //проходим по всем узлам
                    for (int i = 0; i < availableMoves.Count; i++)
                    {
                        //совершаем очередной ход
                        MakeMove(availableMoves[i], solutionThree);

                        //добавляем узел в дерево решений
                        solutionThree.AddChildNode(availableMoves[i]);
                        _Info.GeneratedNodesCount++;

                        //Если уровень узла нового узла дерева больше чем сохраненный в логе,
                        if (solutionThree.ChildNodes[0].Level > _Info.MaxDepth)
                        {
                            //то записываем его в лог
                            _Info.MaxDepth = solutionThree.ChildNodes[0].Level;
                        }

                        // вызываем рекурсивный метод поиска в глубину
                        complete = SteepestRiseSolve(availableMoves[i], solutionThree.ChildNodes[0]);

                        //если решение было найдено
                        if (complete)
                        {
                            //заканчиваем просмотр
                            break;
                        }
                        //в противном случае
                        else
                        {
                            //отменяем ход и удаляем рассмотренную ветку дерева
                            CancelMove(availableMoves[i], solutionThree);
                            solutionThree.DeleteChildNode(0);
                        }

                    }
                }

            //возвращаем результат выполнения
            return complete;
        }
예제 #8
0
 /// <summary>
 /// Совершение хода
 /// </summary>
 /// <param name="parMove">Ход</param>
 /// <param name="parSolutionThree"> узелд дерева из которого совершается ход</param>
 public abstract void MakeMove(Move parMove, SolutionThree parSolutionThree);
예제 #9
0
 /// <summary>
 /// Оценочная функция
 /// </summary>
 /// <param name="parMove">оцениваемый ход</param>
 /// <param name="parSolutionThree"> узелд дерева из которого совершается ход</param>
 /// <returns>оценка хода</returns>
 public abstract int Estimator(Move parMove, SolutionThree parSolutionThree);
예제 #10
0
 /// <summary>
 /// Отмена хода
 /// </summary>
 /// <param name="parMove">Ход</param>
 /// <param name="parSolutionThree">узел дерева у которого отменяется ход</param>
 public abstract void CancelMove(Move parMove, SolutionThree parSolutionThree);