Beispiel #1
0
//---------------------------------------------------------СЕРДЦЕБИЕНИЕ--------------------------------------------------
    void Update()
    {
        //Проработка состояний:
        switch (state)
        {
        case aStarState.pause:
            if (clientList.Count > 0)
            {
                activeClient = clientList [0];
                state        = aStarState.find;
            }
            break;

        //команда расчитать путь:
        case aStarState.find:
            //Для каждого клиента в списке клиентов:
            //Выполняем поиск пути между ближайшими поинтами:
            StartCoroutine(findPath(activeClient));
            break;

        //сбрасываем текущее соcтояние
        case aStarState.founded:
            clientList.Remove(activeClient);
            activeClient = null;
            state        = aStarState.pause;
            break;
        }
    }
Beispiel #2
0
 // Метод приводит обьект этого класса в первоначальное состояние:
 public void astarClean()
 {
     allBox.Clear();
     mapPointList.Clear();
     mapBoxDictionary.Clear();
     mapPointDictionary.Clear();
     findFilter.Clear();
     state = aStarState.pause;
 }
Beispiel #3
0
    //---------------------------------------------------------СЕРДЦЕБИЕНИЕ--------------------------------------------------
    void Update()
    {
        //В любой момент можно запустить инициализацию:
        if (autoInit)
        {
            initialize();
        }

        //Проработка состояний:
        switch (state)
        {
        case aStarState.pause:
            if (clientList.Count > 0)
            {
                activeClient = clientList [0];
                findFilter.Clear();
                findFilter.Add(activeClient.my_patch_Filter);
                state = aStarState.find;
            }
            break;

        //команда расчитать путь:
        case aStarState.find:
            //Для каждого клиента в списке клиентов:
            //Выполняем поиск пути между ближайшими поинтами:
            StartCoroutine(findPath(activeClient));
            break;

        //сбрасываем текущее соcтояние
        case aStarState.founded:
            clientList.Remove(activeClient);
            activeClient = null;
            state        = aStarState.pause;
            break;
        }
    }
