public SimplexNoise_octave(int seed)
        {
            p = (short[])p_supply.Clone();

            InternalRandom rand;

            if (seed == RANDOMSEED)
            {
                rand = new InternalRandom();
                seed = rand.Next();
            }

            //the random for the swaps
            rand = new InternalRandom(seed);

            //the seed determines the swaps that occur between the default order and the order we're actually going to use
            for (int i = 0; i < NUMBEROFSWAPS; i++)
            {
                int swapFrom = rand.Next(p.Length - 1);
                int swapTo   = rand.Next(p.Length - 1);

                short temp = p[swapFrom];
                p[swapFrom] = p[swapTo];
                p[swapTo]   = temp;
            }


            for (int i = 0; i < 512; i++)
            {
                perm[i]      = p[i & 255];
                permMod12[i] = (short)(perm[i] % 12);
            }
        }
Beispiel #2
0
        private static List <Region> GetRegions(TimelineLayer timelineLayer, NamelessGame game, InternalRandom rand, Func <WorldTile, bool> searchCriterion, Action <WorldTile, Region> onFoundRegion, Func <string> nameGenerator)
        {
            List <Region> regions     = new List <Region>();
            var           searchPoint = new Microsoft.Xna.Framework.Point();

            for (; searchPoint.X < game.WorldSettings.WorldBoardWidth; searchPoint.X++)
            {
                for (searchPoint.Y = 0; searchPoint.Y < game.WorldSettings.WorldBoardHeight; searchPoint.Y++)
                {
                    if (searchCriterion(timelineLayer.WorldTiles[searchPoint.X, searchPoint.Y]))
                    {
                        Region r = new Region();
                        r.Name  = nameGenerator();
                        r.Color = new Color(rand.Next(0, 255), rand.Next(0, 255), rand.Next(0, 255), 1f);
                        regions.Add(r);

                        var firstNode = timelineLayer.WorldTiles[searchPoint.X, searchPoint.Y];

                        var floodList = new Queue <WorldTile>();
                        floodList.Enqueue(firstNode);
                        onFoundRegion(firstNode, r);
                        r.SizeInTiles++;

                        void AddToFloodList(int x, int y, Region region)
                        {
                            if (searchCriterion(timelineLayer.WorldTiles[x, y]))
                            {
                                floodList.Enqueue(timelineLayer.WorldTiles[x, y]);
                                onFoundRegion(timelineLayer.WorldTiles[x, y], region);
                                region.SizeInTiles++;
                            }
                        }

                        while (floodList.Any())
                        {
                            var elem = floodList.Dequeue();

                            AddToFloodList(elem.WorldBoardPosiiton.X - 1, elem.WorldBoardPosiiton.Y, r);
                            AddToFloodList(elem.WorldBoardPosiiton.X + 1, elem.WorldBoardPosiiton.Y, r);
                            AddToFloodList(elem.WorldBoardPosiiton.X, elem.WorldBoardPosiiton.Y - 1, r);
                            AddToFloodList(elem.WorldBoardPosiiton.X, elem.WorldBoardPosiiton.Y + 1, r);

                            AddToFloodList(elem.WorldBoardPosiiton.X - 1, elem.WorldBoardPosiiton.Y - 1, r);
                            AddToFloodList(elem.WorldBoardPosiiton.X + 1, elem.WorldBoardPosiiton.Y + 1, r);
                            AddToFloodList(elem.WorldBoardPosiiton.X + 1, elem.WorldBoardPosiiton.Y - 1, r);
                            AddToFloodList(elem.WorldBoardPosiiton.X - 1, elem.WorldBoardPosiiton.Y + 1, r);
                        }
                    }
                }
            }

            return(regions);
        }
        public static void RiverBordersWriteImage(List <List <TileForGeneration> > riverBorders, float[][] heights, int resolution, string path)
        {
            var img = new System.Drawing.Bitmap(resolution, resolution, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            for (int y = 0; y < resolution; y++)
            {
                for (int x = 0; x < resolution; x++)
                {
                    var colorRGB = (float)heights[x][y];

                    if (heights[x][y] > 1)
                    {
                        colorRGB = 1;
                    }

                    if (heights[x][y] <= TileNoiseInterpreter.SeaLevelThreshold)
                    {
                        colorRGB = 0;
                    }

                    var col = new Color(colorRGB, colorRGB, colorRGB, 1f);
                    img.SetPixel(x, resolution - 1 - y, col.ToColor());
                }
            }

            var random = new InternalRandom();

            foreach (var riverBorder in riverBorders)
            {
                var color = new Color(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255), 1f);
                foreach (var tileForGeneration in riverBorder)
                {
                    img.SetPixel(tileForGeneration.x, resolution - 1 - tileForGeneration.y, color.ToColor());
                }
            }

            img.Save(path);


            // Texture2D tex = new Texture2D(NamelessGame.DebugDevice, resolution, resolution, false, SurfaceFormat.Color);
            //tex.SetData(arrBytes);



            //using (var str = File.OpenWrite(path))
            //{
            //    tex.SaveAsPng(str, resolution, resolution);
            //}
            //tex.Dispose();
        }
        public string GetTownName(InternalRandom random)
        {
            if (townChain == null)
            {
                List <string> townList = TownNames.ToLower().Split(' ').ToList();
                foreach (var str in townList)
                {
                    townChain.Add(str);
                }
            }

            return(new string(townChain.Chain(random.Next()).ToArray()).FirstCharToUpper());
        }
