Example #1
0
    IEnumerator GenerateMap(Map map, Location?endTitleLocation)
    {
        // начало создание главной дороги которая может периходить из карты в карту
        bool     isFinish = false;
        Location vectorRoad;
        Vector2  lastDiraction;

        if (endTitleLocation == null) // если у нас на прошлой карте не было перехода дороги на новую карту
        {
            if (Random.value >= 0.5)
            {
                map.cells[sizeMapX - 1, 0] = TypeOfCell.Road;
                vectorRoad = new Location(sizeMapX - 1, 0);
            }
            else
            {
                map.cells[(0), 0] = TypeOfCell.Road;
                vectorRoad        = new Location(0, 0);
            }
            lastDiraction = Vector2.zero;
        }
        else
        {
            map.cells[endTitleLocation.Value.x, 0] = TypeOfCell.Road;
            vectorRoad    = new Location(endTitleLocation.Value.x, 0);
            lastDiraction = Vector2.left;
        }

        // зацикливаем и случайно герерируем дорогу
        while (!isFinish)
        {
            if (lastDiraction == Vector2.left || lastDiraction == Vector2.right)
            {
                lastDiraction = Vector2.up;
            }
            else if (lastDiraction == Vector2.up)
            {
                float rand = Random.value;
                if (rand < 0.45)
                {
                    lastDiraction = Vector2.up;
                }
                else if (rand < 0.75)
                {
                    lastDiraction = Vector2.left;
                }
                else
                {
                    lastDiraction = Vector2.right;
                }
            }
            else if (lastDiraction == Vector2.zero)
            {
                if (vectorRoad.x == 0)
                {
                    lastDiraction = Vector2.right;
                }
                else
                {
                    lastDiraction = Vector2.left;
                }
            }

            int duration = Random.Range(2, 4);

            bool isWentAbroad = false;

            while (duration != 0)
            {
                if (lastDiraction == Vector2.left)
                {
                    if ((vectorRoad.x - 1) >= 0)
                    {
                        map.cells[(vectorRoad.x - 1), (vectorRoad.y)] = TypeOfCell.Road;
                        vectorRoad.x--;
                        if (vectorRoad.x == 0)
                        {
                            isWentAbroad = true;
                        }
                    }
                    else
                    {
                        isWentAbroad = true; break;
                    }
                }
                else if (lastDiraction == Vector2.up)
                {
                    if ((vectorRoad.y + 1) < sizeMapY)
                    {
                        map.cells[(vectorRoad.x), (vectorRoad.y + 1)] = TypeOfCell.Road;
                        vectorRoad.y++;
                    }
                    else
                    {
                        isFinish            = true;
                        map.endLocationRoad = vectorRoad;
                        break;
                    }
                }
                else if (lastDiraction == Vector2.right)
                {
                    if ((vectorRoad.x + 1) < sizeMapX)
                    {
                        map.cells[(vectorRoad.x + 1), (vectorRoad.y)] = TypeOfCell.Road;
                        vectorRoad.x++;
                        if (vectorRoad.x == (sizeMapX - 1))
                        {
                            isWentAbroad = true;
                        }
                    }
                    else
                    {
                        isWentAbroad = true; break;
                    }
                }

                duration--;
            }

            if (isWentAbroad)
            {
                if ((vectorRoad.y + 2) < sizeMapY - 2)
                {
                    if (Random.value >= 0.5)
                    {
                        map.cells[(sizeMapX - 1), (vectorRoad.y + 2)] = TypeOfCell.Road;
                        vectorRoad.x  = (sizeMapX - 1);
                        vectorRoad.y += 2;
                    }
                    else
                    {
                        map.cells[(0), (vectorRoad.y + 2)] = TypeOfCell.Road;
                        vectorRoad.x  = 0;
                        vectorRoad.y += 2;
                    }
                    lastDiraction = Vector2.zero;
                }
                else
                {
                    isFinish            = true;
                    map.endLocationRoad = null;
                }
            }

            if (vectorRoad.y >= sizeMapY - 1)
            {
                isFinish            = true;
                map.endLocationRoad = vectorRoad;
            }
            yield return(null);
        }
        // generate second road
        short roadLeft  = 0;
        short roadRight = 0;

        for (int i = 0; i < sizeMapX; i++)
        {
            for (int j = 0; j < sizeMapY; j++)
            {
                if (map.cells[i, j] == TypeOfCell.Road)
                {
                    if (i < (sizeMapX / 2) + 1)
                    {
                        roadLeft++;
                    }
                    else
                    {
                        roadRight++;
                    }
                }
            }
        }

        float leftKoef = ((float)(roadLeft) / (roadLeft + roadRight));
        byte  forExit  = 10;

        Location startLocation = new Location(0, 0);

        // счучайно генерируем точку и проверяем возможно ли там поставить дорогу
        while (forExit > 0)
        {
            if (Random.value >= leftKoef)
            {
                //left
                startLocation = new Location(Random.Range(1, (sizeMapX / 2) + 1), Random.Range(1, sizeMapY - 1));
            }
            else
            {
                //right
                startLocation = new Location(Random.Range((sizeMapX / 2) + 1, sizeMapX - 1), Random.Range(1, sizeMapY - 1));
            }

            CellInformation info = new CellInformation(map, startLocation, TypeOfCell.Road);

            if (info.IsAllEmpty() && map.cells[startLocation.x, startLocation.y] != TypeOfCell.Road)
            {
                map.cells[startLocation.x, startLocation.y] = TypeOfCell.SecondRoad;
                break;
            }
            else
            {
                forExit--;
            }
        }

        if (forExit == 0)
        {
            yield break;                // если у нас не нашло такой точки где свободно то на это карте не будет дополнительной дороги
        }
        Location firstCellSecondRoad = new Location();

        for (int rep = 0; rep < 2; rep++)   // от точки проводим 2 случайно генерации в стороны ( ибо точка центр дороги. А нам нужно начало иконец дороги)
        {
            bool     isEndGenerateSecondRoad = false;
            Vector2  roadDirection           = Vector2.zero;
            bool     isFirstTime             = true;
            Location currentLocation         = new Location(startLocation.x, startLocation.y);
            Location lastSecondRoad          = new Location(currentLocation.x, currentLocation.y);

            if (rep == 1)
            {
                map.cells[startLocation.x, startLocation.y]             = TypeOfCell.SecondRoad;
                map.cells[firstCellSecondRoad.x, firstCellSecondRoad.y] = TypeOfCell.SecondRoad;
                lastSecondRoad = firstCellSecondRoad;
            }


            while (!isEndGenerateSecondRoad)
            {
                CellInformation info         = new CellInformation(map, currentLocation, TypeOfCell.SecondRoad);
                List <Vector2>  random       = new List <Vector2>();
                int             roadDuration = Random.Range(2, 5);

                if (!info.isUp && currentLocation.y < map.cells.GetLength(1) - 3)
                {
                    random.Add(Vector2.up);
                    roadDuration = Random.Range(2, map.cells.GetLength(1) - 2 - currentLocation.y + 1);
                }
                if (!info.isDown && currentLocation.y > 2)
                {
                    random.Add(Vector2.down);
                    roadDuration = Random.Range(2, currentLocation.y);
                }
                if (!info.isRight)
                {
                    random.Add(Vector2.right);
                }
                if (!info.isLeft)
                {
                    random.Add(Vector2.left);
                }


                roadDirection = random[Random.Range(0, random.Count)];

                for (byte i = 0; i < roadDuration; i++)
                {
                    CellInformation cell       = new CellInformation(map, currentLocation, TypeOfCell.Road);
                    CellInformation cellSecond = new CellInformation(map, currentLocation, TypeOfCell.SecondRoad);
                    Location        nextLoc    = new Location(currentLocation.x + (int)roadDirection.x, (int)roadDirection.y + currentLocation.y);

                    if ((currentLocation.y == 1 && roadDirection == Vector2.down) || (currentLocation.y == (map.cells.GetLength(1) - 2) && roadDirection == Vector2.up))
                    {
                        break;
                    }

                    if (!cell.GetValueByVector(roadDirection) && !cellSecond.GetValueByVector(roadDirection) && !map.IsOutOfBounds(nextLoc))
                    {
                        if (cell.IsBlockNear(roadDirection))
                        {
                            map.cells[lastSecondRoad.x, lastSecondRoad.y]   = TypeOfCell.Road;
                            map.cells[currentLocation.x, currentLocation.y] = TypeOfCell.Road;
                            isEndGenerateSecondRoad = true;
                            break;
                        }
                        if (lastSecondRoad != currentLocation)
                        {
                            map.cells[lastSecondRoad.x, lastSecondRoad.y] = TypeOfCell.Road;
                        }
                        lastSecondRoad = currentLocation;

                        if (isFirstTime)
                        {
                            isFirstTime = false; firstCellSecondRoad = nextLoc;
                        }

                        map.cells[nextLoc.x, nextLoc.y] = TypeOfCell.SecondRoad;
                        currentLocation = nextLoc;
                    }
                    else
                    {
                        map.cells[lastSecondRoad.x, lastSecondRoad.y]   = TypeOfCell.Road;
                        map.cells[currentLocation.x, currentLocation.y] = TypeOfCell.Road;
                        isEndGenerateSecondRoad = true;
                    }
                }
                yield return(null);
            }
            yield return(null);
        }
    }