Beispiel #4
0
    //---------------------------------------------------PatchFORPoint-----------------------------------------------------
    //Для многопоточности требуется изменить метод под static(а так-же перенести переменные в clientPatch)
    public IEnumerator findPath(ClientPatch client)
    {
        if (mapPointList.Count > 0)
        {
            //Получаем поинты старта и финиша:
            Point start  = mapPointDictionary[Vector3toVector3i(client.lostPoint)];
            Point finish = mapPointDictionary[Vector3toVector3i(client.targetPosition.position)];

            found   = false;
            noroute = false;

            openList   = new List <Point>();                    //8 доступных ячеек для каждой(это в 2д пространстве), пополняется при выборе следующей точки с минимальной стоимостью окружающими ее
            closedList = new List <Point>();
            tmpList    = new List <Point>();

            //1) Добавляем стартовую клетку в открытый список.
            openList.Add(start);
            min = start;

            //2) Повторяем следующее:
            while (!found & !noroute)
            {      //пока путь еще не найден и не известно что пути не существует
                   //a) Ищем в открытом списке клетку с наименьшей стоимостью F. Делаем ее текущей клеткой.
                min = openList[0];
                int m = openList.Count;
                for (int k = 0; k < m; k++)
                {
                    Point point = openList[k];
                    // тут я специально тестировал, при < или <= выбираются разные пути,
                    // но суммарная стоимость G у них совершенно одинакова. Забавно, но так и должно быть.
                    if (point.F <= min.F)
                    {
                        min = point;
                    }
                }

                //b) Помещаем ее в закрытый список. (И удаляем с открытого)
                closedList.Add(min);
                openList.Remove(min);

                //c) Для каждой из соседних(min) 8-ми клеток(в нашем случае их может и не быть 8) ...
                tmpList.Clear();

                int otherx = 0;
                int othery = 0;
                int otherz = 0;

                int iteration = iterations;
                int i         = 0;

                Vector3i vector = Vector3i.zero;

                Point otherPoint;

                //идем от старта:
                //--------------------------------------------------FORWARD
                otherz = min.pointPosition.z + stepForward;
                //формируем позицию запроса
                vector.x = min.pointPosition.x;
                vector.y = min.pointPosition.y;
                vector.z = otherz;
                //Проверяем содержит ли коллекция поинт с такой позицией(если да то определяем его как поинт впереди)
                if (mapPointDictionary.ContainsKey(vector))
                {
                    otherPoint = mapPointDictionary[vector];
                    if (!closedList.Contains(otherPoint))
                    {
                        tmpList.Add(otherPoint);
                    }
                }

                //---------------------------------------------------BACK
                otherz = min.pointPosition.z - stepForward;
                //формируем позицию запроса
                vector.x = min.pointPosition.x;
                vector.y = min.pointPosition.y;
                vector.z = otherz;
                //Проверяем содержит ли коллекция поинт с такой позицией(если да то определяем его как поинт впереди)
                if (mapPointDictionary.ContainsKey(vector))
                {
                    otherPoint = mapPointDictionary[vector];
                    if (!closedList.Contains(otherPoint))
                    {
                        tmpList.Add(otherPoint);
                    }
                }

                //----------------------------------------------------RIGHT
                otherx = min.pointPosition.x + stepRight;
                //формируем позицию запроса
                vector.x = otherx;
                vector.y = min.pointPosition.y;
                vector.z = min.pointPosition.z;
                //Проверяем содержит ли коллекция поинт с такой позицией(если да то определяем его как поинт впереди)
                if (mapPointDictionary.ContainsKey(vector))
                {
                    otherPoint = mapPointDictionary[vector];
                    if (!closedList.Contains(otherPoint))
                    {
                        tmpList.Add(otherPoint);
                    }
                }

                //-----------------------------------------------------LEFT
                otherx = min.pointPosition.x - stepRight;
                //формируем позицию запроса
                vector.x = otherx;
                vector.y = min.pointPosition.y;
                vector.z = min.pointPosition.z;
                //Проверяем содержит ли коллекция поинт с такой позицией(если да то определяем его как поинт впереди)
                if (mapPointDictionary.ContainsKey(vector))
                {
                    otherPoint = mapPointDictionary[vector];
                    if (!closedList.Contains(otherPoint))
                    {
                        tmpList.Add(otherPoint);
                    }
                }

                if (find != typeFind.xz)
                {
                    //-----------------------------------------------------Up
                    othery = min.pointPosition.y + stepUp;
                    //формируем позицию запроса
                    vector.x = min.pointPosition.x;
                    vector.y = othery;
                    vector.z = min.pointPosition.z;
                    //Проверяем содержит ли коллекция поинт с такой позицией(если да то определяем его как поинт впереди)
                    if (mapPointDictionary.ContainsKey(vector))
                    {
                        otherPoint = mapPointDictionary[vector];
                        if (!closedList.Contains(otherPoint))
                        {
                            tmpList.Add(otherPoint);
                        }
                    }

                    //-----------------------------------------------------Down
                    othery = min.pointPosition.y - stepUp;
                    //формируем позицию запроса
                    vector.x = min.pointPosition.x;
                    vector.y = othery;
                    vector.z = min.pointPosition.z;
                    //Проверяем содержит ли коллекция поинт с такой позицией(если да то определяем его как поинт впереди)
                    if (mapPointDictionary.ContainsKey(vector))
                    {
                        otherPoint = mapPointDictionary[vector];
                        if (!closedList.Contains(otherPoint))
                        {
                            tmpList.Add(otherPoint);
                        }
                    }
                }

                //-------------------------------------------------------------------Движение по диагоналям------------------------------------------

                /*
                 *              //-----------------------------------------------------LEFT-FORWARD
                 *              otherx = min.pointTransform.position.x - stepRight;
                 *              otherz = min.pointTransform.position.z + stepForward;
                 *              //формируем позицию запроса
                 *              vector.x = otherx;
                 *              vector.y = min.pointTransform.position.y;
                 *              vector.z = otherz;
                 *              //Проверяем содержит ли коллекция поинт с такой позицией(если да то определяем его как поинт впереди)
                 *              if (mapPointDictionary.ContainsKey(vector))
                 *              {
                 *                  otherPoint = mapPointDictionary[vector];
                 *                  if (!closedList.Contains(otherPoint))
                 *                  {
                 *                      tmpList.Add(otherPoint);
                 *                  }
                 *              }
                 *
                 *              //-----------------------------------------------------RIGHT-FORWARD
                 *              //if point step right-forward(+x, +z)
                 *
                 *              otherx = min.pointTransform.position.x + stepRight;
                 *              otherz = min.pointTransform.position.z + stepForward;
                 *              //формируем позицию запроса
                 *              vector.x = otherx;
                 *              vector.y = min.pointTransform.position.y;
                 *              vector.z = otherz;
                 *              //Проверяем содержит ли коллекция поинт с такой позицией(если да то определяем его как поинт впереди)
                 *              if (mapPointDictionary.ContainsKey(vector))
                 *              {
                 *                  otherPoint = mapPointDictionary[vector];
                 *                  if (!closedList.Contains(otherPoint))
                 *                  {
                 *                      tmpList.Add(otherPoint);
                 *                  }
                 *              }
                 *
                 *              //------------------------------------------------------LEFT-BACK
                 *              //if point step left-back(-x, -z)
                 *              otherx = min.pointTransform.position.x - stepRight;
                 *              otherz = min.pointTransform.position.z - stepForward;
                 *              //формируем позицию запроса
                 *              vector.x = otherx;
                 *              vector.y = min.pointTransform.position.y;
                 *              vector.z = otherz;
                 *              //Проверяем содержит ли коллекция поинт с такой позицией(если да то определяем его как поинт впереди)
                 *              if (mapPointDictionary.ContainsKey(vector))
                 *              {
                 *                  otherPoint = mapPointDictionary[vector];
                 *                  if (!closedList.Contains(otherPoint))
                 *                  {
                 *                      tmpList.Add(otherPoint);
                 *                  }
                 *              }
                 *
                 *              //-------------------------------------------------------RIGHT-BACK
                 *              //if point step right-back(-x)
                 *              otherx = min.pointTransform.position.x + stepRight;
                 *              otherz = min.pointTransform.position.z - stepForward;
                 *              //формируем позицию запроса
                 *              vector.x = otherx;
                 *              vector.y = min.pointTransform.position.y;
                 *              vector.z = otherz;
                 *              //Проверяем содержит ли коллекция поинт с такой позицией(если да то определяем его как поинт впереди)
                 *              if (mapPointDictionary.ContainsKey(vector))
                 *              {
                 *                  otherPoint = mapPointDictionary[vector];
                 *                  if (!closedList.Contains(otherPoint))
                 *                  {
                 *                      tmpList.Add(otherPoint);
                 *                  }
                 *              }
                 */

                /*
                 *                  if (i == iteration)
                 *                  {
                 *                      iteration += iterations;
                 *                      yield return null;
                 *                  }
                 */
                //    }

                iteration = iterations;
                //После того как мы добавили в список tmpList окружающие min поинт поинты, выполняем следующее:
                for (i = 0; i < tmpList.Count; i += 1)
                {
                    Point neightbour = tmpList[i];

                    /*
                     * //foreach (Point neightbour in tmpList.ToArray()) {
                     * //Если клетка непроходимая или она находится в закрытом списке, игнорируем ее. В противном случае делаем следующее(похоже строчка не нужна).
                     * if (neightbour.type == Point.typePoint.blocked)
                     * {
                     *  continue;
                     * }
                     */

                    //Если Point дверь, то нужно предпринять следующие действия:
                    if (neightbour.type == Point.typePoint.door)
                    {
                        continue;
                    }

                    //Если клетка еще не в открытом списке, то добавляем ее туда. Делаем текущую клетку родительской для это клетки. Расчитываем стоимости F, G и H клетки.
                    if (!openList.Contains(neightbour))
                    {
                        openList.Add(neightbour);
                        neightbour.parent = min;
                        neightbour.H      = (int)neightbour.mandist(finish);                      //стоимость до итоговой точки
                        neightbour.G      = start.price(min);                                     //стоимость относительно прямой или диагонали
                        neightbour.F      = neightbour.H + neightbour.G;                          //суммарная стоимость
                        continue;
                    }
                    //Debug.Log ("this");
                    // Если клетка уже в открытом списке, то проверяем, не дешевле ли будет путь через эту клетку. Для сравнения используем стоимость G.
                    if (neightbour.G + neightbour.price(min) < min.G)
                    {
                        // Более низкая стоимость G указывает на то, что путь будет дешевле. Эсли это так, то меняем родителя клетки на текущую клетку и пересчитываем для нее стоимости G и F.
                        neightbour.parent = min; // вот тут я честно хз, надо ли min.parent или нет
                        neightbour.H      = (int)neightbour.mandist(finish);
                        neightbour.G      = start.price(min);
                        neightbour.F      = neightbour.H + neightbour.G;
                    }
                    if (i == iteration)
                    {
                        iteration += iterations;
                        yield return(null);
                    }
                    // Если вы сортируете открытый список по стоимости F, то вам надо отсортировать весь список в соответствии с изменениями.
                    //state = aStarState.founded;
                }

                //d) Останавливаемся если:
                //Добавили целевую клетку в открытый список, в этом случае путь найден.
                //Или открытый список пуст и мы не дошли до целевой клетки. В этом случае путь отсутствует.

                if (openList.Contains(finish))
                {
                    found = true;
                }

                if (openList.Count == 0)
                {
                    noroute = true;
                }
            }

            List <Point> completePatch = new List <Point>();
            //3) Сохраняем путь. Двигаясь назад от целевой точки, проходя от каждой точки к ее родителю до тех пор, пока не дойдем до стартовой точки. Это и будет наш путь.
            if (!noroute)
            {
                //формируем список возвращаемый клиенту(внимание список будет получен с конца(start в конце)а так-же необходимо отменить применение настроек):
                completePatch.Add(finish);
                Point rd = finish.parent;
                while (!rd.equals(start))
                {
                    completePatch.Add(rd);
                    rd = rd.parent;
                    if (rd == null)
                    {
                        break;
                    }
                }
                if (!completePatch.Contains(start))
                {
                    completePatch.Add(start);
                }
                client.patch = completePatch;                                   //Указываем клиенту список point которые следует пройти для начала

                /*
                 *              //Очищаем зависимости в поинтах:
                 *              foreach(Point p in client.mapPointList.ToArray()){
                 *                      p.parent = null;
                 *                      p.F = 0;
                 *                      p.G = 0;
                 *                      p.H = 0;
                 *                      p.myPrice = 0;
                 *              }
                 */
                //Debug.Log("Список поинтов установлен клиенту");
                min              = null;
                tmpList          = new List <Point>();
                openList         = new List <Point>();
                closedList       = new List <Point>();
                blockedPointList = new List <Point>();
            }
            else
            {
                client.patch     = new List <Point>();
                min              = null;
                tmpList          = new List <Point>();
                openList         = new List <Point>();
                closedList       = new List <Point>();
                blockedPointList = new List <Point>();
                //Очищаем зависимости в поинтах:

                /*
                 *              foreach(Point p in client.mapPointList.ToArray()){
                 *                      p.parent = null;
                 *                      p.F = 0;
                 *                      p.G = 0;
                 *                      p.H = 0;
                 *                      p.myPrice = 0;
                 *              }
                 */
                /*
                 * //обнуляем текущий приказ, мы дошли до места назначения
                 * if (client.unit.firstOrder != null)
                 * {
                 *  client.unit.firstOrder.complete = true;
                 * }
                 * //Debug.Log("Пути нет");
                 */
            }
            state = aStarState.founded;
        }
        else
        {
            Debug.Log("Список поинтов клиента пуст");
        }
    }
