Ejemplo n.º 1
0
        static void GenerateSmart(string filepath)
        {
            int       w = 30, h = 20, rooms = 20;
            const int numheroes = 5;

            MapBlueprint map = new MapBlueprint();

            map.StartRoomId = 1;
            map.Encoding    = new byte[w, h][];

            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    map.Encoding[x, y] = new byte[3];
                }
            }

            Rectangle[] initialRooms = new Rectangle[rooms];
            Random      rnd          = new Random();

            /*int maxW = (int)(w * 2f / rooms);
            *  int maxH = (int)(h * 2f / rooms);*/
            int maxW = 7, maxH = 7;
            int index = 0;

            /*do
             *  initialRooms[index] = new Rectangle(rnd.Next(w - maxW), rnd.Next(h - maxH), rnd.Next(1, maxW), rnd.Next(1, maxH));
             * while (++attempts < 1000 && initialRooms[0].Width * initialRooms[0].Height >= numheroes &&
             *    (Overlaps(index, initialRooms) || ++index < rooms));*/

            do // FIXME: slow!
            {
                initialRooms = new Rectangle[rooms];
                index        = 0;
                int attempts = 0;

                do
                {
                    initialRooms[index] = new Rectangle(rnd.Next(w - maxW), rnd.Next(h - maxH), rnd.Next(1, maxW), rnd.Next(1, maxH));
                }while (++attempts < 1000 && (Overlaps(index, initialRooms) || ++index < rooms));

                if (attempts == 1000)
                {
                    Rectangle[] tmp = new Rectangle[index];
                    Array.Copy(initialRooms, tmp, index);
                    initialRooms = tmp;
                }
            }while (initialRooms[0].Width * initialRooms[0].Height < numheroes);

            for (int i = 0; i < initialRooms.Length; i++)
            {
                Rectangle r     = Rectangle.Zero;
                int       width = 1;

                do
                {
                    r = new Rectangle(initialRooms[i].X + initialRooms[i].Width,
                                      initialRooms[i].Y,
                                      width++,
                                      initialRooms[i].Height);

                    if (r.X + r.Width - 1 > w)
                    {
                        r.Width = 0;
                        break;
                    }
                }while (!Overlaps(r, initialRooms));

                initialRooms[i].Width += r.Width - 1;

                int height = 1;

                do
                {
                    r = new Rectangle(initialRooms[i].X,
                                      initialRooms[i].Y + initialRooms[i].Height,
                                      initialRooms[i].Width,
                                      height++);

                    if (r.Y + r.Height - 1 > h)
                    {
                        r.Height = 0;
                        break;
                    }
                }while (!Overlaps(r, initialRooms));

                initialRooms[i].Height += r.Height - 1;
            }

            for (int i = 0; i < initialRooms.Length; i++)
            {
                for (int x = initialRooms[i].X; x < initialRooms[i].X + initialRooms[i].Width; x++)
                {
                    for (int y = initialRooms[i].Y; y < initialRooms[i].Y + initialRooms[i].Height; y++)
                    {
                        if (map.Encoding[x, y][0] > 0)
                        {
                            Rectangle a = initialRooms[i];
                            Rectangle b = initialRooms[map.Encoding[x, y][0] - 1];

                            bool inter = a.Overlaps(b);
                            throw new InvalidOperationException("Overlap!");
                        }

                        map.Encoding[x, y][0] = (byte)(i + 1);
                    }
                }
            }

            byte          doors = 1;
            HashSet <int> doorsExistBetweenRooms = new HashSet <int>();

            for (int x = 0; x < w - 1; x++)
            {
                for (int y = 0; y < h - 1; y++)
                {
                    int  hash       = (851 + map.Encoding[x, y][0]) * 37 + map.Encoding[x + 1, y][0];
                    bool doorsAdded = false;

                    if (map.Encoding[x, y][0] > 0 &&
                        map.Encoding[x + 1, y][0] > 0 &&
                        map.Encoding[x, y][0] != map.Encoding[x + 1, y][0] &&
                        !doorsExistBetweenRooms.Contains(hash))
                    {
                        map.Encoding[x + 1, y][1] = doors;
                        map.Encoding[x, y][1]     = doors++;

                        doorsExistBetweenRooms.Add(hash);
                        doorsAdded = true;
                    }

                    if (!doorsAdded)
                    {
                        hash = (851 + map.Encoding[x, y][0]) * 37 + map.Encoding[x, y + 1][0];

                        if (map.Encoding[x, y][0] > 0 &&
                            map.Encoding[x, y + 1][0] > 0 &&
                            map.Encoding[x, y][0] != map.Encoding[x, y + 1][0] &&
                            !doorsExistBetweenRooms.Contains(hash))
                        {
                            map.Encoding[x, y][1]     = doors;
                            map.Encoding[x, y + 1][1] = doors++;

                            doorsExistBetweenRooms.Add(hash);
                        }
                    }
                }
            }

            map.SaveMapToFile(filepath + "map.bin");
            map.SaveImageToFile(filepath + "map.png", 1536, 1024);
        }