Esempio n. 1
0
        public void SetupMap(double PerlinDiff, double Seed, double HeightBias, double Zoom)
        {
            map = new MapTile[width, height];

            PerlinNoise p = new PerlinNoise();

            //Generate tiles
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    //Map generation
                    //Calculate perlin
                    double mHeight = p.perlin(x * PerlinDiff, y * PerlinDiff, Seed);

                    //Modify perlin value for more extremes
                    mHeight = mHeight * Zoom - HeightBias;
                    mHeight = mHeight < 0 ? 0 : mHeight; //Remove negative values
                    mHeight = mHeight > 1 ? 1 : mHeight; //Remove values larger than 1

                    MapTileTypeEnum mapTileEnum = MapTileTypeEnum.land;

                    if (mHeight < 0.2)
                    {
                        mapTileEnum = MapTileTypeEnum.deepWater;
                    }
                    else if (mHeight < 0.4)
                    {
                        mapTileEnum = MapTileTypeEnum.shallowWater;
                    }
                    else if (mHeight < 0.6)
                    {
                        mapTileEnum = MapTileTypeEnum.land;
                    }
                    else if (mHeight < 0.8)
                    {
                        mapTileEnum = MapTileTypeEnum.hill;
                    }
                    else if (mHeight <= 1.0)
                    {
                        mapTileEnum = MapTileTypeEnum.mountain;
                    }

                    map[x, y] = new MapTile(new Point(x, y), new MapTileType
                    {
                        type = mapTileEnum
                    }, mHeight);
                }
            }

            //Add neighbours as they are now initialised
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    map[x, y].GetNeighbours(this);
                }
            }

            //Generate continents
            int    counter        = 0;
            Random colorGenerator = new Random();

            continents = new List <Continent>();
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (map[x, y].continent == null)
                    {
                        Continent continent = new Continent();
                        map = continent.NewContinent(this, new Point(x, y), counter++.ToString(), colorGenerator).map;
                        continents.Add(continent);
                    }
                }
            }

            //Find largest land continent for road TODO: Do this for all continents of certain size
            int       maxSize      = 0;
            Continent maxContinent = new Continent();

            foreach (Continent continent in continents)
            {
                if (continent.Type == MapTileTypeEnum.land && maxSize < continent.tiles.Count)
                {
                    maxSize      = continent.tiles.Count;
                    maxContinent = continent;
                }
            }
            maxContinent.color = Color.Black;

            //TODO: For edges in continents find all the different zones, not only side
            //TODO: Create a road between each of the zones
            goals = new List <MapTile>();
            while (true)
            {
                if (maxContinent.edges.top.Count != 0)
                {
                    MapTile toAdd = maxContinent.edges.top[colorGenerator.Next(maxContinent.edges.top.Count)];
                    if (!goals.Contains(toAdd))
                    {
                        goals.Add(toAdd);
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            while (true)
            {
                if (maxContinent.edges.bottom.Count != 0)
                {
                    MapTile toAdd = maxContinent.edges.bottom[colorGenerator.Next(maxContinent.edges.bottom.Count)];
                    if (!goals.Contains(toAdd))
                    {
                        goals.Add(toAdd);
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            while (true)
            {
                if (maxContinent.edges.left.Count != 0)
                {
                    MapTile toAdd = maxContinent.edges.left[colorGenerator.Next(maxContinent.edges.left.Count)];
                    if (!goals.Contains(toAdd))
                    {
                        goals.Add(toAdd);
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            while (true)
            {
                if (maxContinent.edges.right.Count != 0)
                {
                    MapTile toAdd = maxContinent.edges.right[colorGenerator.Next(maxContinent.edges.right.Count)];
                    if (!goals.Contains(toAdd))
                    {
                        goals.Add(toAdd);
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            //Skip code to create path when there are to few goals
            if (goals.Count <= 1)
            {
                return;
            }
            for (int x = 0; x <= map.GetUpperBound(0); x++)
            {
                for (int y = 0; y <= map.GetUpperBound(1); y++)
                {
                    map[x, y].InitialiseDistances(goals.Count);
                    map[x, y].GoalIDs = goals.ConvertAll(g => g.id).ToArray();
                    for (int i = 0; i < goals.Count; i++)
                    {
                        map[x, y].Costs[i] = -1;
                    }
                }
            }

            CalculateCost(ref map);

            //Path creation
            List <MapTile> toDraw          = new List <MapTile>(goals);
            int            positionsLength = toDraw.Count;
            IEnumerable <IEnumerable <int> > rawPossibilites = GetPermutations(Enumerable.Range(0, positionsLength).ToList(), positionsLength);
            List <List <int> > possibilites = rawPossibilites.ToList().ConvertAll(i => i.ToList());

            //Save shortest path
            double shortestLength = double.MaxValue;

            MapTile[] shortestGoals = new MapTile[positionsLength];
            //Calculate the length of each path option
            foreach (IEnumerable <int> possibility in possibilites)
            {
                //Generate order
                MapTile[] order = new MapTile[positionsLength];
                foreach (int index in possibility)
                {
                    order[index] = toDraw[index];
                }
                //Initialise variables for path finding
                //Copy map
                MapTile[,] localMap = new MapTile[map.GetUpperBound(0) + 1, map.GetUpperBound(1) + 1];

                for (int x = 0; x <= map.GetUpperBound(0); x++)
                {
                    for (int y = 0; y <= map.GetUpperBound(1); y++)
                    {
                        localMap[x, y] = (MapTile)map[x, y].Clone();
                    }
                }

                double         length     = 0;
                List <MapTile> localGoals = order.ToList();
                localGoals.RemoveAt(0);
                //Calculate path length
                FindPath(order.ToList(), ref localMap, ref length, localGoals.ToArray());

                //Check if shortest
                if (length < shortestLength)
                {
                    shortestLength = length;
                    shortestGoals  = order;
                }
            }

            //Draw path
            pathLength = 0;
            //This is starting position
            toDraw.Remove(goals[0]);
            FindPath(shortestGoals.ToList(), ref map, ref pathLength, goals.ToArray());

            //Clean up path
            //CleanPath();
        }
Esempio n. 2
0
        public Map NewContinent(Map map, Point point, string ID, Random rng)
        {
            color = Color.FromArgb(100, rng.Next(255), rng.Next(255), rng.Next(255));
            id    = ID;

            MapTile activeTile = map.map[point.X, point.Y];

            Type = activeTile.type.type;
            map.map[point.X, point.Y].isBeingChecked = true;

            toCheck = new List <MapTile>();
            tiles   = new List <MapTile>();
            //Find tiles
            while (true)
            {
                //Add new tiles to continent
                List <MapTile> neighbours = activeTile.neighbours.GetSameType(Type);
                if (neighbours.Count != 0)
                {
                    foreach (MapTile tile in neighbours)
                    {
                        map.map[tile.position.X, tile.position.Y].isBeingChecked = true;
                    }
                    toCheck.AddRange(neighbours);
                }
                tiles.Add(map.map[activeTile.position.X, activeTile.position.Y]);
                map.map[activeTile.position.X, activeTile.position.Y].continent = this;
                //Choose new tile
                if (toCheck.Count != 0)
                {
                    activeTile = toCheck[0];
                    toCheck.RemoveAt(0);
                }
                //End
                else
                {
                    break;
                }
            }

            //Find edges
            List <MapTile> top    = new List <MapTile>();
            List <MapTile> bottom = new List <MapTile>();
            List <MapTile> left   = new List <MapTile>();
            List <MapTile> right  = new List <MapTile>();

            foreach (MapTile tile in tiles)
            {
                if (tile.position.X == 0)
                {
                    left.Add(tile);
                }
                if (tile.position.X == map.map.GetUpperBound(0))
                {
                    right.Add(tile);
                }
                if (tile.position.Y == 0)
                {
                    top.Add(tile);
                }
                if (tile.position.Y == map.map.GetUpperBound(1))
                {
                    bottom.Add(tile);
                }
            }
            edges = new EdgeArray(top.ToArray(), bottom.ToArray(), left.ToArray(), right.ToArray());

            return(map);
        }