Beispiel #5
0
    //---------------------------------------------------PatchFORPoint-----------------------------------------------------
    //Для многопоточности требуется изменить метод под static(а так-же перенести переменные в clientPatch)
    public IEnumerator findPath(ClientPatch client)
    {
        if (mapPointList.Count > 0)
        {
            if (mapPointDictionary.ContainsKey(Vector3toVector3i(client.lostPointVector3D)) &&
                mapPointDictionary.ContainsKey(Vector3toVector3i(client.targetPosition.position)))
            {
                //Получаем поинты старта и финиша:
                Point start  = mapPointDictionary[Vector3toVector3i(client.lostPointVector3D)];
                Point finish = mapPointDictionary[Vector3toVector3i(client.targetPosition.position)];

                found   = false;
                noroute = false;

                openList   = new List <Point>();                    //8 доступных ячеек для каждой(это в 2д пространстве), пополняется при выборе следующей точки с минимальной стоимостью окружающими ее
                closedList = new List <Point>();
                tmpList    = new List <Point>();

                //1) Добавляем стартовую клетку в открытый список.
                openList.Add(start);
                min = start;

                //2) Повторяем следующее:
                while (!found & !noroute)
                {
                    //пока путь еще не найден и не известно что пути не существует
                    //a) Ищем в открытом списке клетку с наименьшей стоимостью F. Делаем ее текущей клеткой.
                    findFilter[0].min_searcher(this);

                    //b) Помещаем ее в закрытый список. (И удаляем с открытого)
                    closedList.Add(min);
                    openList.Remove(min);

                    //c) Для каждой из соседних(min) 8-ми клеток(в нашем случае их может и не быть 8) ...
                    tmpList.Clear();

                    int iteration = iterations;
                    int i         = 0;

                    //тут пробегаем по фильтрам:
                    for (int n = 0; n < findFilter.Count; n++)
                    {
                        PatchFilter nextFilter = findFilter[n];
                        nextFilter.filter(min, this);
                    }

                    iteration = iterations;
                    //После того как мы добавили в список tmpList окружающие min поинт поинты, выполняем следующее:
                    for (i = 0; i < tmpList.Count; i += 1)
                    {
                        Point neightbour = tmpList[i];

                        ///*
                        //Если клетка непроходимая или она находится в закрытом списке, игнорируем ее. В противном случае делаем следующее(похоже строчка не нужна).
                        if (neightbour.point_type == Point.typePoint.blocked && !activeClient.ignore_blocked)
                        {
                            continue;
                        }
                        //*/

                        //Если клетка еще не в открытом списке, то добавляем ее туда. Делаем текущую клетку родительской для это клетки. Расчитываем стоимости F, G и H клетки.
                        if (!openList.Contains(neightbour))
                        {
                            openList.Add(neightbour);
                            neightbour.parent = min;
                            neightbour.H      = (int)neightbour.mandist(finish);                      //стоимость до итоговой точки
                            neightbour.G      = start.price(min);                                     //стоимость относительно прямой или диагонали
                            neightbour.F      = neightbour.H + neightbour.G;                          //суммарная стоимость
                            continue;
                        }
                        // Если клетка уже в открытом списке, то проверяем, не дешевле ли будет путь через эту клетку. Для сравнения используем стоимость G.
                        if (neightbour.G + neightbour.price(min) < min.G)
                        {
                            // Более низкая стоимость G указывает на то, что путь будет дешевле. Эсли это так, то меняем родителя клетки на текущую клетку и пересчитываем для нее стоимости G и F.
                            neightbour.parent = min; // вот тут я честно хз, надо ли min.parent или нет
                            neightbour.H      = (int)neightbour.mandist(finish);
                            neightbour.G      = start.price(min);
                            neightbour.F      = neightbour.H + neightbour.G;
                        }
                        if (i == iteration)
                        {
                            iteration += iterations;
                            yield return(null);
                        }
                        // Если вы сортируете открытый список по стоимости F, то вам надо отсортировать весь список в соответствии с изменениями.
                    }

                    //d) Останавливаемся если:
                    //Добавили целевую клетку в открытый список, в этом случае путь найден.
                    //Или открытый список пуст и мы не дошли до целевой клетки. В этом случае путь отсутствует.

                    if (openList.Contains(finish))
                    {
                        found = true;
                    }

                    if (openList.Count == 0)
                    {
                        noroute = true;
                    }
                }

                List <Point> completePatch = new List <Point>();
                //3) Сохраняем путь. Двигаясь назад от целевой точки, проходя от каждой точки к ее родителю до тех пор, пока не дойдем до стартовой точки. Это и будет наш путь.
                if (!noroute)
                {
                    //формируем список возвращаемый клиенту(внимание список будет получен с конца(start в конце)а так-же необходимо отменить применение настроек):
                    completePatch.Add(finish);
                    Point rd = finish.parent;
                    while (!rd.equals(start))
                    {
                        completePatch.Add(rd);
                        rd = rd.parent;
                        if (rd == null)
                        {
                            break;
                        }
                    }
                    if (!completePatch.Contains(start))
                    {
                        completePatch.Add(start);
                    }
                    client.patch = completePatch;                                   //Указываем клиенту список point которые следует пройти для начала

                    min        = null;
                    tmpList    = new List <Point>();
                    openList   = new List <Point>();
                    closedList = new List <Point>();
                }
                else
                {
                    activeClient.patch_not_realy = true;
                    client.patch = new List <Point>();
                    min          = null;
                    tmpList      = new List <Point>();
                    openList     = new List <Point>();
                    closedList   = new List <Point>();
                }
                state = aStarState.founded;
            }
            else
            {
                //Debug.Log("Список поинтов клиента пуст");
            }
        }
        else
        {
            activeClient.patch_not_realy = true;
        }
    }