Exemple #1
0
        /// <summary>
        /// Generate a dungeon in the given map, from the objects in the lists given in the constructor
        /// </summary>
        /// <param name="map">the map to generate the dungeon in</param>
        /// <param name="entry">the entry (door + position) used to start the dungeon</param>
        public void GenerateMap(Map map, PatternPosition entry)
        {
            List <PatternPosition> availablesExits = new List <PatternPosition>();
            List <PatternPosition> usedRooms       = new List <PatternPosition>();
            List <PatternPosition> rejectedExits   = new List <PatternPosition>();

            // use given entry as the initial entry/door
            map.Place(_doors.Find(entry.id), entry.x, entry.y);
            availablesExits.Add(entry);
            // also add it to the toremove (it will not be used by another room...)
            // since it's the first, it will be the "Up" (see ManageEntries)
            rejectedExits.Add(entry);
            if (Debug)
            {
                CharUtils.saveAsImage($"./assets/map{operationCount++}.png", map.Content);
            }

            // While there are not checked exits
            while (availablesExits.Count > 0)
            {
                // Select one door on the map (random)
                //PatternPosition exit = availablesExits[rnd.Next(0, availablesExits.Count)];

                // Select one door on the map (breadth first)
                PatternPosition exit = availablesExits[0];

                // Select one door on the map (deapth first)
                //PatternPosition exit = availablesExits[availablesExits.Count - 1];

                // try to place a room to this exit
                this.PlaceRoomForDoor(map, exit, availablesExits, usedRooms, rejectedExits);

                if (Debug)
                {
                    CharUtils.saveAsImage($"./assets/map{operationCount++}.png", map.Content);
                }
                Logger.Pop();
            }

            // generate an entry and exit
            ManageEntries(map, rejectedExits);

            // remove unwanted artifacts (not used doors...)
            Clean(map);

            // place some new element / remove some based on pattern
            Decorate(map);


            Logger.Pop();
        }
        /// <summary>
        /// Read a room in the "0" FileFormat
        /// First line is XSize
        ///Second Line is YSize
        ///Third line are operation to generate Mirror rooms (Rotate : X, H Mirror : X, V Mirror : Y)
        ///Followed by YSize lines of XSize chars
        /// </summary>
        /// <param name="reader"></param>
        public static void Read_FileFormat_1(StreamReader reader, ReplacementRuleList templates)
        {
            try
            {
                int priority = 1;
                int xsize    = 0;
                int ysize    = 0;
                int chance   = 100;
                Int32.TryParse(reader.ReadLine(), out priority);
                Int32.TryParse(reader.ReadLine(), out xsize);
                Int32.TryParse(reader.ReadLine(), out ysize);
                string operations = reader.ReadLine();

                char[,] initialData = loadData(reader, xsize, ysize);
                Int32.TryParse(reader.ReadLine(), out chance);
                char[,] replacementData = loadData(reader, xsize, ysize);

                // if requested, create mirrored copies
                List <char[, ]> initialMirrors =
                    CharUtils.CreateMirrors(initialData, operations);
                List <char[, ]> replacementMirrors =
                    CharUtils.CreateMirrors(replacementData, operations);
                for (int i = 0; i < initialMirrors.Count; i++)
                {
                    MapTemplate     initial     = new MapTemplate(initialMirrors[i]);
                    MapTemplate     replacement = new MapTemplate(replacementMirrors[i]);
                    ReplacementRule replace     = new ReplacementRule();
                    replace.InitialContent     = initial;
                    replace.ReplacementContent = replacement;
                    replace.Priority           = priority;
                    replace.Chance             = chance;
                    if (replace.Check())
                    {
                        templates.Add(replace);
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Error(e.Message);
                Console.WriteLine(e.Message);
            }
        }
Exemple #3
0
        /// <summary>
        /// Remove unwanted artifact from the map : door leading to nowhere, cul-de-sac...
        /// This is done by replacement rules with chance = 100
        /// </summary>
        /// <param name="map"></param>
        private void Clean(Map map)
        {
            Logger.Info($"Cleaning the map from unwanted artifact", Logger.LogAction.PUSH);
            // change "unknown" to "wall"

            map.ReplaceAll('?', '#');
            bool modified = true;
            // get all rentries that are always used...
            List <ReplacementRule> always = _modifications.collection.FindAll(template => (template.Chance == 100));

            Logger.Info($"{always.Count} rules found");
            always.Sort(
                delegate(ReplacementRule x,
                         ReplacementRule y)
            {
                if (x.Priority == y.Priority)
                {
                    return(0);
                }
                if (x.Priority > y.Priority)
                {
                    return(1);
                }
                else
                {
                    return(-1);
                }
            }
                );
            while (modified)
            {
                modified = false;
                foreach (ReplacementRule rule in always)
                {
                    modified = modified || map.ReplaceAll(rule.InitialContent, rule.ReplacementContent);
                }
                if (Debug)
                {
                    CharUtils.saveAsImage($"./assets/map{operationCount++}.png", map.Content);
                }
            }
            Logger.Pop();
        }
        /// <summary>
        /// Read a pattern in the "0" FileFormat
        /// First line is XSize
        ///Second Line is YSize
        ///Third line are operation to generate Mirror pattern (Rotate : X, H Mirror : X, V Mirror : Y)
        ///Followed by YSize lines of XSize chars
        /// </summary>
        /// <param name="reader"></param>
        public static void Read_FileFormat_0(StreamReader reader, MapTemplateList templates)
        {
            try
            {
                int xsize = 0;
                int ysize = 0;
                Int32.TryParse(reader.ReadLine(), out xsize);
                Int32.TryParse(reader.ReadLine(), out ysize);
                string operations = reader.ReadLine();

                char[,] roomData = loadData(reader, xsize, ysize);

                // if requested, create mirrored copies
                List <char[, ]> mirrors =
                    CharUtils.CreateMirrors(roomData, operations);
                int         count    = 0;
                int         sourceId = 0;
                MapTemplate tmp;
                foreach (char[,] copy in mirrors)
                {
                    if (count == 0)
                    {
                        tmp      = new MapTemplate(copy);
                        sourceId = tmp.Id;
                        CharUtils.saveAsImage($"./assets/images/{templates._name}_{tmp.Id}.png", copy);
                    }
                    else
                    {
                        tmp = new MapTemplate(copy, sourceId);
                    }
                    templates.Add(tmp);
                    //CharUtils.saveAsImage($"./assets/images/{templates._name}_{tmp.Id}.png", copy);
                    count++;
                }
            }
            catch (Exception e)
            {
                Logger.Error(e.Message);
                Console.WriteLine(e.Message);
            }
        }
Exemple #5
0
        /// <summary>
        /// Check that a room can be placed, comparing the map and the room pattern
        /// </summary>
        /// <param name="map">the map where to add the room to</param>
        /// <param name="room">the room to add</param>
        /// <param name="xpos">xposition of the left side of the room in the map</param>
        /// <param name="ypos">yposition of the top of the room in the map</param>
        /// <param name="usedRooms">List of all already used room, with their position</param>
        /// <returns>true if the room can be added</returns>
        private bool CheckRoom(Map map, MapTemplate room, int xpos, int ypos, List <PatternPosition> usedRooms)
        {
            char[,] roomContent = room.Content;
            if ((xpos + room.XSize >= (map.XSize - 1)) || (ypos + room.YSize >= (map.YSize - 1)))
            {
                return(false);
            }
            if ((xpos <= 0) || (ypos <= 0))
            {
                return(false);
            }

            // check that we didn't put the new room exactly at the same place as a previous room with the same Id (ie same look)
            int count = usedRooms.FindAll(used => (used.x == xpos && used.y == ypos && used.id == room.SourceId)).Count;

            if (count > 0)
            {
                return(false);
            }

            // check that the room can be placed here, taking into accountt the joker on both pattern
            return(CharUtils.FullMatch(map: map.Content, pattern: room.Content, xpos, ypos));
        }
Exemple #6
0
        static void Main(string[] args)
        {
            Logger.initialisation();
            // get char groups
            CharGroupsLoader.loadFromDirectory("./assets/");
            // get the rooms & doors template
            MapTemplateList rooms = MapTemplateLoader.loadFromDirectory("./assets/rooms", "rooms");
            // get the rooms & doors template
            MapTemplateList doors = MapTemplateLoader.loadFromDirectory("./assets/doors", "doors");
            // get the cleaning template rules
            ReplacementRuleList modifications = ReplacementRuleLoader.loadFromDirectory("./assets/modifications", "modifications");

            // create the map
            Map map = new Map(75, 75);
            // create the generator & call it
            MapGenerator1 generator = new MapGenerator1(rooms, doors, modifications);

            generator.GenerateMap(map);



            CharUtils.saveAsImage("./assets/map.png", map.Content);
        }
Exemple #7
0
        /// <summary>
        /// replace some part of the map by others, based on pattern matching and randomness
        /// </summary>
        /// <param name="map"></param>
        private void Decorate(Map map)
        {
            Logger.Info($"Modifiying the map ", Logger.LogAction.PUSH);
            // get all rentries that are always used...
            List <ReplacementRule> sometimes = _modifications.collection.FindAll(template => (template.Chance != 100));

            Logger.Info($"{sometimes.Count} rules found");
            sometimes.Sort(
                delegate(ReplacementRule x,
                         ReplacementRule y)
            {
                if (x.Priority == y.Priority)
                {
                    return(0);
                }
                if (x.Priority > y.Priority)
                {
                    return(1);
                }
                else
                {
                    return(-1);
                }
            }
                );
            foreach (ReplacementRule rule in sometimes)
            {
                Logger.Info($" replacement of {rule.InitialContent.Id} by {rule.ReplacementContent.Id} with {rule.Chance}% chance ");
                map.ReplaceAll(rule.InitialContent, rule.ReplacementContent, rule.Chance, "");
                if (Debug)
                {
                    CharUtils.saveAsImage($"./assets/map{operationCount++}.png", map.Content);
                }
            }
            Logger.Pop();
        }
Exemple #8
0
        /// <summary>
        /// Select two non used doors and set them as exit of the map;
        /// </summary>
        /// <param name="map">the map to get the entries on</param>
        /// <param name="rejectedExits">list of non used doors</param>
        private void ManageEntries(Map map, List <PatternPosition> rejectedExits)
        {
            // choose the exit
            PatternPosition exitPos = rejectedExits[0];
            // get the template
            MapTemplate door = _doors.Find(exitPos.id);
            // duplicate it and change it
            MapTemplate exit = new MapTemplate(door);

            CharUtils.ReplaceAll(exit.Content, '=', 'U');
            // update the map
            map.Place(exit, exitPos.x, exitPos.y);
            map.UpExit = exitPos;

            exitPos = rejectedExits[rejectedExits.Count - 1];
            // get the template
            door = _doors.Find(exitPos.id);
            // duplicate it and change it
            exit = new MapTemplate(door);
            CharUtils.ReplaceAll(exit.Content, '=', 'D');
            // update the map
            map.Place(exit, exitPos.x, exitPos.y);
            map.DownExit = exitPos;
        }
Exemple #9
0
 /// <summary>
 /// Replace all occurence of a character on the map by another one
 /// </summary>
 /// <param name="source">the character to replace</param>
 /// <param name="dest">the new character to replace with</param>
 public bool ReplaceAll(char source, char dest)
 {
     return(CharUtils.ReplaceAll(Content, source, dest));
 }
Exemple #10
0
 /// <summary>
 /// Search a template in the content of this objetc, and replace it with another one,
 /// </summary>
 /// <param name="toFind">the template to find</param>
 /// <param name="toReplace">the template to replace with</param>
 /// <returns>true if at least one modification occured</returns>
 public bool ReplaceAll(MapTemplate toFind, MapTemplate toReplace)
 {
     return(CharUtils
            .Replace(Content, toFind.Content, toReplace.Content, 100, ""));
 }
Exemple #11
0
 /// <summary>
 /// place a given template on the content at a given position.
 /// Only filled part of the template characters (!= '?') are used
 /// </summary>
 /// <param name="Template">the replacing template</param>
 /// <param name="xpos">X position</param>
 /// <param name="ypos">Y position</param>
 public void Place(MapTemplate template, int xpos, int ypos)
 {
     CharUtils.Place(Content, template.Content, xpos, ypos);
 }
Exemple #12
0
 /// <summary>
 /// check the given template against the content of the object return the list of position where the template matche
 /// </summary>
 /// <param name="template">The template to chek </param>
 /// <param name="operation">operations to perform on the template (RXY) </param>
 /// <returns>List of position where the template Matches</returns>
 public List <Position> Matches(MapTemplate template, string operations, bool strict = false)
 {
     return(CharUtils.Matches(Content, template.Content, operations, strict: strict));
 }
Exemple #13
0
 /// <summary>
 /// check the current template against a given map and return the list of position where both template matche
 /// </summary>
 /// <param name="destination">The template to chekc the template against. It should be bigger than the template</param>
 /// <returns>List of position where the template Matches</returns>
 public List <Position> Matches(MapTemplate content, bool strict = false)
 {
     return(CharUtils
            .Matches(map: content.Content, template: Content, "", strict: strict));
 }
Exemple #14
0
 /// <summary>
 /// check the current template against a given position on the given map and return true if the template matche
 /// </summary>
 /// <param name="template">The template to check</param>
 /// <param name="xpos">X position</param>
 /// <param name="ypos">Y position</param>
 /// <returns>true if the template Matches, false otherwise</returns>
 public bool Matches(MapTemplate template, int xpos, int ypos, bool strict = false)
 {
     return(CharUtils.Match(pattern: Content, map: template.Content, xpos: xpos, ypos: ypos, strict: strict));
 }