Beispiel #5
0
        public SimplexNoise(int largestFeature, double persistence, InternalRandom rnd)
        {
            this.largestFeature = largestFeature;
            this.persistence    = persistence;

            //recieves a number (eg 128) and calculates what power of 2 it is (eg 2^7)
            int numberOfOctaves = (int)Math.Ceiling(Math.Log10(largestFeature) / Math.Log10(2));

            octaves    = new SimplexNoise_octave[numberOfOctaves];
            frequencys = new double[numberOfOctaves];
            amplitudes = new double[numberOfOctaves];


            for (int i = 0; i < numberOfOctaves; i++)
            {
                octaves[i] = new SimplexNoise_octave(rnd.Next());

                frequencys[i] = Math.Pow(2, i);
                amplitudes[i] = Math.Pow(persistence, octaves.Length - i);
            }
        }
 public ItemsGenerator(InternalRandom random)
 {
     this.random = new InternalRandom(random.Next());
 }
Beispiel #7
0
 public string GetCountryName(InternalRandom random)
 {
     return(new string(countryChain.Chain(random.Next()).ToArray()));
 }
Beispiel #8
0
        public static void PlaceInitialCivilizations(TimelineLayer timelineLayer, NamelessGame game)
        {
            var worldSettingsContinentTilesPerCivilization = game.WorldSettings.ContinentTilesPerCivilization;

            foreach (var worldBoardContinent in timelineLayer.Continents)
            {
                var civNumber = worldBoardContinent.SizeInTiles / worldSettingsContinentTilesPerCivilization;

                var continentTiles = new Queue <WorldTile>();

                foreach (var worldBoardWorldTile in timelineLayer.WorldTiles)
                {
                    if (worldBoardWorldTile.Continent == worldBoardContinent && worldBoardWorldTile.Terrain != TerrainTypes.Water && worldBoardWorldTile.Owner == null)
                    {
                        continentTiles.Enqueue(worldBoardWorldTile);
                    }
                }
                //randomize list
                continentTiles = new Queue <WorldTile>(continentTiles.OrderBy(
                                                           (o) =>
                {
                    return(game.WorldSettings.GlobalRandom.Next() % continentTiles.Count);
                }));

                InternalRandom random = new InternalRandom(game.WorldSettings.GlobalRandom.Next(int.MaxValue - 1));

                for (int i = 0; i < civNumber; i++)
                {
                    bool   civNameUnique = false;
                    string civName       = "";
                    while (!civNameUnique)
                    {
                        civName       = game.WorldSettings.NamesGenerator.GetCountryName(random).FirstCharToUpper();
                        civNameUnique = timelineLayer.Civilizations.All(x => x.Name != civName);
                    }

                    CultureTemplate culture = game.WorldSettings.CultureTemplates[
                        random.Next(game.WorldSettings.CultureTemplates.Count - 1)];

                    var civilization = new Civilization(civName, new Microsoft.Xna.Framework.Color(
                                                            new Vector4((float)random.Next(0, 100) / 100,
                                                                        (float)random.Next(0, 100) / 100,
                                                                        (float)random.Next(0, 100) / 100, 1)),
                                                        culture);
                    timelineLayer.Civilizations.Add(civilization);


                    var firstSettlement = new Settlement()
                    {
                        Name = civilization.CultureTemplate.GetTownName(random)
                    };

                    civilization.Settlements.Add(firstSettlement);



                    WorldTile tile = null;
                    bool      noNeighbooringCivs = false;
                    const int squareToCheck      = 10;
                    const int radiusToClaim      = 7;
                    while (!noNeighbooringCivs)
                    {
                        if (!continentTiles.Any())
                        {
                            break;
                        }

                        tile = continentTiles.Dequeue();
                        noNeighbooringCivs = true;
                        for (int x = tile.WorldBoardPosiiton.X - squareToCheck; x <= tile.WorldBoardPosiiton.X + squareToCheck; x++)
                        {
                            for (int y = tile.WorldBoardPosiiton.Y - squareToCheck; y <= tile.WorldBoardPosiiton.Y + squareToCheck; y++)
                            {
                                if (timelineLayer.WorldTiles[x, y].Owner != null)
                                {
                                    noNeighbooringCivs = false;
                                }
                            }
                        }
                    }


                    //if there is no tiles to place civilizations then break the loop
                    if (!continentTiles.Any())
                    {
                        break;
                    }


                    timelineLayer.Civilizations.Add(civilization);

                    tile.Settlement = firstSettlement;



                    for (int x = tile.WorldBoardPosiiton.X - radiusToClaim; x <= tile.WorldBoardPosiiton.X + radiusToClaim; x++)
                    {
                        for (int y = tile.WorldBoardPosiiton.Y - radiusToClaim; y <= tile.WorldBoardPosiiton.Y + radiusToClaim; y++)
                        {
                            var dX = x - tile.WorldBoardPosiiton.X;
                            var dY = y - tile.WorldBoardPosiiton.Y;

                            if (dX * dX + dY * dY <= (radiusToClaim))
                            {
                                timelineLayer.WorldTiles[x, y].Owner = civilization;
                            }
                        }
                    }
                }

                // var names = timelineLayer.Civilizations.Select(x => x.Name).Aggregate((s1, s2) => s1 + ", " + s2);
            }
        }
