示例#1
0
 /// <summary>
 /// Конструктор класса
 /// </summary>
 /// <param name="parPosition">Положение на поле</param>
 /// <param name="parFirstHole">Первое отверстие </param>
 /// <param name="parSecondHole">Второе отверстие</param>
 /// <param name="parImage">Изображение трубы</param>
 public Pipe(Point parPosition, Orientation parFirstHole, Orientation parSecondHole, Bitmap parImage)
 {
     _Position = parPosition;
     _FirstHole = parFirstHole;
     _SecondHole = parSecondHole;
     _Image = parImage;
     _PartOfPath = false;
 }
示例#2
0
        private bool DepthSolve(Point parCurrentPoint, Orientation parDirection, SolutionThree parSolutionNode)
        {
            //решение еще не найдено
            bool complete = false;
            //добавляем узел в дерево решений
            SolutionThree solutionThree = parSolutionNode;
            //назначаем текущую точку
            Point currentPoint = parCurrentPoint;
            //назначаем направление движения
            Orientation direction = parDirection;
            //исходя из текущего положения и направления движения вычисляем следующую точку
            Point nextPoint = new Point(currentPoint.X + direction.X, currentPoint.Y + direction.Y);
            //Если следующая точка является точкой выхода,
            if (nextPoint == _Exit)
            {
                //то решение найдено, алгоритм завершен
                complete = true;
            }
            //если текущая труба вывела нас за границы поля
            else if ((nextPoint.X < 1) || (nextPoint.X > _ColCount) || (nextPoint.Y < 1) || (nextPoint.Y > _RowCount))
            {
                //тупик
                complete = false;

            }
            else
            {
                //если в следующей точки нету трубы
                if ((object) _Field[nextPoint.X, nextPoint.Y] == null)
                {
                    //тупик
                    complete = false;
                }
                //если в ледующей точке есть труба, то смотрим ее
                else
                {
                    //если следующая труба уже задействована в текущем рассматриваемом пути,
                    if (_Field[nextPoint.X, nextPoint.Y].PartOfPath == true)
                    {
                        //тупик
                        complete = false;
                    }
                    //если следующая труба еще не задействована
                    else
                    {
                        //получаем следующую трубу
                        Pipe nextPipe = _Field[nextPoint.X, nextPoint.Y];
                        //разворачиваем ее так, какой-то из ее входов выходил на текущую точку
                        nextPipe.RotateTo(currentPoint);
                        //добавляем в дерево решений новую ветку рассмотрения
                        solutionThree.AddChildNode(nextPipe.Clone(), currentPoint);
                        //получаем новое направление движение (куда смотрит второй вход следующей трубы)
                        Orientation nextDirection = direction;
                        if (direction == -nextPipe.FirstHole)
                        {
                            nextDirection = nextPipe.SecondHole.Clone();
                        }
                        else
                        {
                            nextDirection = nextPipe.FirstHole.Clone();
                        }
                        //помечаем, что труба занята в решении
                        nextPipe.PartOfPath = true;
                        //вызываем рекурсивный методи рассматриваем все со следующей точки со следующим направлением
                        complete = DepthSolve(nextPoint, nextDirection, solutionThree.ChildNodes[0]);
                        //если поиск в глубину завершился неудачей и поворачивать еще можно
                        //(т.е. следующая труба не прямая, ведь ее разворот приведет к томуже результату)
                        if ((complete == false) && (nextPipe.FirstHole != -nextPipe.SecondHole))
                        {
                            //удаляем текущую ветвь дерева решений
                            solutionThree.ChildNodes.RemoveAt(0);
                            //поворачиваем трубу второй раз, другим входом к текущей точке
                            nextPipe.RotateTo(currentPoint);
                            //добавляем в дерево решений новую ветвь
                            solutionThree.AddChildNode(nextPipe, currentPoint);
                            //вычисляем новое направление движения
                            if (direction == -nextPipe.FirstHole)
                            {
                                nextDirection = nextPipe.SecondHole;
                            }
                            else
                            {
                                nextDirection = nextPipe.FirstHole;
                            }
                            //и вызываем поиск в глубину в новом направлении (это уже второй вызов)
                            complete = DepthSolve(nextPoint, nextDirection, solutionThree.ChildNodes[0]);
                            //если и в эту сторону решение не находится
                            if (complete == false)
                            {
                                //то следующая труба - безперспективна
                                nextPipe.PartOfPath = false;
                            }
                        }
                    }
                }
            }

            return complete;
        }