示例#1
0
        private void ConnectCloseCountriesOverWater(int maxDistance)
        {
            List <OceanConnection> oceanConnections = new List <OceanConnection>();

            foreach (Country source in Map.Countries)
            {
                foreach (Country target in Map.Countries)
                {
                    foreach (Point sourcePoint in source.AreaPixels)
                    {
                        foreach (Point targetPoint in target.AreaPixels)
                        {
                            if (source != target && !source.Neighbours.Contains(target) && !target.Neighbours.Contains(source) && !WithinWaterConnectionCountryRange(source, target))
                            {
                                int distance = (int)(Math.Sqrt((targetPoint.X - sourcePoint.X) * (targetPoint.X - sourcePoint.X) + ((targetPoint.Y - sourcePoint.Y) * (targetPoint.Y - sourcePoint.Y))));
                                if (distance <= maxDistance)
                                {
                                    // Found new short connection
                                    OceanConnection newConnection = new OceanConnection(distance, source, target, sourcePoint, targetPoint);

                                    // Check if not crossing land
                                    bool valid = true;
                                    int  steps = newConnection.Distance;
                                    for (int i = 0; i < steps; i++)
                                    {
                                        int targetX = (int)(newConnection.SourcePoint.X + ((newConnection.TargetPoint.X - newConnection.SourcePoint.X) / steps * i));
                                        int targetY = (int)(newConnection.SourcePoint.Y + ((newConnection.TargetPoint.Y - newConnection.SourcePoint.Y) / steps * i));
                                        if (!(Map.CountryMap[targetX, targetY] == MapPixelType.OCEAN || Map.CountryMap[targetX, targetY] == MapPixelType.BORDER || Map.CountryMap[targetX, targetY] == newConnection.SourceCountry.Id || Map.CountryMap[targetX, targetY] == newConnection.TargetCountry.Id))
                                        {
                                            valid = false;
                                        }
                                    }

                                    if (valid)
                                    {
                                        // Check if connection between those country exists
                                        if (oceanConnections.Where(x => source == x.SourceCountry && target == x.TargetCountry).Count() > 0)
                                        {
                                            OceanConnection oldCon = oceanConnections.Where(x => source == x.SourceCountry && target == x.TargetCountry).FirstOrDefault();
                                            if (distance < oldCon.Distance)
                                            {
                                                oceanConnections.Remove(oldCon);
                                                oceanConnections.Add(newConnection);
                                                newConnection.SourceCountry.AddNeighbour(newConnection.TargetCountry);
                                                newConnection.TargetCountry.AddNeighbour(newConnection.SourceCountry);
                                            }
                                        }
                                        else
                                        {
                                            oceanConnections.Add(newConnection);
                                            newConnection.SourceCountry.AddNeighbour(newConnection.TargetCountry);
                                            newConnection.TargetCountry.AddNeighbour(newConnection.SourceCountry);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            foreach (OceanConnection con in oceanConnections)
            {
                // Draw connection to map
                double startX = con.SourcePoint.X;
                double startY = con.SourcePoint.Y;
                double endX   = con.TargetPoint.X;
                double endY   = con.TargetPoint.Y;

                int circlesDrawn = 0;
                int steps        = con.Distance / 4;
                for (int i = 0; i < steps; i++)
                {
                    int targetX = (int)(startX + ((endX - startX) / steps * i));
                    int targetY = (int)(startY + ((endY - startY) / steps * i));
                    if (Map.CountryMap[targetX, targetY] == MapPixelType.OCEAN)
                    {
                        Map.GetWriteableBitmap().FillEllipseCentered(targetX, targetY, 1, 1, Color.FromArgb(255, 255, 0, 0));
                        circlesDrawn++;
                    }
                }
                if (circlesDrawn == 0)
                {
                    Map.GetWriteableBitmap().FillEllipseCentered((int)(startX + (endX - startX) / 2), (int)(startY + (endY - startY) / 2), 1, 1, Color.FromArgb(255, 255, 0, 0));
                }
            }

            Map.SetMap(MapGenerator.ConvertWriteableBitmapToBitmapImage(Map.GetWriteableBitmap()), false);
            RefreshMap();
        }
示例#2
0
        private void ConnectIslands()
        {
            List <HashSet <Country> > Clusters = new List <HashSet <Country> >();

            foreach (Country c in Map.Countries)
            {
                // Create new cluster if country is not in one
                if (Clusters.Where(x => x.Contains(c)).Count() == 0)
                {
                    HashSet <Country> newCluster = new HashSet <Country>();
                    newCluster.Add(c);
                    foreach (Country n in c.Neighbours)
                    {
                        newCluster.Add(n);
                    }
                    Clusters.Add(newCluster);
                }
                // Add to cluster if country already is in one
                else
                {
                    HashSet <Country> cluster = Clusters.Where(x => x.Contains(c)).First();
                    foreach (Country n in c.Neighbours)
                    {
                        cluster.Add(n);
                    }
                }
            }

            // Merge clusters
            List <Country> inMultipleClusters = Map.Countries.Where(x => (Clusters.Where(l => l.Contains(x)).Count() > 1)).ToList();

            foreach (Country c in inMultipleClusters)
            {
                List <HashSet <Country> > ClustersToMerge = Clusters.Where(l => l.Contains(c)).ToList();
                if (ClustersToMerge.Count > 1)
                {
                    HashSet <Country>         ClusterToKeep    = ClustersToMerge[0];
                    List <HashSet <Country> > ClustersToRemove = ClustersToMerge.Skip(1).ToList();
                    foreach (HashSet <Country> toRemove in ClustersToRemove)
                    {
                        foreach (Country c2 in toRemove)
                        {
                            ClusterToKeep.Add(c2);
                        }
                        Clusters.Remove(toRemove);
                    }
                }
            }

            // Connect clusters
            while (Clusters.Count > 1)
            {
                HashSet <Country>      clusterToConnect = Clusters[0];
                List <OceanConnection> connections      = new List <OceanConnection>();
                // Find nearest neighbours
                foreach (Country c1 in clusterToConnect)
                {
                    foreach (HashSet <Country> others in Clusters.Skip(1).ToList())
                    {
                        foreach (Country c2 in others)
                        {
                            foreach (Point p1 in c1.AreaPixels)
                            {
                                foreach (Point p2 in c2.AreaPixels)
                                {
                                    int distance = (int)(Math.Sqrt((p2.X - p1.X) * (p2.X - p1.X) + ((p2.Y - p1.Y) * (p2.Y - p1.Y))));
                                    if (connections.Count < islandConnections || distance < connections[0].Distance)
                                    {
                                        // Found new short connection
                                        OceanConnection newConnection = new OceanConnection(distance, c1, c2, p1, p2, others);

                                        // Check if not crossing land
                                        bool valid = true;
                                        int  steps = newConnection.Distance / 4;
                                        for (int i = 0; i < steps; i++)
                                        {
                                            int targetX = (int)(newConnection.SourcePoint.X + ((newConnection.TargetPoint.X - newConnection.SourcePoint.X) / steps * i));
                                            int targetY = (int)(newConnection.SourcePoint.Y + ((newConnection.TargetPoint.Y - newConnection.SourcePoint.Y) / steps * i));
                                            if (!(Map.CountryMap[targetX, targetY] == MapPixelType.OCEAN || Map.CountryMap[targetX, targetY] == MapPixelType.BORDER || Map.CountryMap[targetX, targetY] == newConnection.SourceCountry.Id || Map.CountryMap[targetX, targetY] == newConnection.TargetCountry.Id))
                                            {
                                                valid = false;
                                            }
                                        }

                                        if (valid)
                                        {
                                            // Check if connection between those country exists
                                            if (connections.Where(x => c1 == x.SourceCountry && c2 == x.TargetCountry).Count() > 0)
                                            {
                                                OceanConnection oldCon = connections.Where(x => c1 == x.SourceCountry && c2 == x.TargetCountry).FirstOrDefault();
                                                if (distance < oldCon.Distance)
                                                {
                                                    connections.Remove(oldCon);
                                                    connections.Add(newConnection);
                                                }
                                            }
                                            else
                                            {
                                                connections.Add(newConnection);
                                            }
                                            connections = connections.OrderBy(x => x.Distance).Take(islandConnections).OrderByDescending(x => x.Distance).ToList();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                // Add neighbours
                foreach (OceanConnection con in connections)
                {
                    con.SourceCountry.AddNeighbour(con.TargetCountry);
                    con.TargetCountry.AddNeighbour(con.SourceCountry);
                    foreach (Country c in con.TargetCluster)
                    {
                        clusterToConnect.Add(c);
                    }
                    Clusters.Remove(con.TargetCluster);

                    // Draw connection to map
                    double startX = con.SourcePoint.X;
                    double startY = con.SourcePoint.Y;
                    double endX   = con.TargetPoint.X;
                    double endY   = con.TargetPoint.Y;

                    int circlesDrawn = 0;
                    int steps        = con.Distance / 4;
                    for (int i = 0; i < steps; i++)
                    {
                        int targetX = (int)(startX + ((endX - startX) / steps * i));
                        int targetY = (int)(startY + ((endY - startY) / steps * i));
                        if (Map.CountryMap[targetX, targetY] == MapPixelType.OCEAN)
                        {
                            Map.GetWriteableBitmap().FillEllipseCentered(targetX, targetY, 1, 1, Color.FromArgb(255, 255, 0, 0));
                            circlesDrawn++;
                        }
                    }
                    if (circlesDrawn == 0)
                    {
                        Map.GetWriteableBitmap().FillEllipseCentered((int)(startX + (endX - startX) / 2), (int)(startY + (endY - startY) / 2), 1, 1, Color.FromArgb(255, 255, 0, 0));
                    }
                }


                Map.SetMap(MapGenerator.ConvertWriteableBitmapToBitmapImage(Map.GetWriteableBitmap()), false);
                RefreshMap();
            }
        }