Beispiel #9
0
        public static void PopulateWithInitialData(TimelineLayer board, NamelessGame game)
        {
            var resolution = WorldGenConstants.Resolution;

            var random = new InternalRandom(game.WorldSettings.GlobalRandom.Next());


            for (int x = 0; x < game.WorldSettings.WorldBoardWidth; x++)
            {
                for (int y = 0; y < game.WorldSettings.WorldBoardHeight; y++)
                {
                    var worldTile = new WorldTile(new Microsoft.Xna.Framework.Point(x, y));
                    var tile      = game.WorldSettings.TerrainGen.GetTileWithoutRiverWater(x, y, (float)game.WorldSettings.WorldBoardWidth / resolution);
                    worldTile.Terrain = tile.Terrain;
                    worldTile.Biome   = tile.Biome;

                    board.WorldTiles[x, y] = worldTile;
                }
            }


            //generate elevation map for river gen
            for (int i = 0; i < resolution; i++)
            {
                for (int j = 0; j < resolution; j++)
                {
                    //fill it with terrain heght with current noises using resolution
                    board.ElevationMap[i][j] = game.WorldSettings.TerrainGen.GetHeightNoise(i, j, 1);
                }
            }

            //copy elevationArray
            var fillArray = new TileForGeneration[resolution][];

            for (int i = 0; i < resolution; i++)
            {
                fillArray[i] = new TileForGeneration[resolution];
                for (int j = 0; j < resolution; j++)
                {
                    fillArray[i][j] = new TileForGeneration()
                    {
                        fillValue = board.ElevationMap[i][j], x = i, y = j, isWater = false
                    };
                }
            }

            List <FortuneSite> points = new List <FortuneSite>();
            LinkedList <VEdge> edges  = new LinkedList <VEdge>();

            for (var i = 0; i < resolution; i++)
            {
                points.Add(new FortuneSite(
                               random.Next(0, resolution - 1),
                               random.Next(0, resolution - 1)));
            }

            //uniq the points
            points.Sort((p1, p2) =>
            {
                if (p1.X.ApproxEqual(p2.X))
                {
                    if (p1.Y.ApproxEqual(p2.Y))
                    {
                        return(0);
                    }
                    if (p1.Y < p2.Y)
                    {
                        return(-1);
                    }
                    return(1);
                }
                if (p1.X < p2.X)
                {
                    return(-1);
                }
                return(1);
            });

            var unique = new List <FortuneSite>(points.Count / 2);
            var last   = points.First();

            unique.Add(last);
            for (var index = 1; index < points.Count; index++)
            {
                var point = points[index];
                if (!last.X.ApproxEqual(point.X) ||
                    !last.Y.ApproxEqual(point.Y))
                {
                    unique.Add(point);
                    last = point;
                }
            }
            points = unique;

            edges = FortunesAlgorithm.Run(points, 0, 0, resolution - 1, resolution - 1);

            //VEdge.Start is a VPoint with location VEdge.Start.X and VEdge.End.Y
            //VEdge.End is the ending point for the edge
            //FortuneSite.Neighbors contains the site's neighbors in the Delaunay Triangulation


            var waterBitmap = new Bitmap(resolution, resolution);

            var graphics = Graphics.FromImage(waterBitmap);

            Pen whitePen = new Pen(System.Drawing.Color.White, 1);

            var edgesByTheSea = edges.Where(
                x =>
                board.ElevationMap[(int)x.Start.X][(int)x.Start.Y] < TileNoiseInterpreter.SeaLevelThreshold &&
                board.ElevationMap[(int)x.End.X][(int)x.End.Y] >= TileNoiseInterpreter.SeaLevelThreshold ||

                board.ElevationMap[(int)x.End.X][(int)x.End.Y] < TileNoiseInterpreter.SeaLevelThreshold &&
                board.ElevationMap[(int)x.Start.X][(int)x.Start.Y] >= TileNoiseInterpreter.SeaLevelThreshold
                );

            var allInlandEdges = edges.Where(
                x =>
                board.ElevationMap[(int)x.End.X][(int)x.End.Y] >= TileNoiseInterpreter.SeaLevelThreshold &&
                board.ElevationMap[(int)x.Start.X][(int)x.Start.Y] >= TileNoiseInterpreter.SeaLevelThreshold
                ).ToList();

            //randommly remove some rivers;
            var cullingChance = 15;
            var culledEdges   = allInlandEdges.Where(edge => random.Next(1, 101) > cullingChance).ToList();

            culledEdges.AddRange(edgesByTheSea.Where(edge => random.Next(1, 101) > cullingChance));

            //remove desert rivers with high probability
            var cullingDesertChance = 90;

            //if not in desert biome ignore, if in desert, cull with high probability
            culledEdges = culledEdges.Where(edge =>
                                            (board.WorldTiles[(int)edge.Start.X, (int)edge.Start.Y].Biome.HasFlag(Biomes.Desert | Biomes.Jungle | Biomes.Savannah) &&
                                             board.WorldTiles[(int)edge.End.X, (int)edge.End.Y].Biome.HasFlag(Biomes.Desert | Biomes.Jungle | Biomes.Savannah)) ||
                                            random.Next(1, 101) < cullingDesertChance).ToList();

            var finalEdges = new List <VEdge>();

            finalEdges.AddRange(culledEdges);

            foreach (var edge in finalEdges)
            {
                var pointCountForLerpAndRandomization = 7;

                var listVectorEdgePoints = new List <Vector2>();
                var startVector          = new Vector2((float)edge.Start.X, (float)edge.Start.Y);
                var endVector            = new Vector2((float)edge.End.X, (float)edge.End.Y);
                var perpendicular        = (endVector - startVector);
                perpendicular.Normalize();
                perpendicular = new Vector2(perpendicular.Y, -perpendicular.X);



                listVectorEdgePoints.Add(startVector);

                var riverWiggle = 3;

                for (int i = 1; i < pointCountForLerpAndRandomization - 1; i++)
                {
                    var newPoint = Vector2.Lerp(startVector, endVector, ((float)i / (pointCountForLerpAndRandomization - 1))) + (perpendicular * (random.Next(-riverWiggle, riverWiggle)));
                    listVectorEdgePoints.Add(newPoint);
                }
                listVectorEdgePoints.Add(endVector);

                graphics.DrawCurve(whitePen, listVectorEdgePoints.Select(x => x.ToPoint().ToPoint()).ToArray());
            }

            for (int x = 3; x < resolution - 3; x++)
            {
                for (int y = 3; y < resolution - 3; y++)
                {
                    if (waterBitmap.GetPixel(x, y).R > 0)
                    {
                        //fillArray[x][y].isWater = true;

                        if (board.ElevationMap[x][y] >= TileNoiseInterpreter.SeaLevelThreshold)
                        {
                            fillArray[x][y].isWater = true;
                        }
                        else
                        {
                            Queue <TileForGeneration> neighbours = new Queue <TileForGeneration>();
                            GenerationUtility.GetNeighbours(fillArray, neighbours, x, y, 2);
                            if (neighbours.Any(n => board.ElevationMap[n.x][n.y] >= TileNoiseInterpreter.SeaLevelThreshold))
                            {
                                fillArray[x][y].isWater = true;
                            }
                        }
                    }
                }
            }


            for (int i = 0; i < resolution; i++)
            {
                for (int j = 0; j < resolution; j++)
                {
                    board.RiverMap[i][j] = fillArray[i][j].isWater;
                }
            }

            var riverBorderMapCopyForCalcultaion = new bool[resolution][];

            for (int i = 0; i < resolution; i++)
            {
                riverBorderMapCopyForCalcultaion[i] = new bool[resolution];
                for (int j = 0; j < resolution; j++)
                {
                    if (board.RiverMap[i][j])
                    {
                        bool borderedByAnythingBesidesWater = false;
                        //not really a radius, more like an side lenght of a square
                        var searchRadius = 3;
                        if (i > searchRadius && i < resolution - searchRadius && j > searchRadius && j < resolution - searchRadius)
                        {
                            for (int k = i - searchRadius; k < i + searchRadius + 1; k++)
                            {
                                for (int l = j - searchRadius; l < j + searchRadius + 1; l++)
                                {
                                    if (!board.RiverMap[k][l])
                                    {
                                        borderedByAnythingBesidesWater = true;
                                    }
                                }
                            }
                        }

                        if (borderedByAnythingBesidesWater)
                        {
                            board.RiverBorderMap[i][j]             = true;
                            riverBorderMapCopyForCalcultaion[i][j] = true;
                        }
                    }
                }
            }


            var pointsNotConnectedToStartingPoints = new List <TileForGeneration>();

            for (int i = 0; i < resolution; i++)
            {
                for (int j = 0; j < resolution; j++)
                {
                    if (board.RiverBorderMap[i][j])
                    {
                        pointsNotConnectedToStartingPoints.Add(fillArray[i][j]);
                    }
                }
            }


            GenerationUtility.AnalyzeAndAddLines(pointsNotConnectedToStartingPoints, riverBorderMapCopyForCalcultaion, out var borderLines);


            for (int i = 0; i < resolution; i++)
            {
                for (int j = 0; j < resolution; j++)
                {
                    board.InlandWaterConnectivity[i][j] = new TileForInlandWaterConnectivity()
                    {
                        x       = i,
                        y       = j,
                        isWater = board.RiverMap[i][j]
                    };
                }
            }

            foreach (var borderLine in borderLines)
            {
                var line = new WaterBorderLine()
                {
                    Points = borderLine.Select(p => new Microsoft.Xna.Framework.Point(p.x, p.y)).ToList()
                };
                board.BorderLines.Add(line);
                foreach (var p in line.Points)
                {
                    board.InlandWaterConnectivity[p.X][p.Y].WaterBorderLines.Add(line);
                }
            }
#if DEBUG
            ImageWriter.WaterWriteImage(board.RiverMap, board.ElevationMap, resolution, "C:\\11\\RiverMap.png", new Color(1, 0, 0, 1f));

            ImageWriter.WaterWriteImage(board.RiverBorderMap, board.ElevationMap, resolution, "C:\\11\\RiverBorderMap.png", new Color(1, 0, 0, 1f));

            ImageWriter.RiverBordersWriteImage(borderLines, board.ElevationMap, resolution, "C:\\11\\riverBordersLines.png");
#endif

            for (int x = 0; x < game.WorldSettings.WorldBoardWidth; x++)
            {
                for (int y = 0; y < game.WorldSettings.WorldBoardHeight; y++)
                {
                    var worldTile = board.WorldTiles[x, y];

                    if (board.RiverMap[x][y] && worldTile.Terrain != TerrainTypes.Water)
                    {
                        worldTile.Terrain = TerrainTypes.Water;
                        worldTile.Biome   = Biomes.River;
                    }
                }
            }
        }
Beispiel #10
0
 /// <summary>
 /// Flips a coin.
 /// </summary>
 /// <returns><b>True</b> if Heads; <b>False</b> otherwise (i.e. Tails).</returns>
 public bool HeadsOrTails()
 {
     return(InternalRandom.Next(0, 2) == 1);
 }