// returns a Path if there is one or null if not
 // default to allow diagonal steps
 public static Path BFSPath(int xStart, int yStart, int xEnd, int yEnd,
                            CanStep stepFrom, CanStep stepTo, StepCost costFrom, DirectedStepCost costTo,
                            MapRectangle limits)
 {
     return(BFSPath(xStart, yStart, xEnd, yEnd, stepFrom, stepTo,
                    costFrom, costTo, limits, true));
 }
 // returns a Path if there is one or null if not
 // default to allow diagonal steps
 public static Path BFSPath(int xStart, int yStart, int xEnd, int yEnd,
    CanStep stepFrom, CanStep stepTo, StepCost costFrom, DirectedStepCost costTo,
    MapRectangle limits)
 {
     return BFSPath(xStart, yStart, xEnd, yEnd, stepFrom, stepTo,
        costFrom, costTo, limits, true);
 }
Esempio n. 3
0
 public static void CalculateBresenhamProductsToRectangle(int fromX, int
                                                          fromY, int[][] map, MapRectangle rectangle, UpdateProductForSquare
                                                          update, int startingProduct, int[][] outputMap)
 {
     CalculateBresenhamProductsToRectangle(fromX, fromY, map,
                                           rectangle, update, startingProduct, false, true, outputMap);
 }
Esempio n. 4
0
        public static void CalculateBresenhamProductsToRectangle(int fromX, int
                                                                 fromY, int[][] map, MapRectangle rectangle, UpdateProductForSquare
                                                                 update, int startingProduct, bool includeFirstSquare, bool
                                                                 includeLastSquare, int[][] outputMap)
        {
            // top and bottom edges
            for (int x = rectangle.x; x <= rectangle.x2; x++)
            {
                outputMap[fromX][fromY] = startingProduct;
                CalculateBresenhamProductSquareToSquare(fromX, fromY,
                                                        x, rectangle.y, map,
                                                        (previous, mapval, xs, ys) => {
                    outputMap[xs][ys] = update(previous, mapval);
                    return(outputMap[xs][ys]);
                }, startingProduct, includeFirstSquare, includeLastSquare);
                outputMap[fromX][fromY] = startingProduct;
                CalculateBresenhamProductSquareToSquare(fromX, fromY,
                                                        x, rectangle.y2, map,
                                                        (previous, mapval, xs, ys) => {
                    outputMap[xs][ys] = update(previous, mapval);
                    return(outputMap[xs][ys]);
                }, startingProduct, includeFirstSquare, includeLastSquare);
            }

            // right and left edges
            for (int y = rectangle.y + 1; y <= rectangle.y2 - 1; y++)
            {
                outputMap[fromX][fromY] = startingProduct;
                CalculateBresenhamProductSquareToSquare(fromX, fromY,
                                                        rectangle.x, y, map,
                                                        (previous, mapval, xs, ys) => {
                    outputMap[xs][ys] = update(previous, mapval);
                    return(outputMap[xs][ys]);
                }, startingProduct, includeFirstSquare, includeLastSquare);
                outputMap[fromX][fromY] = startingProduct;
                CalculateBresenhamProductSquareToSquare(fromX, fromY,
                                                        rectangle.x2, y, map,
                                                        (previous, mapval, xs, ys) => {
                    outputMap[xs][ys] = update(previous, mapval);
                    return(outputMap[xs][ys]);
                }, startingProduct, includeFirstSquare, includeLastSquare);
            }
        }
Esempio n. 5
0
 // pixel types: 
 //    [0] = outer wall
 //    [1] = inner fill
 // custom params:
 //    none
 public override List<MapRoom> Run(int[][] map, MapRectangle fillRegion,
    List<MapRoom> roomsToInclude)
 {
     bool[][] pixelIsProtected = BuildProtectedMap(roomsToInclude,
        map.Length, map[0].Length);
     for (int i = fillRegion.x; i <= fillRegion.x2; i++)
     {
         for (int j = fillRegion.y; j <= fillRegion.y2; j++)
         {
             if (!pixelIsProtected[i][j])
             {
                 bool isBorder = (i == fillRegion.x ||
                    i == fillRegion.x2 || j == fillRegion.y ||
                    j == fillRegion.y2);
                 map[i][j] = isBorder ? pixelTypes[1] : pixelTypes[0];
             }
         }
     }
     return new List<MapRoom>(new MapRoom[0]);
 }
Esempio n. 6
0
 // pixel types:
 //    [0] = outer wall
 //    [1] = inner fill
 // custom params:
 //    none
 public override List <MapRoom> Run(int[][] map, MapRectangle fillRegion,
                                    List <MapRoom> roomsToInclude)
 {
     bool[][] pixelIsProtected = BuildProtectedMap(roomsToInclude,
                                                   map.Length, map[0].Length);
     for (int i = fillRegion.x; i <= fillRegion.x2; i++)
     {
         for (int j = fillRegion.y; j <= fillRegion.y2; j++)
         {
             if (!pixelIsProtected[i][j])
             {
                 bool isBorder = (i == fillRegion.x ||
                                  i == fillRegion.x2 || j == fillRegion.y ||
                                  j == fillRegion.y2);
                 map[i][j] = isBorder ? pixelTypes[1] : pixelTypes[0];
             }
         }
     }
     return(new List <MapRoom>(new MapRoom[0]));
 }
Esempio n. 7
0
 public abstract List <MapRoom> Run(int[][] map, MapRectangle fillRegion,
                                    List <MapRoom> roomsToInclude);
Esempio n. 8
0
 public MapRoom(MapRectangle bounds)
 {
     this.bounds       = bounds;
     this.doors        = new List <MapRoomDoor>();
     this.doNotConnect = false;
 }
        // pixel types:
        //    [0] = wall
        //    [1] = floor
        ///   [2] = door
        // custom params:
        //    nLevels = max levels of subdivision
        //    corridorWidth = top-level corridor width; drops by 1 at each
        //       level below til it reaches 1
        public override List <MapRoom> Run(int[][] map, MapRectangle fillRegion,
                                           List <MapRoom> roomsToInclude)
        {
            bool debug = false;

            bool[][] pixelIsProtected = BuildProtectedMap(roomsToInclude,
                                                          map.Length, map[0].Length);
            for (int i = 0; i < fillRegion.w; i++)
            {
                for (int j = 0; j < fillRegion.h; j++)
                {
                    if (!pixelIsProtected[i + fillRegion.x][j + fillRegion.y])
                    {
                        map[i + fillRegion.x][j + fillRegion.y] = pixelTypes[1];
                    }
                }
            }
            List <MapRoom> rooms = BSPBlock(nLevels, corridorWidth, NextRandom(0, 2) == 1,
                                            pixelIsProtected, map, fillRegion);

            if (debug)
            {
                Console.WriteLine("Fill region " + fillRegion);
            }
            foreach (MapRoom room in rooms)
            {
                bool[] sideOk   = new bool[] { true, true, true, true };
                int    nSidesOk = 4;
                if (debug)
                {
                    Console.WriteLine("Room at " + room.bounds);
                }
                if (room.bounds.x == fillRegion.x)
                {
                    if (debug)
                    {
                        Console.WriteLine("  W wall external");
                    }
                    sideOk[3] = false;
                    nSidesOk--;
                }
                if (room.bounds.y == fillRegion.y)
                {
                    if (debug)
                    {
                        Console.WriteLine("  N wall external");
                    }
                    sideOk[0] = false;
                    nSidesOk--;
                }
                if (room.bounds.x2 == fillRegion.x2)
                {
                    if (debug)
                    {
                        Console.WriteLine("  E wall external");
                    }
                    sideOk[1] = false;
                    nSidesOk--;
                }
                if (room.bounds.y2 == fillRegion.y2)
                {
                    if (debug)
                    {
                        Console.WriteLine("  S wall external");
                    }
                    sideOk[2] = false;
                    nSidesOk--;
                }
                if (debug)
                {
                    Console.WriteLine("  # doorable sides = " + nSidesOk);
                }
                if (nSidesOk > 0)
                {
                    int sideOffset = NextRandom(0, nSidesOk);
                    int side       = 0;
                    while (!sideOk[side] || sideOffset > 0)
                    {
                        if (sideOk[side])
                        {
                            sideOffset--;
                        }
                        side++;
                    }
                    int offset = NextRandom(2, (((side % 2) == 0) ?
                                                room.bounds.w : room.bounds.h) - 2);
                    if (debug)
                    {
                        Console.WriteLine("  door in side " + side + " offset " + offset);
                    }
                    MapRoomDoor door = new MapRoomDoor(side, offset, room);
                    room.doors.Add(door);
                    map[door.x][door.y] = pixelTypes[2];
                    if (debug)
                    {
                        Console.WriteLine("  door at " + door.x + ", " + door.y);
                    }
                }
            }
            return(rooms);
        }
        // returns a Path if there is one or null if not
        public static Path BFSPath(int xStart, int yStart, int xEnd, int yEnd,
           CanStep stepFrom, CanStep stepTo, StepCost costFrom, DirectedStepCost costTo,
           MapRectangle limits, bool allowDiagonalSteps)
        {
            bool debug = false;
            if (debug)
            {
                Console.WriteLine("BFS start");
            }

            // update bestCost to hold the Dijkstra map
            if (bestCost == null || bestCost.Length < limits.w)
            {
                bestCost = new int[limits.w][];
                visitedFrom = new eStep[limits.w][];
            }
            if (bestCost[0] == null || bestCost[0].Length < limits.h)
            {
                for (int x = 0; x < limits.w; x++)
                {
                    bestCost[x] = new int[limits.h];
                    visitedFrom[x] = new eStep[limits.h];
                }
            }

            // clear bestCost to -1 = unvisited
            for (int x = 0; x < limits.w; x++)
            {
                for (int y = 0; y < limits.h; y++)
                {
                    bestCost[x][y] = -1;
                }
            }

            // forward pass
            List<int> frontX = new List<int>();
            List<int> frontY = new List<int>();
            List<int> newFrontX = new List<int>();
            List<int> newFrontY = new List<int>();
            frontX.Add(xStart);
            frontY.Add(yStart);
            bestCost[xStart - limits.x][yStart - limits.y] = 0;
            bool done = false;
            while (!done)
            {
                if (debug)
                {
                    Console.WriteLine("BFS new iteration, front size = " +
                       frontX.Count);
                }
                newFrontX.Clear();
                newFrontY.Clear();
                done = true;
                for (int i = 0; i < frontX.Count; i++)
                {
                    int baseCost = bestCost[frontX[i] - limits.x][
                       frontY[i] - limits.y];
                    if (costFrom != null)
                    {
                        baseCost += costFrom(frontX[i], frontY[i]);
                    }
                    if (stepFrom == null || stepFrom(frontX[i], frontY[i]))
                    {
                        for (int j = 0; j < 8; j += (allowDiagonalSteps ? 1 : 2))
                        {
                            int xNew = frontX[i] + StepDX[j];
                            int yNew = frontY[i] + StepDY[j];
                            if (debug) 
                            {
                                Console.WriteLine("   attempt step from " + frontX[i] +
                                   ", " + frontY[i] + " dir " + j + " delta = " + 
                                   StepDX[j] + ", " + StepDY[j] + " to " + xNew + ", " + 
                                   yNew);
                            }
                            if (xNew >= limits.x && yNew >= limits.y &&
                               xNew <= limits.x2 && yNew <= limits.y2 &&
                               (stepTo == null || stepTo(xNew, yNew)))
                            {
                                int newCost = baseCost;
                                if (costTo != null)
                                {
                                    newCost += costTo(xNew, yNew, (eStep)j);
                                }
                                int dx = xNew - limits.x;
                                int dy = yNew - limits.y;
                                int currentCost = bestCost[dx][dy];
                                if (currentCost == -1 ||
                                   currentCost > newCost)
                                {
                                    bestCost[dx][dy] = newCost;
                                    visitedFrom[dx][dy] = ReverseStep[
                                       (int)j];
                                    newFrontX.Add(xNew);
                                    newFrontY.Add(yNew);
                                    if (debug)
                                    {
                                        Console.WriteLine("  step to " + xNew +
                                           ", " + yNew + " new cost = " +
                                           newCost);
                                    }
                                    done = false;
                                }
                            }
                        }
                    }
                }
                if (!done)
                {
                    List<int> swap = newFrontX; newFrontX = frontX; frontX = swap;
                    swap = newFrontY; newFrontY = frontY; frontY = swap;
                }
            }


            if (bestCost[xEnd - limits.x][yEnd - limits.y] != -1)
            {
                // reverse pass and path gen
                int x = xEnd, y = yEnd;
                List<eStep> steps = new List<eStep>();
                while (x != xStart || y != yStart)
                {
                    eStep backStep = visitedFrom[x - limits.x][y - limits.y];
                    steps.Add(backStep);
                    int dx = StepDX[(int)backStep];
                    int dy = StepDY[(int)backStep];
                    x += dx;
                    y += dy;
                }
                Path solution = new Path(new eStep[steps.Count]);
                for (int i = 0; i < steps.Count; i++)
                {
                    solution.Steps[i] = ReverseStep[(int)steps[steps.Count - i - 1]];
                }
                return solution;
            }
            else
            {
                return null; // there is no path
            }
        }
 // pixel types: 
 //    [0] = wall
 //    [1] = floor
 ///   [2] = door
 // custom params:
 //    nLevels = max levels of subdivision
 //    corridorWidth = top-level corridor width; drops by 1 at each
 //       level below til it reaches 1
 public override List<MapRoom> Run(int[][] map, MapRectangle fillRegion,
    List<MapRoom> roomsToInclude)
 {
     bool debug = false;
     bool[][] pixelIsProtected = BuildProtectedMap(roomsToInclude,
        map.Length, map[0].Length);
     for (int i = 0; i < fillRegion.w; i++)
     {
         for (int j = 0; j < fillRegion.h; j++)
         {
             if (!pixelIsProtected[i + fillRegion.x][j + fillRegion.y])
             {
                 map[i + fillRegion.x][j + fillRegion.y] = pixelTypes[1];
             }
         }
     }
     List<MapRoom> rooms = BSPBlock(nLevels, corridorWidth, NextRandom(0, 2) == 1,
        pixelIsProtected, map, fillRegion);
     if (debug)
     {
         Console.WriteLine("Fill region " + fillRegion);
     }
     foreach (MapRoom room in rooms)
     {
         bool[] sideOk = new bool[] {true, true, true, true};
         int nSidesOk = 4;
         if (debug)
         {
             Console.WriteLine("Room at " + room.bounds);
         }
         if (room.bounds.x == fillRegion.x)
         {
             if (debug)
             {
                 Console.WriteLine("  W wall external");
             }
             sideOk[3] = false;
             nSidesOk--;
         }
         if (room.bounds.y == fillRegion.y)
         {
             if (debug)
             {
                 Console.WriteLine("  N wall external");
             }
             sideOk[0] = false;
             nSidesOk--;
         }
         if (room.bounds.x2 == fillRegion.x2)
         {
             if (debug)
             {
                 Console.WriteLine("  E wall external");
             }
             sideOk[1] = false;
             nSidesOk--;
         }
         if (room.bounds.y2 == fillRegion.y2)
         {
             if (debug)
             {
                 Console.WriteLine("  S wall external");
             }
             sideOk[2] = false;
             nSidesOk--;
         }
         if (debug)
         {
             Console.WriteLine("  # doorable sides = " + nSidesOk);
         }
         if (nSidesOk > 0)
         {
             int sideOffset = NextRandom(0, nSidesOk);
             int side = 0;
             while (!sideOk[side] || sideOffset > 0)
             {
                if (sideOk[side]) sideOffset--;
                side++;
             }
             int offset = NextRandom(2, (((side % 2) == 0) ?
                room.bounds.w : room.bounds.h) - 2);
             if (debug)
             {
                 Console.WriteLine("  door in side " + side + " offset " + offset);
             }
             MapRoomDoor door = new MapRoomDoor(side, offset, room);
             room.doors.Add(door);
             map[door.x][door.y] = pixelTypes[2];
             if (debug)
             {
                 Console.WriteLine("  door at " + door.x + ", " + door.y);
             }
         }
     }
     return rooms;
 }
Esempio n. 12
0
        public static int Main(String[] args)
        {
            ClearMapGenerator gen = new ClearMapGenerator(new int[] {0, 0},
               MapCoordinate.GenerateRandom());

            MapData mapdata = new MapData(40, 40);
            ClearMapGenerator gen2 = new ClearMapGenerator(new int[] {2, 1},
               MapCoordinate.GenerateRandom());
            gen2.Run(mapdata.grid, new MapRectangle(10, 10, 10, 10), null);
            List<MapRoom> blockedList = new List<MapRoom>();
            MapRectangle fullArea = new MapRectangle(0, 0, 40, 40);
            blockedList.Add(new MapRoom(new MapRectangle(10, 10, 10, 10)));
            gen.Run(mapdata.grid, fullArea, blockedList);

            if (args.Length == 0)
            {
                Console.WriteLine("Specify -cave, -dungeon, or -office");
                return 0;
            }
            else if (args[0] == "-office")
            {
                gen.Run(mapdata.grid, fullArea, null);
                BSPBuildingMapGenerator bsp = new BSPBuildingMapGenerator(
                   new int[] {0, 1, 7}, MapCoordinate.GenerateRandom(),
                   4, 3, 2);
                MapRectangle borderedArea = new MapRectangle(1, 1, 38, 38);
                bsp.Run(mapdata.grid, borderedArea, null);

                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '.');
                mapdata.AddSpaceType(glyph: 'O');
                mapdata.AddSpaceType(glyph: '*');
                mapdata.AddSpaceType(glyph: '~');
                mapdata.AddSpaceType(glyph: 'X');
                mapdata.AddSpaceType(glyph: ' ');
                mapdata.AddSpaceType(glyph: '+');
            }
            else if (args[0] == "-dungeon")
            {
                DungeonRoomMapGenerator drmg = new DungeonRoomMapGenerator(new
                   int[] {5, 6, 7}, MapCoordinate.GenerateRandom(),
                   5, 12, 10, 3);
                List<MapRoom> allRooms = drmg.Run(mapdata.grid, fullArea,
                   blockedList);
                DungeonCorridorMapGenerator dcmg = new
                   DungeonCorridorMapGenerator(
                   new int[] {5, 6, 7}, MapCoordinate.GenerateRandom(), 2,
                   new int[] {0, 100000, 100000, 0, 0, 100000, 0, 0});
                dcmg.Run(mapdata.grid, fullArea, allRooms);

                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '*');
                mapdata.AddSpaceType(glyph: '~');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: ' ');
                mapdata.AddSpaceType(glyph: '+');
            }
            else if (args[0] == "-cave")
            {
                CADecayMapGenerator cad = new CADecayMapGenerator(new
                   int[] {0, 1}, MapCoordinate.GenerateRandom(), 10, 20, 5, 10);
                // add this to not get random caves
                // cad.UseCoordinateBasedRandom();
                cad.Run(mapdata.grid, fullArea, blockedList);
                CAGrowthMapGenerator cag1 = new CAGrowthMapGenerator(new int[]
                   {3, 1}, MapCoordinate.GenerateRandom(), 50, 2, 20);
                cag1.Run(mapdata.grid, fullArea, blockedList);
                CAGrowthMapGenerator cag2 = new CAGrowthMapGenerator(new int[]
                   {4, 1, 2}, MapCoordinate.GenerateRandom(), 200, 8, 20);
                cag2.Run(mapdata.grid, fullArea, blockedList);
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '.');
                mapdata.AddSpaceType(glyph: 'O');
                mapdata.AddSpaceType(glyph: '*');
                mapdata.AddSpaceType(glyph: '~');
                mapdata.AddSpaceType(glyph: 'X');
                mapdata.AddSpaceType(glyph: ' ');
                mapdata.AddSpaceType(glyph: '+');
            }
            else if (args[0] == "-line")
            {
                Path path = PathUtils.GetBresenhamPath(0, 1, 6, 4, null);
                Console.WriteLine("Path from 0, 1 to 6, 4");
                PathUtils.PrintPath(path, 0, 1);
                PathUtils.GetBresenhamPath(-3, 1, -4, 9, path);
                Console.WriteLine("Path from -3, 1 to -4, 9");
                PathUtils.PrintPath(path, -3, 1);

                gen = new ClearMapGenerator(new int[] {1, 1},
                   MapCoordinate.GenerateRandom());
                fullArea = new MapRectangle(0, 0, 40, 40);
                mapdata = new MapData(40, 40);
                gen.Run(mapdata.grid, fullArea, null);
                int length = PathUtils.CalculateBresenhamProductSquareToSquare(
                   0, 1, 6, 4, mapdata.grid, (x, y) => x + y, 0);
                Console.WriteLine("Length (0, 1) -> (6, 4) in steps = " + length);
                
                MapData distance = new MapData(40, 40);
                PathUtils.CalculateBresenhamProductsToRectangle(5, 5, mapdata.grid,
                   fullArea, (x, y) => x + y, 0, distance.grid);
                for (int i = 0; i < 20; i++)
                {
                    Console.WriteLine("3 " + i + " dist = " + distance.grid[3][i]);
                }
                return 0;
            }
            else if (args[0] == "-bfs")
            {
                DungeonRoomMapGenerator drmg = new DungeonRoomMapGenerator(new
                   int[] {5, 6, 7}, MapCoordinate.GenerateRandom(),
                   5, 12, 10, 3);
                List<MapRoom> allRooms = drmg.Run(mapdata.grid, fullArea,
                   blockedList);
                DungeonCorridorMapGenerator dcmg = new
                   DungeonCorridorMapGenerator(
                   new int[] {5, 6, 7}, MapCoordinate.GenerateRandom(), 2,
                   new int[] {0, 100000, 100000, 0, 0, 100000, 0, 0});
                dcmg.Run(mapdata.grid, fullArea, allRooms);

                int xStart = allRooms[0].bounds.xCenter;
                int yStart = allRooms[0].bounds.yCenter;
                int xEnd = allRooms[1].bounds.xCenter;
                int yEnd = allRooms[1].bounds.yCenter;
                Path path = PathUtils.BFSPath(xStart, yStart, xEnd, yEnd, null, 
                   (x, y) => (mapdata.grid[x][y] >= 6), null, (x, y, d) => 
                   ((((int)d) % 2) == 1 ? 140 : 100), fullArea);
                if (path != null)
                {
                    int[][] pathSquares = PathUtils.UnrollPath(path, xStart, yStart);
                    for (int i = 0; i < pathSquares.Length; i++)
                    {
                        mapdata.grid[pathSquares[i][0]][pathSquares[i][1]] = 8;
                    }
                }
                mapdata.grid[xStart][yStart] = 9;
                mapdata.grid[xEnd][yEnd] = 10;

                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '*');
                mapdata.AddSpaceType(glyph: '~');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: ' ');
                mapdata.AddSpaceType(glyph: '+');
                mapdata.AddSpaceType(glyph: 'v');
                mapdata.AddSpaceType(glyph: 'S');
                mapdata.AddSpaceType(glyph: 'E');
            }
            else
            {
                Console.WriteLine("Specify -cave, -dungeon, or -office");
                return 0;
            }
            DisplayMap(mapdata);
            return 0;
        }
Esempio n. 13
0
        public override List <MapRoom> Run(int[][] map, MapRectangle fillRegion,
                                           List <MapRoom> roomsToInclude)
        {
            bool[][] pixelIsProtected = BuildProtectedMap(roomsToInclude,
                                                          map.Length, map[0].Length);

            // make a map of which pixels are open for growth
            int nOpen = 0;

            bool[][] open = new bool[fillRegion.w][];
            for (int i = fillRegion.x; i <= fillRegion.x2; i++)
            {
                open[i] = new bool[fillRegion.h];
                for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                {
                    if (!pixelIsProtected[i][j])
                    {
                        for (int k = 0; k < openGrowthPixels.Length; k++)
                        {
                            if (map[i][j] == openGrowthPixels[k])
                            {
                                open[i - fillRegion.x][j - fillRegion.y] = true;
                                nOpen++;
                            }
                        }
                    }
                }
            }

            // put in the seeds
            int n = nOpen / seedPointInverseDensity;

            for (int i = 0; i < n; i++)
            {
                int offset = NextRandom(0, nOpen);
                for (int j = 0; (j < fillRegion.w) && (offset > 0); j++)
                {
                    for (int k = 0; k < fillRegion.h; k++)
                    {
                        if (open[j][k])
                        {
                            offset--;
                            if (offset == 0)
                            {
                                map[j + fillRegion.x][k + fillRegion.y] =
                                    newGrowthPixel;
                            }
                        }
                    }
                }
            }

            for (int k = 0; k < numberOfGrowPasses; k++)
            {
                for (int i = fillRegion.x; i <= fillRegion.x2; i++)
                {
                    for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                    {
                        if (map[i][j] != newGrowthPixel &&
                            open[i - fillRegion.x][j - fillRegion.y])
                        {
                            int nNeighbors = 0;
                            if (i > 0)
                            {
                                if (j > 0)
                                {
                                    if (map[i - 1][j - 1] == newGrowthPixel)
                                    {
                                        nNeighbors++;
                                    }
                                }
                                if (j < map[i].Length - 1)
                                {
                                    if (map[i - 1][j + 1] == newGrowthPixel)
                                    {
                                        nNeighbors++;
                                    }
                                }
                                if (map[i - 1][j] == newGrowthPixel)
                                {
                                    nNeighbors++;
                                }
                            }
                            if (i < map.Length - 1)
                            {
                                if (j > 0)
                                {
                                    if (map[i + 1][j - 1] == newGrowthPixel)
                                    {
                                        nNeighbors++;
                                    }
                                }
                                if (j < map[i].Length - 1)
                                {
                                    if (map[i + 1][j + 1] == newGrowthPixel)
                                    {
                                        nNeighbors++;
                                    }
                                }
                                if (map[i + 1][j] == newGrowthPixel)
                                {
                                    nNeighbors++;
                                }
                            }
                            if (j > 0)
                            {
                                if (map[i][j - 1] == newGrowthPixel)
                                {
                                    nNeighbors++;
                                }
                            }
                            if (j < map[i].Length - 1)
                            {
                                if (map[i][j + 1] == newGrowthPixel)
                                {
                                    nNeighbors++;
                                }
                            }
                            int flipChance = nNeighbors *
                                             growthPercentPerGrownNeighbor;
                            if (NextRandom(1, 101) < flipChance)
                            {
                                map[i][j] = -1;
                            }
                        }
                    }
                }
                for (int i = fillRegion.x; i <= fillRegion.x2; i++)
                {
                    for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                    {
                        if (map[i][j] == -1 && !pixelIsProtected[i][j])
                        {
                            map[i][j] = newGrowthPixel;
                        }
                    }
                }
            }

            return(new List <MapRoom>(new MapRoom[0]));
        }
Esempio n. 14
0
        static public void Main ()
        {
            //UI d = new VT100UI();
            VT100UI d = new VT100UI();

            // This is just a placeholder

            for (int x = 0; x < 80; x++)
            {
                d.DrawAt(x,3," ",0,0,0,0,0,64);
            }

            for (int x = 0; x < 80; x++)
            {
                d.DrawAt(x,22," ",0,0,0,0,0,64);
            }

            UIMapElement map_element = d.MapElement(
                    x: 0,
                    y: 4,
                    h: 17
            );

            ClearMapGenerator gen = new ClearMapGenerator(new int[] {0, 0},
               MapCoordinate.GenerateRandom());

            map_element.map = new MapData(80,40);
            ClearMapGenerator gen2 = new ClearMapGenerator(new int[]{2, 1},
               MapCoordinate.GenerateRandom());
            gen2.Run(map_element.map.grid, new MapRectangle(10, 10, 10, 10), null);
            List<MapRoom> blockedList = new List<MapRoom>();
            MapRectangle fullArea = new MapRectangle(0, 0, 80, 40);
            blockedList.Add(new MapRoom(new MapRectangle(10, 10, 10, 10)));
            gen.Run(map_element.map.grid, fullArea, blockedList);

            DungeonRoomMapGenerator drmg = new DungeonRoomMapGenerator(new int[]
               {5, 6, 7}, MapCoordinate.GenerateRandom(), 5, 12, 10, 3);
            List<MapRoom> allRooms = drmg.Run(map_element.map.grid, fullArea, blockedList);

            DungeonCorridorMapGenerator dcmg = new DungeonCorridorMapGenerator(
               new int[] {5, 6, 7}, MapCoordinate.GenerateRandom(), 2,
               new int[] {0, 100000, 100000, 0, 0, 100000, 0, 0});
            dcmg.Run(map_element.map.grid, fullArea, allRooms);

            map_element.map.AddSpaceType(glyph: '#', r: 128, g: 128, b: 128);
            map_element.map.AddSpaceType(glyph: '#', r: 128, g: 128, b: 128);
            map_element.map.AddSpaceType(glyph: '#', r: 128, g: 128, b: 128);
            map_element.map.AddSpaceType(glyph: '*');
            map_element.map.AddSpaceType(glyph: '~', r:   0, g:  32, b: 255);
            map_element.map.AddSpaceType(glyph: '#', r: 128, g: 128, b: 128);
            map_element.map.AddSpaceType(glyph: '.', r:  64, g:  64, b:  64);
            map_element.map.AddSpaceType(glyph: '+', r: 128, g:  64, b:   0);

            d.DrawAt(54,3," 5 targets in range    ",255,255,192,0,0,0);
            d.DrawAt(74,3,"[T] ",192,192,255,0,0,0);
            d.DrawAt(58,22," Press     for help ",255,255,192,0,0,0);
            d.DrawAt(65,22,"[?]",192,192,255,0,0,0);

            map_element.Draw();

            d.DrawScreen();
        }
Esempio n. 15
0
        public override List <MapRoom> Run(int[][] map, MapRectangle fillRegion,
                                           List <MapRoom> roomsToInclude)
        {
            bool[][] pixelIsProtected = BuildProtectedMap(roomsToInclude,
                                                          map.Length, map[0].Length);

            // clear to solid
            for (int i = fillRegion.x; i <= fillRegion.x2; i++)
            {
                for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                {
                    if (!pixelIsProtected[i][j])
                    {
                        map[i][j] = pixelTypes[0];
                    }
                }
            }

            // put in the horizontal seed corridors
            int n = fillRegion.h / seedCorridorAverageSpacing;

            for (int i = 0; i < n; i++)
            {
                int l = NextRandom(seedCorridorAverageLength / 2,
                                   3 * seedCorridorAverageLength / 2 + 1);
                int offset = 0;
                if (l >= fillRegion.w)
                {
                    l = fillRegion.w;
                }
                else
                {
                    offset = NextRandom(0, fillRegion.w - l + 1);
                }
                int crossOffset = NextRandom(fillRegion.y, fillRegion.y2 + 1);
                for (int j = offset; j < offset + l; j++)
                {
                    if (!pixelIsProtected[j + fillRegion.x][crossOffset])
                    {
                        map[j + fillRegion.x][crossOffset] = pixelTypes[1];
                    }
                }
            }

            // put in the vertical seed corridors
            n = fillRegion.w / seedCorridorAverageSpacing;
            for (int i = 0; i < n; i++)
            {
                int l = NextRandom(seedCorridorAverageLength / 2,
                                   3 * seedCorridorAverageLength / 2 + 1);
                int offset = 0;
                if (l >= fillRegion.h)
                {
                    l = fillRegion.h;
                }
                else
                {
                    offset = NextRandom(0, fillRegion.h - l + 1);
                }
                int crossOffset = NextRandom(fillRegion.x, fillRegion.x2 + 1);
                for (int j = offset; j < offset + l; j++)
                {
                    if (!pixelIsProtected[crossOffset][j + fillRegion.y])
                    {
                        map[crossOffset][j + fillRegion.y] = pixelTypes[1];
                    }
                }
            }

            for (int k = 0; k < numberOfDecays; k++)
            {
                for (int i = fillRegion.x; i <= fillRegion.x2; i++)
                {
                    for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                    {
                        if (map[i][j] == pixelTypes[0] && !pixelIsProtected[i][j])
                        {
                            int nNeighbors = 0;
                            if (i > 0)
                            {
                                if (j > 0)
                                {
                                    if (map[i - 1][j - 1] == pixelTypes[1])
                                    {
                                        nNeighbors++;
                                    }
                                }
                                if (j < map[i].Length - 1)
                                {
                                    if (map[i - 1][j + 1] == pixelTypes[1])
                                    {
                                        nNeighbors++;
                                    }
                                }
                                if (map[i - 1][j] == pixelTypes[1])
                                {
                                    nNeighbors++;
                                }
                            }
                            if (i < map.Length - 1)
                            {
                                if (j > 0)
                                {
                                    if (map[i + 1][j - 1] == pixelTypes[1])
                                    {
                                        nNeighbors++;
                                    }
                                }
                                if (j < map[i].Length - 1)
                                {
                                    if (map[i + 1][j + 1] == pixelTypes[1])
                                    {
                                        nNeighbors++;
                                    }
                                }
                                if (map[i + 1][j] == pixelTypes[1])
                                {
                                    nNeighbors++;
                                }
                            }
                            if (j > 0)
                            {
                                if (map[i][j - 1] == pixelTypes[1])
                                {
                                    nNeighbors++;
                                }
                            }
                            if (j < map[i].Length - 1)
                            {
                                if (map[i][j + 1] == pixelTypes[1])
                                {
                                    nNeighbors++;
                                }
                            }
                            int flipChance = nNeighbors *
                                             decayPercentPerDecayedNeighbor;
                            if (NextRandom(1, 101) < flipChance)
                            {
                                map[i][j] = -1;
                            }
                        }
                    }
                }
                for (int i = fillRegion.x; i <= fillRegion.x2; i++)
                {
                    for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                    {
                        if (map[i][j] == -1 && !pixelIsProtected[i][j])
                        {
                            map[i][j] = pixelTypes[1];
                        }
                    }
                }
            }

            return(new List <MapRoom>(new MapRoom[0]));
        }
    // Use this for initialization
    void Start () {

        int player_x = 0;
        int player_y = 0;

        mapdata = new MapData(levelWidth,levelHeight);
        fullMapBounds = new MapRectangle(0, 0, levelWidth, levelHeight);

        ClearMapGenerator gen = new ClearMapGenerator(new int[] {0, 0},
           MapCoordinate.GenerateRandom());

        ClearMapGenerator gen2 = new ClearMapGenerator(new int[] {2, 1},
           MapCoordinate.GenerateRandom());
        gen2.Run(mapdata.grid, new MapRectangle(10, 10, 10, 10), null);
        List<MapRoom> blockedList = new List<MapRoom>();
        MapRectangle fullArea = new MapRectangle(0, 0, 40, 40);
        blockedList.Add(new MapRoom(new MapRectangle(10, 10, 10, 10)));
        gen.Run(mapdata.grid, fullArea, blockedList);

        DungeonRoomMapGenerator drmg = new DungeonRoomMapGenerator(new
           int[] {5, 6, 7}, MapCoordinate.GenerateRandom(),
           5, 12, 10, 3);
        List<MapRoom> allRooms = drmg.Run(mapdata.grid, fullArea,
           blockedList);
        DungeonCorridorMapGenerator dcmg = new
           DungeonCorridorMapGenerator(
           new int[] {5, 6, 7}, MapCoordinate.GenerateRandom(), 2,
           new int[] {0, 100000, 100000, 0, 0, 100000, 0, 0});
        dcmg.Run(mapdata.grid, fullArea, allRooms);

        mapdata.AddSpaceType(glyph: '#', passable: false, transparent: false);
        mapdata.AddSpaceType(glyph: '#', passable: false, transparent: false);
        mapdata.AddSpaceType(glyph: '#', passable: false, transparent: false);
        mapdata.AddSpaceType(glyph: '*', passable: true, transparent: true);
        mapdata.AddSpaceType(glyph: '~', passable: true, transparent: true);
        mapdata.AddSpaceType(glyph: '#', passable: false, transparent: false);
        mapdata.AddSpaceType(glyph: ' ', passable: true, transparent: true);
        mapdata.AddSpaceType(glyph: '+', passable: true, transparent: false);

        bool[][] visibility_map = new bool[levelHeight][];
        for (int i = 0; i < levelWidth; i++)
        {
            visibility_map[i] = new bool[levelWidth];
            for (int j = 0; j < levelHeight; j++)
            {
                visibility_map[i][j] = false;
                bool keepLooping = true;
                for (int x = i-1; (keepLooping == true) && (x <= i+1); x++)
                {
                    for (int y = j-1; (keepLooping == true) && (y <= j+1); y++)
                    {
                        if ( (x >= 0) && (x < levelWidth) && (y >= 0) && (y < levelHeight) && (mapdata.palette[mapdata.grid[x][y]].passable) )
                        {
                            keepLooping = false;
                            visibility_map[i][j] = true;
                        }
                    }
                }
            }
        }

        for (int i = 0; i < levelHeight; i++)
        {
            tileGrid.Add(new List<GameObject>());
            subTileGrid.Add(new List<GameObject>());
            for (int j = 0; j < levelWidth; j++)
            {

                // XXX this is profoundly dumb -- we're just assigning the player coords to the last passable square.  But it's temporary.
                if (mapdata.palette[mapdata.grid[j][i]].passable)
                {
                    player_x = j;
                    player_y = i;
                }

                // special case for doors :(  -- they need a floor.
                if (mapdata.grid[j][i] == 7)
                {
                    var flr = Instantiate(this.tilePrefabs[6]) as GameObject;
                    flr.transform.position = new Vector3(j, i, 1);
                    subTileGrid[i].Add(flr);
                }
                else
                {
                    subTileGrid[i].Add(null);
                }

                var o = Instantiate(this.tilePrefabs[mapdata.grid[j][i]]) as GameObject;
                o.transform.position = new Vector3(j, i, 0);
                var sts = o.GetComponent<ShapeTerrainScript>();
                if (sts)
                {
                    int surroundNum = 0;
                    // 1: north
                    if ( (i < 39) && (visibility_map[j][i+1]) && (! mapdata.palette[mapdata.grid[j][i+1]].passable) )
                    {
                            surroundNum += 1;
                    }
                    // 2: east
                    if ( (j < 39) && (visibility_map[j+1][i]) && (! mapdata.palette[mapdata.grid[j+1][i]].passable) )
                    {
                        surroundNum += 2;
                    }
                    // 4: south
                    if ( (i > 0) && (visibility_map[j][i-1]) && (! mapdata.palette[mapdata.grid[j][i-1]].passable) )
                    {
                            surroundNum += 4;
                    }
                    // 8: west
                    if ( (j > 0) && (visibility_map[j-1][i]) && (! mapdata.palette[mapdata.grid[j-1][i]].passable) )
                    {
                            surroundNum += 8;
                    }
                    sts.SetSprite(surroundNum);
                    if (! visibility_map[j][i])
                        o.GetComponent<SpriteRenderer>().enabled = false;
                }
                tileGrid[i].Add(o);
            }
        }
        this.player = Instantiate(this.playerPrefab) as GameObject;
        Vector3 pos = new Vector3(player_x, player_y, 0);
        this.player.transform.position = pos;
        this.player.transform.SetParent(transform);

        GameObject camera = Instantiate( cameraPrefab );
        pos.z=-10;
        camera.transform.position = pos;
        camera.GetComponent<CameraScript>().target = this.player.transform;

    }
Esempio n. 17
0
 public abstract List<MapRoom> Run(int[][] map, MapRectangle fillRegion,
    List<MapRoom> roomsToInclude);
Esempio n. 18
0
 public MapRoom(MapRectangle bounds)
 {
     this.bounds = bounds;
     this.doors = new List<MapRoomDoor>();
     this.doNotConnect = false;
 }
Esempio n. 19
0
        public static int Main(String[] args)
        {
            ClearMapGenerator gen = new ClearMapGenerator(new int[] { 0, 0 },
                                                          MapCoordinate.GenerateRandom());

            MapData           mapdata = new MapData(40, 40);
            ClearMapGenerator gen2    = new ClearMapGenerator(new int[] { 2, 1 },
                                                              MapCoordinate.GenerateRandom());

            gen2.Run(mapdata.grid, new MapRectangle(10, 10, 10, 10), null);
            List <MapRoom> blockedList = new List <MapRoom>();
            MapRectangle   fullArea    = new MapRectangle(0, 0, 40, 40);

            blockedList.Add(new MapRoom(new MapRectangle(10, 10, 10, 10)));
            gen.Run(mapdata.grid, fullArea, blockedList);

            if (args.Length == 0)
            {
                Console.WriteLine("Specify -cave, -dungeon, or -office");
                return(0);
            }
            else if (args[0] == "-office")
            {
                gen.Run(mapdata.grid, fullArea, null);
                BSPBuildingMapGenerator bsp = new BSPBuildingMapGenerator(
                    new int[] { 0, 1, 7 }, MapCoordinate.GenerateRandom(),
                    4, 3, 2);
                MapRectangle borderedArea = new MapRectangle(1, 1, 38, 38);
                bsp.Run(mapdata.grid, borderedArea, null);

                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '.');
                mapdata.AddSpaceType(glyph: 'O');
                mapdata.AddSpaceType(glyph: '*');
                mapdata.AddSpaceType(glyph: '~');
                mapdata.AddSpaceType(glyph: 'X');
                mapdata.AddSpaceType(glyph: ' ');
                mapdata.AddSpaceType(glyph: '+');
            }
            else if (args[0] == "-dungeon")
            {
                DungeonRoomMapGenerator drmg = new DungeonRoomMapGenerator(new
                                                                           int[] { 5, 6, 7 }, MapCoordinate.GenerateRandom(),
                                                                           5, 12, 10, 3);
                List <MapRoom> allRooms = drmg.Run(mapdata.grid, fullArea,
                                                   blockedList);
                DungeonCorridorMapGenerator dcmg = new
                                                   DungeonCorridorMapGenerator(
                    new int[] { 5, 6, 7 }, MapCoordinate.GenerateRandom(), 2,
                    new int[] { 0, 100000, 100000, 0, 0, 100000, 0, 0 });
                dcmg.Run(mapdata.grid, fullArea, allRooms);

                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '*');
                mapdata.AddSpaceType(glyph: '~');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: ' ');
                mapdata.AddSpaceType(glyph: '+');
            }
            else if (args[0] == "-cave")
            {
                CADecayMapGenerator cad = new CADecayMapGenerator(new
                                                                  int[] { 0, 1 }, MapCoordinate.GenerateRandom(), 10, 20, 5, 10);
                // add this to not get random caves
                // cad.UseCoordinateBasedRandom();
                cad.Run(mapdata.grid, fullArea, blockedList);
                CAGrowthMapGenerator cag1 = new CAGrowthMapGenerator(new int[]
                                                                     { 3, 1 }, MapCoordinate.GenerateRandom(), 50, 2, 20);
                cag1.Run(mapdata.grid, fullArea, blockedList);
                CAGrowthMapGenerator cag2 = new CAGrowthMapGenerator(new int[]
                                                                     { 4, 1, 2 }, MapCoordinate.GenerateRandom(), 200, 8, 20);
                cag2.Run(mapdata.grid, fullArea, blockedList);
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '.');
                mapdata.AddSpaceType(glyph: 'O');
                mapdata.AddSpaceType(glyph: '*');
                mapdata.AddSpaceType(glyph: '~');
                mapdata.AddSpaceType(glyph: 'X');
                mapdata.AddSpaceType(glyph: ' ');
                mapdata.AddSpaceType(glyph: '+');
            }
            else if (args[0] == "-line")
            {
                Path path = PathUtils.GetBresenhamPath(0, 1, 6, 4, null);
                Console.WriteLine("Path from 0, 1 to 6, 4");
                PathUtils.PrintPath(path, 0, 1);
                PathUtils.GetBresenhamPath(-3, 1, -4, 9, path);
                Console.WriteLine("Path from -3, 1 to -4, 9");
                PathUtils.PrintPath(path, -3, 1);

                gen = new ClearMapGenerator(new int[] { 1, 1 },
                                            MapCoordinate.GenerateRandom());
                fullArea = new MapRectangle(0, 0, 40, 40);
                mapdata  = new MapData(40, 40);
                gen.Run(mapdata.grid, fullArea, null);
                int length = PathUtils.CalculateBresenhamProductSquareToSquare(
                    0, 1, 6, 4, mapdata.grid, (x, y) => x + y, 0);
                Console.WriteLine("Length (0, 1) -> (6, 4) in steps = " + length);

                MapData distance = new MapData(40, 40);
                PathUtils.CalculateBresenhamProductsToRectangle(5, 5, mapdata.grid,
                                                                fullArea, (x, y) => x + y, 0, distance.grid);
                for (int i = 0; i < 20; i++)
                {
                    Console.WriteLine("3 " + i + " dist = " + distance.grid[3][i]);
                }
                return(0);
            }
            else if (args[0] == "-bfs")
            {
                DungeonRoomMapGenerator drmg = new DungeonRoomMapGenerator(new
                                                                           int[] { 5, 6, 7 }, MapCoordinate.GenerateRandom(),
                                                                           5, 12, 10, 3);
                List <MapRoom> allRooms = drmg.Run(mapdata.grid, fullArea,
                                                   blockedList);
                DungeonCorridorMapGenerator dcmg = new
                                                   DungeonCorridorMapGenerator(
                    new int[] { 5, 6, 7 }, MapCoordinate.GenerateRandom(), 2,
                    new int[] { 0, 100000, 100000, 0, 0, 100000, 0, 0 });
                dcmg.Run(mapdata.grid, fullArea, allRooms);

                int  xStart = allRooms[0].bounds.xCenter;
                int  yStart = allRooms[0].bounds.yCenter;
                int  xEnd   = allRooms[1].bounds.xCenter;
                int  yEnd   = allRooms[1].bounds.yCenter;
                Path path   = PathUtils.BFSPath(xStart, yStart, xEnd, yEnd, null,
                                                (x, y) => (mapdata.grid[x][y] >= 6), null, (x, y, d) =>
                                                ((((int)d) % 2) == 1 ? 140 : 100), fullArea);
                if (path != null)
                {
                    int[][] pathSquares = PathUtils.UnrollPath(path, xStart, yStart);
                    for (int i = 0; i < pathSquares.Length; i++)
                    {
                        mapdata.grid[pathSquares[i][0]][pathSquares[i][1]] = 8;
                    }
                }
                mapdata.grid[xStart][yStart] = 9;
                mapdata.grid[xEnd][yEnd]     = 10;

                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: '*');
                mapdata.AddSpaceType(glyph: '~');
                mapdata.AddSpaceType(glyph: '#');
                mapdata.AddSpaceType(glyph: ' ');
                mapdata.AddSpaceType(glyph: '+');
                mapdata.AddSpaceType(glyph: 'v');
                mapdata.AddSpaceType(glyph: 'S');
                mapdata.AddSpaceType(glyph: 'E');
            }
            else
            {
                Console.WriteLine("Specify -cave, -dungeon, or -office");
                return(0);
            }
            DisplayMap(mapdata);
            return(0);
        }
Esempio n. 20
0
        // pixel types:
        //    [0] = wall
        //    [1] = floor
        //    [2] = door
        // custom params:
        //    none
        public override List <MapRoom> Run(int[][] map, MapRectangle fillRegion,
                                           List <MapRoom> roomsToInclude)
        {
            List <MapRoom> generatedRooms = new List <MapRoom>();

            // generate the rooms

            int mapArea         = map[0].Length * map.Length;
            int typicalRoomArea = (minSide + maxSide) * (minSide + maxSide) / 4;
            int nRooms          = mapArea * openPercentage / typicalRoomArea;

            for (int i = 0; i < nRooms; i++)
            {
                int  maxPlacementTries = 10;
                bool placed            = false;
                int  width             = NextRandom(minSide, maxSide + 1);
                int  height            = NextRandom(minSide, maxSide + 1);
                if (width < fillRegion.w && height < fillRegion.h)
                {
                    int x0 = 0, y0 = 0;
                    for (int j = 0; (j < maxPlacementTries) && (!placed); j++)
                    {
                        x0     = NextRandom(0, fillRegion.w - width);
                        y0     = NextRandom(0, fillRegion.h - height);
                        placed = true;
                        for (int k = 0; k < roomsToInclude.Count && placed; k++)
                        {
                            if (RegionOverlapsRoom(x0, y0, height, width,
                                                   roomsToInclude[k]))
                            {
                                placed = false;
                            }
                        }
                        for (int k = 0; k < generatedRooms.Count && placed; k++)
                        {
                            if (RegionOverlapsRoom(x0, y0, height, width,
                                                   generatedRooms[k]))
                            {
                                placed = false;
                            }
                        }
                    }
                    if (placed)
                    {
                        generatedRooms.Add(new MapRoom(new MapRectangle(
                                                           x0, y0, width, height)));
                    }
                }
            }

            // add doors to generatedRooms
            for (int i = 0; i < generatedRooms.Count; i++)
            {
                int     nDoors = NextRandom(1, maxDoorsPerRoom + 1);
                MapRoom r      = generatedRooms[i];
                for (int j = 0; j < nDoors; j++)
                {
                    int side   = NextRandom(0, 4);
                    int offset = NextRandom(1, ((side == 0 || side == 2) ?
                                                r.bounds.w : r.bounds.h) - 1);
                    r.doors.Add(new MapRoomDoor(side, offset, r));
                }
                // clean out any duplicated doors
                for (int j = r.doors.Count - 1; j > 0; j--)
                {
                    bool dupe = false;
                    for (int k = 0; k < j; k++)
                    {
                        if (r.doors[j].side == r.doors[k].side &&
                            r.doors[j].offset == r.doors[k].offset)
                        {
                            dupe = true;
                        }
                    }
                    if (dupe)
                    {
                        r.doors.RemoveAt(j);
                    }
                }
            }

            // now set the map tiles for doors, walls, and floors
            for (int i = 0; i < generatedRooms.Count; i++)
            {
                MapRoom r = generatedRooms[i];
                for (int j = r.bounds.x; j < r.bounds.x + r.bounds.w; j++)
                {
                    for (int k = r.bounds.y; k < r.bounds.y + r.bounds.h; k++)
                    {
                        bool isBorder = (j == r.bounds.x) ||
                                        (j == r.bounds.x + r.bounds.w - 1) ||
                                        (k == r.bounds.y) ||
                                        (k == r.bounds.y + r.bounds.h - 1);
                        map[j][k] = pixelTypes[isBorder ? 0 : 1];
                    }
                }
                for (int j = 0; j < r.doors.Count; j++)
                {
                    int x = r.bounds.x, y = r.bounds.y;
                    switch (r.doors[j].side)
                    {
                    case 0:     // N, offset from W
                        x += r.doors[j].offset;
                        break;

                    case 1:     // E, offset from N
                        x += r.bounds.w - 1;
                        y += r.doors[j].offset;
                        break;

                    case 2:     // S, offset from W
                        x += r.doors[j].offset;
                        y += r.bounds.h - 1;
                        break;

                    case 3:     // W, offset from N
                        y += r.doors[j].offset;
                        break;
                    }
                    map[x][y] = pixelTypes[2];
                }
            }

            return(generatedRooms);
        }
Esempio n. 21
0
        private bool ExtendBFSCorridor(bool[][] isGoal, int[][] bestDistance,
                                       int[][] extraCost, int[][] fromDirection, int x0, int y0,
                                       int[][] map, MapRectangle fillRegion, int open, bool debug)
        {
            bool debugVerbose = false;

            if (debug)
            {
                Console.WriteLine("BFS map with goal (O) and start (S) marked");
                for (int i = 0; i < fillRegion.h; i++)
                {
                    for (int j = 0; j < fillRegion.w; j++)
                    {
                        if (i == y0 && j == x0)
                        {
                            Console.Write("O");
                        }
                        else if (bestDistance[i][j] == -1)
                        {
                            Console.Write("X");
                        }
                        else if (isGoal[j][i])
                        {
                            Console.Write("$");
                        }
                        else
                        {
                            Console.Write(".");
                        }
                    }
                    Console.WriteLine("");
                }
                Console.WriteLine("");
            }
            List <int> frontX    = new List <int>();
            List <int> frontY    = new List <int>();
            List <int> newFrontX = new List <int>();
            List <int> newFrontY = new List <int>();

            frontX.Add(x0);
            frontY.Add(y0);
            bestDistance[x0][y0] = 0;
            int  bestGoalX        = 0;
            int  bestGoalY        = 0;
            int  bestGoalDistance = -1;
            bool done             = true;

            do
            {
                // expand the existing front
                done = true;
                for (int i = 0; i < frontX.Count; i++)
                {
                    if (debugVerbose)
                    {
                        Console.WriteLine("BFS: step from " +
                                          frontX[i] + ", " + frontY[i]);
                    }
                    for (int j = 0; j < 4; j++)
                    {
                        int to_x = frontX[i] + step_dx[j];
                        int to_y = frontY[i] + step_dy[j];
                        if (debugVerbose)
                        {
                            Console.WriteLine("  test step to " +
                                              to_x + ", " + to_y);
                        }
                        if (to_x >= 0 && to_x < isGoal.Length &&
                            to_y >= 0 && to_y < isGoal[0].Length &&
                            bestDistance[to_x][to_y] != -1)
                        {
                            bool stepIsTurn = false;
                            if (frontX[i] != x0 || frontY[i] != y0)
                            {
                                stepIsTurn = (j != inverseDirection[
                                                  fromDirection[frontX[i]][frontY[i]]]);
                            }
                            int newDistance =
                                bestDistance[frontX[i]][frontY[i]] +
                                (stepIsTurn ? turnCostPenalty : 0) +
                                extraCost[to_x][to_y] + 1;
                            if (debugVerbose)
                            {
                                Console.WriteLine("  it's legit, turn = " +
                                                  stepIsTurn + " cost = " + newDistance +
                                                  " best cost so far = " +
                                                  bestDistance[to_x][to_y]);
                            }
                            if (newDistance < bestDistance[to_x][to_y])
                            {
                                done = false;
                                bestDistance[to_x][to_y]  = newDistance;
                                fromDirection[to_x][to_y] = inverseDirection[j];
                                bool alreadyInNewFront = false;
                                if (isGoal[to_x][to_y])
                                {
                                    if (bestGoalDistance == -1 ||
                                        newDistance < bestGoalDistance)
                                    {
                                        bestGoalDistance = newDistance;
                                        bestGoalX        = to_x;
                                        bestGoalY        = to_y;
                                    }
                                }
                                for (int k = 0; k < newFrontX.Count; k++)
                                {
                                    if (newFrontX[k] == to_x &&
                                        newFrontY[k] == to_y)
                                    {
                                        alreadyInNewFront = true;
                                    }
                                }
                                if (!alreadyInNewFront)
                                {
                                    newFrontX.Add(to_x);
                                    newFrontY.Add(to_y);
                                }
                            }
                        }
                    }
                }

                if (!done)
                {
                    // swap the fronts if we are still advancing
                    List <int> swapFrontX = frontX;
                    List <int> swapFrontY = frontY;
                    frontX    = newFrontX;
                    frontY    = newFrontY;
                    newFrontX = swapFrontX;
                    newFrontY = swapFrontY;
                    newFrontX.Clear();
                    newFrontY.Clear();
                }
            }while (!done);

            if (debug)
            {
                Console.WriteLine("   BFS best goal distance = " +
                                  bestGoalDistance);
            }

            if (bestGoalDistance != -1)
            {
                // backward pass writing in the corridor
                int x = bestGoalX;
                int y = bestGoalY;
                while (x != x0 || y != y0)
                {
                    if (x != bestGoalX || y != bestGoalY)
                    {
                        map[fillRegion.x + x][fillRegion.y + y] = open;
                        if (debug)
                        {
                            Console.WriteLine("   corr at " +
                                              (fillRegion.x + x) + ", " +
                                              (fillRegion.y + y));
                        }
                    }
                    int fromDir = fromDirection[x][y];
                    x += step_dx[fromDir];
                    y += step_dy[fromDir];
                }
            }
            return(bestGoalDistance != -1);
        }
        private bool ExtendBFSCorridor(bool[][] isGoal, int[][] bestDistance,
           int[][] extraCost, int[][] fromDirection, int x0, int y0, 
           int[][] map, MapRectangle fillRegion, int open, bool debug)
        {
            bool debugVerbose = false;
            if (debug)
            {
                Console.WriteLine("BFS map with goal (O) and start (S) marked");
                for (int i = 0; i < fillRegion.h; i++)
                {
                    for (int j = 0; j < fillRegion.w; j++) 
                    {
                        if (i == y0 && j == x0)
                        {
                            Console.Write("O");
                        }
                        else if (bestDistance[i][j] == -1)
                        {
                            Console.Write("X");
                        }
                        else if (isGoal[j][i])
                        {
                            Console.Write("$");
                        }
                        else
                        {
                            Console.Write(".");
                        }
                    }
                    Console.WriteLine("");
                }
                Console.WriteLine("");
            }
            List<int> frontX = new List<int>();
            List<int> frontY = new List<int>();
            List<int> newFrontX = new List<int>();
            List<int> newFrontY = new List<int>();
            frontX.Add(x0);
            frontY.Add(y0);
            bestDistance[x0][y0] = 0;
            int bestGoalX = 0;
            int bestGoalY = 0;
            int bestGoalDistance = -1;
            bool done = true;
            do
            {
                // expand the existing front
                done = true;
                for (int i = 0; i < frontX.Count; i++)
                {
                    if (debugVerbose)
                    {
                        Console.WriteLine("BFS: step from " + 
                           frontX[i] + ", " + frontY[i]);
                    }
                    for (int j = 0; j < 4; j++)
                    {
                        int to_x = frontX[i] + step_dx[j];
                        int to_y = frontY[i] + step_dy[j];
                        if (debugVerbose)
                        {
                            Console.WriteLine("  test step to " + 
                               to_x + ", " + to_y);
                        }
                        if (to_x >= 0 && to_x < isGoal.Length &&
                           to_y >= 0 && to_y < isGoal[0].Length &&
                           bestDistance[to_x][to_y] != -1)
                        {
                            bool stepIsTurn = false;
                            if (frontX[i] != x0 || frontY[i] != y0)
                            {
                                stepIsTurn = (j != inverseDirection[
                                   fromDirection[frontX[i]][frontY[i]]]);
                            }
                            int newDistance = 
                               bestDistance[frontX[i]][frontY[i]] +
                               (stepIsTurn ? turnCostPenalty : 0) +
                               extraCost[to_x][to_y] + 1;
                            if (debugVerbose)
                            {
                                Console.WriteLine("  it's legit, turn = " +
                                   stepIsTurn + " cost = " + newDistance +
                                   " best cost so far = " + 
                                   bestDistance[to_x][to_y]);
                            }
                            if (newDistance < bestDistance[to_x][to_y])
                            {
                                done = false;
                                bestDistance[to_x][to_y] = newDistance;
                                fromDirection[to_x][to_y] = inverseDirection[j];
                                bool alreadyInNewFront = false;
                                if (isGoal[to_x][to_y])
                                {
                                    if (bestGoalDistance == -1 ||
                                       newDistance < bestGoalDistance)
                                    {
                                        bestGoalDistance = newDistance;
                                        bestGoalX = to_x;
                                        bestGoalY = to_y;
                                    }
                                }
                                for (int k = 0; k < newFrontX.Count; k++)
                                {
                                    if (newFrontX[k] == to_x &&
                                       newFrontY[k] == to_y)
                                    {
                                        alreadyInNewFront = true;
                                    }
                                }
                                if (!alreadyInNewFront)
                                {
                                    newFrontX.Add(to_x);
                                    newFrontY.Add(to_y);
                                }
                            }
                        }
                    }
                }

                if (!done)
                {
                    // swap the fronts if we are still advancing
                    List<int> swapFrontX = frontX;
                    List<int> swapFrontY = frontY;
                    frontX = newFrontX;
                    frontY = newFrontY;
                    newFrontX = swapFrontX;
                    newFrontY = swapFrontY;
                    newFrontX.Clear();
                    newFrontY.Clear();
                }
            }
            while (!done);

            if (debug)
            {
                Console.WriteLine("   BFS best goal distance = " + 
                   bestGoalDistance);
            }

            if (bestGoalDistance != -1)
            {
                // backward pass writing in the corridor
                int x = bestGoalX;
                int y = bestGoalY;
                while (x != x0 || y != y0)
                {
                    if (x != bestGoalX || y != bestGoalY)
                    {
                        map[fillRegion.x + x][fillRegion.y + y] = open;
                        if (debug)
                        {
                            Console.WriteLine("   corr at " + 
                               (fillRegion.x + x) + ", " + 
                               (fillRegion.y + y));
                        }
                    }
                    int fromDir = fromDirection[x][y];
                    x += step_dx[fromDir];
                    y += step_dy[fromDir];
                }
            }
            return (bestGoalDistance != -1);
        }
Esempio n. 23
0
        public override List<MapRoom> Run(int[][] map, MapRectangle fillRegion,
           List<MapRoom> roomsToInclude)
        {
            bool[][] pixelIsProtected = BuildProtectedMap(roomsToInclude,
               map.Length, map[0].Length);
        
            // make a map of which pixels are open for growth
            int nOpen = 0;
            bool[][] open = new bool[fillRegion.w][];
            for (int i = fillRegion.x; i <= fillRegion.x2; i++)
            {
                open[i] = new bool[fillRegion.h];
                for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                {
                    if (!pixelIsProtected[i][j])
                    {
                        for (int k = 0; k < openGrowthPixels.Length; k++)
                        {
                            if (map[i][j] == openGrowthPixels[k])
                            {
                                open[i - fillRegion.x][j - fillRegion.y] = true;
                                nOpen++;
                            }
                        }
                    }
                }
            }

            // put in the seeds
            int n = nOpen / seedPointInverseDensity;
            for (int i = 0; i < n; i++)
            {
                int offset = NextRandom(0, nOpen);
                for (int j = 0; (j < fillRegion.w) && (offset > 0); j++)
                {
                    for (int k = 0; k < fillRegion.h; k++)
                    {
                       if (open[j][k])
                       {
                           offset--;
                           if (offset == 0)
                           {
                               map[j + fillRegion.x][k + fillRegion.y] = 
                                  newGrowthPixel;
                           }
                       }
                    }
                }
            }

            for (int k = 0; k < numberOfGrowPasses; k++)
            {
                for (int i = fillRegion.x; i <= fillRegion.x2; i++)
                {
                    for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                    {
                        if (map[i][j] != newGrowthPixel &&
                           open[i - fillRegion.x][j - fillRegion.y])
                        {
                            int nNeighbors = 0;
                            if (i > 0)
                            {
                               if (j > 0)
                               {
                                   if (map[i - 1][j - 1] == newGrowthPixel)
                                   {
                                       nNeighbors++;
                                   }
                               }
                               if (j < map[i].Length - 1)
                               {
                                   if (map[i - 1][j + 1] == newGrowthPixel)
                                   {
                                       nNeighbors++;
                                   }
                               }
                               if (map[i - 1][j] == newGrowthPixel)
                               {
                                   nNeighbors++;
                               }
                            }
                            if (i < map.Length - 1)
                            {
                               if (j > 0)
                               {
                                   if (map[i + 1][j - 1] == newGrowthPixel)
                                   {
                                       nNeighbors++;
                                   }
                               }
                               if (j < map[i].Length - 1)
                               {
                                   if (map[i + 1][j + 1] == newGrowthPixel)
                                   {
                                       nNeighbors++;
                                   }
                               }
                               if (map[i + 1][j] == newGrowthPixel)
                               {
                                   nNeighbors++;
                               }
                            }
                            if (j > 0)
                            {
                                if (map[i][j - 1] == newGrowthPixel)
                                {
                                    nNeighbors++;
                                }
                            }
                            if (j < map[i].Length - 1)
                            {
                                if (map[i][j + 1] == newGrowthPixel)
                                {
                                    nNeighbors++;
                                }
                            }
                            int flipChance = nNeighbors * 
                               growthPercentPerGrownNeighbor;
                            if (NextRandom(1, 101) < flipChance)
                            {
                                map[i][j] = -1;
                            }
                        }
                    }
                }
                for (int i = fillRegion.x; i <= fillRegion.x2; i++)
                {
                    for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                    {
                        if (map[i][j] == -1 && !pixelIsProtected[i][j])
                        {
                            map[i][j] = newGrowthPixel;
                        }
                    }
                }
            }

            return new List<MapRoom>(new MapRoom[0]);
        }
Esempio n. 24
0
        // pixel types:
        //    [0] = wall
        //    [1] = floor
        //    [2] = door
        //    >2  = other sorts of wall
        //    not on list = impenetrable
        // custom params:
        //    none; skips rooms with doNotConnect set to true
        public override List <MapRoom> Run(int[][] map, MapRectangle fillRegion,
                                           List <MapRoom> roomsToInclude)
        {
            bool debug = false;

            if (debug)
            {
                Console.WriteLine("DCMG start, " + roomsToInclude.Count +
                                  " rooms");
            }
            int corridorPixelType = 1234567;

            // pass 1 : get all the rooms connected to each other

            List <int> alreadyConnectedRoomIndices = new List <int>();

            for (int i = 0; (i < roomsToInclude.Count) &&
                 (alreadyConnectedRoomIndices.Count < 1); i++)
            {
                if (!roomsToInclude[i].doNotConnect)
                {
                    alreadyConnectedRoomIndices.Add(i);
                    if (debug)
                    {
                        Console.WriteLine("DCMG to connect room " + i);
                    }
                }
            }

            if (alreadyConnectedRoomIndices.Count < 1)
            {
                // none of the rooms want to be hooked up to each other
                return(roomsToInclude);
            }

            // distanceMap = -1 for impassable squares
            int[][] distanceMap = Allocate2DIntArray(fillRegion.w,
                                                     fillRegion.h);
            // fromDirectionMap = -1 for unvisited, 0 1 2 3 = from N S E W
            int[][] fromDirectionMap = Allocate2DIntArray(fillRegion.w,
                                                          fillRegion.h);
            // set true for the goal squares of a search
            bool[][] goalMap = Allocate2DBoolArray(fillRegion.w,
                                                   fillRegion.h);
            // > 0 for squares that are expensive to step into
            int[][] extraCostMap = Allocate2DIntArray(fillRegion.w,
                                                      fillRegion.h);
            if (intoPixelCostPenalty != null)
            {
                for (int i = 0; i < fillRegion.w; i++)
                {
                    for (int j = 0; j < fillRegion.h; j++)
                    {
                        int pixel = map[fillRegion.x + i][fillRegion.y + j];
                        if (pixel >= 0 && pixel < intoPixelCostPenalty.Length)
                        {
                            extraCostMap[i][j] = intoPixelCostPenalty[pixel];
                        }
                    }
                }
            }

            for (int i = alreadyConnectedRoomIndices[0] + 1;
                 i < roomsToInclude.Count; i++)
            {
                MapRoom thisRoom = roomsToInclude[i];
                if (!thisRoom.doNotConnect)
                {
                    if (debug)
                    {
                        Console.WriteLine("DCMG try to connect " + i +
                                          " to net");
                    }
                    int bestDoorIndex           = -1;
                    int bestDoorDistanceSquared = 0;
                    int bestTargetRoomIndex     = -1;
                    for (int j = 0; j < thisRoom.doors.Count; j++)
                    {
                        for (int k = 0; k < alreadyConnectedRoomIndices.Count;
                             k++)
                        {
                            int     testRoomIndex       = alreadyConnectedRoomIndices[k];
                            MapRoom r2                  = roomsToInclude[testRoomIndex];
                            int     dx                  = thisRoom.doors[j].x - r2.bounds.xCenter;
                            int     dy                  = thisRoom.doors[j].y - r2.bounds.yCenter;
                            int     testDistanceSquared = dx * dx + dy * dy;
                            if (bestTargetRoomIndex == -1 ||
                                testDistanceSquared < bestDoorDistanceSquared)
                            {
                                bestTargetRoomIndex     = testRoomIndex;
                                bestDoorIndex           = j;
                                bestDoorDistanceSquared = testDistanceSquared;
                                if (debug)
                                {
                                    Console.WriteLine("   new closest door is "
                                                      + j + " to room " + testRoomIndex +
                                                      " from room " + i);
                                }
                            }
                        }
                    }
                    if (bestDoorIndex != -1)
                    {
                        // run a BFS corridor from door bestDoor of
                        // roomsToInclude[i] to any existing corridor or
                        // any door of roomsToInclude[bestTargetRoomIndex]

                        Clear2DIntArray(fromDirectionMap, -1); // unvisited

                        // set all of the rooms interiors and walls to
                        // impassable

                        Clear2DIntArray(distanceMap, 100000000);
                        foreach (MapRoom r in roomsToInclude)
                        {
                            for (int j = 1; j < r.bounds.w - 1; j++)
                            {
                                int dx = r.bounds.x + j - fillRegion.x;
                                for (int k = 1; k < r.bounds.h - 1; k++)
                                {
                                    int dy = r.bounds.y + k - fillRegion.y;
                                    distanceMap[dx][dy] = -1;
                                }
                            }
                        }

                        // set up the goals

                        Clear2DBoolArray(goalMap);
                        MapRoom targetRoom = roomsToInclude[
                            bestTargetRoomIndex];
                        for (int j = 1; j < targetRoom.bounds.w - 1; j++)
                        {
                            for (int k = 1; k < targetRoom.bounds.h - 1; k++)
                            {
                                goalMap[j + targetRoom.bounds.x - fillRegion.x][
                                    k + targetRoom.bounds.y - fillRegion.y] =
                                    true;
                            }
                        }
                        for (int j = 0; j < targetRoom.doors.Count; j++)
                        {
                            int dx = targetRoom.doors[j].x - fillRegion.x;
                            int dy = targetRoom.doors[j].y - fillRegion.y;
                            goalMap[dx][dy]     = true;
                            distanceMap[dx][dy] = 1000000;
                        }

                        // also load the existing cooridors into the goal map
                        for (int j = 0; j < fillRegion.w; j++)
                        {
                            for (int k = 0; k < fillRegion.h; k++)
                            {
                                if (map[fillRegion.x + j][fillRegion.y + k] ==
                                    corridorPixelType)
                                {
                                    goalMap[j][k] = true;
                                }
                            }
                        }

                        bool success = ExtendBFSCorridor(goalMap, distanceMap,
                                                         extraCostMap, fromDirectionMap,
                                                         thisRoom.doors[bestDoorIndex].x - fillRegion.x,
                                                         thisRoom.doors[bestDoorIndex].y - fillRegion.y,
                                                         map, fillRegion, corridorPixelType, debug);
                        if (success)
                        {
                            alreadyConnectedRoomIndices.Add(i);
                        }
                        if (debug)
                        {
                            Console.WriteLine("   ran route from door " +
                                              bestDoorIndex + " success = " + success);
                        }
                    }
                }
            }

            // convert corridorPixelType to pixelTypes[1]

            SearchAndReplace2DIntArray(map, corridorPixelType, pixelTypes[1]);

            return(roomsToInclude);
        }
        // returns a Path if there is one or null if not
        public static Path BFSPath(int xStart, int yStart, int xEnd, int yEnd,
                                   CanStep stepFrom, CanStep stepTo, StepCost costFrom, DirectedStepCost costTo,
                                   MapRectangle limits, bool allowDiagonalSteps)
        {
            bool debug = false;

            if (debug)
            {
                Console.WriteLine("BFS start");
            }

            // update bestCost to hold the Dijkstra map
            if (bestCost == null || bestCost.Length < limits.w)
            {
                bestCost    = new int[limits.w][];
                visitedFrom = new eStep[limits.w][];
            }
            if (bestCost[0] == null || bestCost[0].Length < limits.h)
            {
                for (int x = 0; x < limits.w; x++)
                {
                    bestCost[x]    = new int[limits.h];
                    visitedFrom[x] = new eStep[limits.h];
                }
            }

            // clear bestCost to -1 = unvisited
            for (int x = 0; x < limits.w; x++)
            {
                for (int y = 0; y < limits.h; y++)
                {
                    bestCost[x][y] = -1;
                }
            }

            // forward pass
            List <int> frontX    = new List <int>();
            List <int> frontY    = new List <int>();
            List <int> newFrontX = new List <int>();
            List <int> newFrontY = new List <int>();

            frontX.Add(xStart);
            frontY.Add(yStart);
            bestCost[xStart - limits.x][yStart - limits.y] = 0;
            bool done = false;

            while (!done)
            {
                if (debug)
                {
                    Console.WriteLine("BFS new iteration, front size = " +
                                      frontX.Count);
                }
                newFrontX.Clear();
                newFrontY.Clear();
                done = true;
                for (int i = 0; i < frontX.Count; i++)
                {
                    int baseCost = bestCost[frontX[i] - limits.x][
                        frontY[i] - limits.y];
                    if (costFrom != null)
                    {
                        baseCost += costFrom(frontX[i], frontY[i]);
                    }
                    if (stepFrom == null || stepFrom(frontX[i], frontY[i]))
                    {
                        for (int j = 0; j < 8; j += (allowDiagonalSteps ? 1 : 2))
                        {
                            int xNew = frontX[i] + StepDX[j];
                            int yNew = frontY[i] + StepDY[j];
                            if (debug)
                            {
                                Console.WriteLine("   attempt step from " + frontX[i] +
                                                  ", " + frontY[i] + " dir " + j + " delta = " +
                                                  StepDX[j] + ", " + StepDY[j] + " to " + xNew + ", " +
                                                  yNew);
                            }
                            if (xNew >= limits.x && yNew >= limits.y &&
                                xNew <= limits.x2 && yNew <= limits.y2 &&
                                (stepTo == null || stepTo(xNew, yNew)))
                            {
                                int newCost = baseCost;
                                if (costTo != null)
                                {
                                    newCost += costTo(xNew, yNew, (eStep)j);
                                }
                                int dx          = xNew - limits.x;
                                int dy          = yNew - limits.y;
                                int currentCost = bestCost[dx][dy];
                                if (currentCost == -1 ||
                                    currentCost > newCost)
                                {
                                    bestCost[dx][dy]    = newCost;
                                    visitedFrom[dx][dy] = ReverseStep[
                                        (int)j];
                                    newFrontX.Add(xNew);
                                    newFrontY.Add(yNew);
                                    if (debug)
                                    {
                                        Console.WriteLine("  step to " + xNew +
                                                          ", " + yNew + " new cost = " +
                                                          newCost);
                                    }
                                    done = false;
                                }
                            }
                        }
                    }
                }
                if (!done)
                {
                    List <int> swap = newFrontX; newFrontX = frontX; frontX = swap;
                    swap = newFrontY; newFrontY = frontY; frontY = swap;
                }
            }


            if (bestCost[xEnd - limits.x][yEnd - limits.y] != -1)
            {
                // reverse pass and path gen
                int          x = xEnd, y = yEnd;
                List <eStep> steps = new List <eStep>();
                while (x != xStart || y != yStart)
                {
                    eStep backStep = visitedFrom[x - limits.x][y - limits.y];
                    steps.Add(backStep);
                    int dx = StepDX[(int)backStep];
                    int dy = StepDY[(int)backStep];
                    x += dx;
                    y += dy;
                }
                Path solution = new Path(new eStep[steps.Count]);
                for (int i = 0; i < steps.Count; i++)
                {
                    solution.Steps[i] = ReverseStep[(int)steps[steps.Count - i - 1]];
                }
                return(solution);
            }
            else
            {
                return(null); // there is no path
            }
        }
        // pixel types: 
        //    [0] = wall
        //    [1] = floor
        //    [2] = door
        //    >2  = other sorts of wall
        //    not on list = impenetrable
        // custom params:
        //    none; skips rooms with doNotConnect set to true
        public override List<MapRoom> Run(int[][] map, MapRectangle fillRegion,
           List<MapRoom> roomsToInclude)
        {
            bool debug = false;
            if (debug) 
            {
                Console.WriteLine("DCMG start, " + roomsToInclude.Count +
                   " rooms");
            }
            int corridorPixelType = 1234567;

            // pass 1 : get all the rooms connected to each other

            List<int> alreadyConnectedRoomIndices = new List<int>();
            for (int i = 0; (i < roomsToInclude.Count) &&
               (alreadyConnectedRoomIndices.Count < 1); i++)
            {
                if (!roomsToInclude[i].doNotConnect)
                {
                    alreadyConnectedRoomIndices.Add(i);
                    if (debug)
                    {
                        Console.WriteLine("DCMG to connect room " + i);
                    }
                }
            }

            if (alreadyConnectedRoomIndices.Count < 1)
            {
                // none of the rooms want to be hooked up to each other
                return roomsToInclude;
            }

            // distanceMap = -1 for impassable squares
            int[][] distanceMap = Allocate2DIntArray(fillRegion.w,
               fillRegion.h);
            // fromDirectionMap = -1 for unvisited, 0 1 2 3 = from N S E W
            int[][] fromDirectionMap = Allocate2DIntArray(fillRegion.w,
               fillRegion.h);
            // set true for the goal squares of a search
            bool[][] goalMap = Allocate2DBoolArray(fillRegion.w,
               fillRegion.h);
            // > 0 for squares that are expensive to step into
            int[][] extraCostMap = Allocate2DIntArray(fillRegion.w,
               fillRegion.h);
            if (intoPixelCostPenalty != null)
            {
                for (int i = 0; i < fillRegion.w; i++)
                {
                    for (int j = 0; j < fillRegion.h; j++)
                    {
                        int pixel = map[fillRegion.x + i][fillRegion.y + j];
                        if (pixel >= 0 && pixel < intoPixelCostPenalty.Length)
                        {
                            extraCostMap[i][j] = intoPixelCostPenalty[pixel];
                        }
                    }
                }
            }

            for (int i = alreadyConnectedRoomIndices[0] + 1;
               i < roomsToInclude.Count; i++)
            {
                MapRoom thisRoom = roomsToInclude[i];
                if (!thisRoom.doNotConnect)
                {
                    if (debug)
                    {
                        Console.WriteLine("DCMG try to connect " + i + 
                           " to net");
                    }
                    int bestDoorIndex = -1;
                    int bestDoorDistanceSquared = 0;
                    int bestTargetRoomIndex = -1;
                    for (int j = 0; j < thisRoom.doors.Count; j++)
                    {
                        for (int k = 0; k < alreadyConnectedRoomIndices.Count;
                           k++)
                        {
                            int testRoomIndex = alreadyConnectedRoomIndices[k];
                            MapRoom r2 = roomsToInclude[testRoomIndex];
                            int dx = thisRoom.doors[j].x - r2.bounds.xCenter;
                            int dy = thisRoom.doors[j].y - r2.bounds.yCenter;
                            int testDistanceSquared = dx * dx + dy * dy;
                            if (bestTargetRoomIndex == -1 ||
                               testDistanceSquared < bestDoorDistanceSquared)
                            {
                                bestTargetRoomIndex = testRoomIndex;
                                bestDoorIndex = j;
                                bestDoorDistanceSquared = testDistanceSquared;
                                if (debug)
                                {
                                    Console.WriteLine("   new closest door is "
                                       + j + " to room " + testRoomIndex +
                                       " from room " + i);
                                }
                            }
                        }
                    }
                    if (bestDoorIndex != -1)
                    {
                        // run a BFS corridor from door bestDoor of 
                        // roomsToInclude[i] to any existing corridor or 
                        // any door of roomsToInclude[bestTargetRoomIndex]

                        Clear2DIntArray(fromDirectionMap, -1); // unvisited

                        // set all of the rooms interiors and walls to 
                        // impassable

                        Clear2DIntArray(distanceMap, 100000000);
                        foreach (MapRoom r in roomsToInclude)
                        {
                            for (int j = 1; j < r.bounds.w - 1; j++)
                            {
                                int dx = r.bounds.x + j - fillRegion.x;
                                for (int k = 1; k < r.bounds.h - 1; k++)
                                {
                                    int dy = r.bounds.y + k - fillRegion.y;
                                    distanceMap[dx][dy] = -1;
                                }
                            }
                        }

                        // set up the goals

                        Clear2DBoolArray(goalMap);
                        MapRoom targetRoom = roomsToInclude[
                           bestTargetRoomIndex];
                        for (int j = 1; j < targetRoom.bounds.w - 1; j++)
                        {
                            for (int k = 1; k < targetRoom.bounds.h - 1; k++)
                            {
                                goalMap[j + targetRoom.bounds.x - fillRegion.x][
                                   k + targetRoom.bounds.y - fillRegion.y] = 
                                   true;
                            }
                        }
                        for (int j = 0; j < targetRoom.doors.Count; j++)
                        {
                            int dx = targetRoom.doors[j].x - fillRegion.x;
                            int dy = targetRoom.doors[j].y - fillRegion.y;
                            goalMap[dx][dy] = true;
                            distanceMap[dx][dy] = 1000000;
                        }

                        // also load the existing cooridors into the goal map
                        for (int j = 0; j < fillRegion.w; j++)
                        {
                            for (int k = 0; k < fillRegion.h; k++)
                            {
                                if (map[fillRegion.x + j][fillRegion.y + k] ==
                                   corridorPixelType)
                                {
                                    goalMap[j][k] = true;
                                }
                            }
                        }

                        bool success = ExtendBFSCorridor(goalMap, distanceMap,
                           extraCostMap, fromDirectionMap,
                           thisRoom.doors[bestDoorIndex].x - fillRegion.x,
                           thisRoom.doors[bestDoorIndex].y - fillRegion.y,
                           map, fillRegion, corridorPixelType, debug);
                        if (success)
                        {
                            alreadyConnectedRoomIndices.Add(i);
                        }
                        if (debug)
                        {
                            Console.WriteLine("   ran route from door " +
                               bestDoorIndex + " success = " + success);
                        }
                    }
                }
            }

            // convert corridorPixelType to pixelTypes[1]

            SearchAndReplace2DIntArray(map, corridorPixelType, pixelTypes[1]);

            return roomsToInclude;
        }
        // pixel types: 
        //    [0] = wall
        //    [1] = floor
        //    [2] = door
        // custom params:
        //    none
        public override List<MapRoom> Run(int[][] map, MapRectangle fillRegion,
           List<MapRoom> roomsToInclude)
        {
            List<MapRoom> generatedRooms = new List<MapRoom>();

            // generate the rooms

            int mapArea = map[0].Length * map.Length;
            int typicalRoomArea = (minSide + maxSide) * (minSide + maxSide) / 4;
            int nRooms = mapArea * openPercentage / typicalRoomArea;
            for (int i = 0; i < nRooms; i++)
            {
                int maxPlacementTries = 10;
                bool placed = false;
                int width = NextRandom(minSide, maxSide + 1);
                int height = NextRandom(minSide, maxSide + 1);
                if (width < fillRegion.w && height < fillRegion.h)
                {
                    int x0 = 0, y0 = 0;
                    for (int j = 0; (j < maxPlacementTries) && (!placed); j++)
                    {
                        x0 = NextRandom(0, fillRegion.w - width);
                        y0 = NextRandom(0, fillRegion.h - height);
                        placed = true;
                        for (int k = 0; k < roomsToInclude.Count && placed; k++)
                        {
                            if (RegionOverlapsRoom(x0, y0, height, width,
                               roomsToInclude[k]))
                            {
                                placed = false;
                            }
                        }
                        for (int k = 0; k < generatedRooms.Count && placed; k++)
                        {
                            if (RegionOverlapsRoom(x0, y0, height, width,
                               generatedRooms[k]))
                            {
                                placed = false;
                            }
                        }
                    }
                    if (placed)
                    {
                        generatedRooms.Add(new MapRoom(new MapRectangle(
                           x0, y0, width, height)));
                    }
                }
            }

            // add doors to generatedRooms
            for (int i = 0; i < generatedRooms.Count; i++)
            {
                int nDoors = NextRandom(1, maxDoorsPerRoom + 1);
                MapRoom r = generatedRooms[i];
                for (int j = 0; j < nDoors; j++)
                {
                    int side = NextRandom(0, 4);
                    int offset = NextRandom(1, ((side == 0 || side == 2) ? 
                       r.bounds.w : r.bounds.h) - 1);
                    r.doors.Add(new MapRoomDoor(side, offset, r));
                }
                // clean out any duplicated doors
                for (int j = r.doors.Count - 1; j > 0; j--)
                {
                    bool dupe = false;
                    for (int k = 0; k < j; k++)
                    {
                        if (r.doors[j].side == r.doors[k].side &&
                           r.doors[j].offset == r.doors[k].offset)
                        {
                            dupe = true;
                        }
                    }
                    if (dupe)
                    {
                        r.doors.RemoveAt(j);
                    }
                }
            }

            // now set the map tiles for doors, walls, and floors
            for (int i = 0; i < generatedRooms.Count; i++)
            {
                MapRoom r = generatedRooms[i];
                for (int j = r.bounds.x; j < r.bounds.x + r.bounds.w; j++)
                {
                    for (int k = r.bounds.y; k < r.bounds.y + r.bounds.h; k++)
                    {
                        bool isBorder = (j == r.bounds.x) ||
                           (j == r.bounds.x + r.bounds.w - 1) ||
                           (k == r.bounds.y) ||
                           (k == r.bounds.y + r.bounds.h - 1);
                        map[j][k] = pixelTypes[isBorder ? 0 : 1];
                    }
                }
                for (int j = 0; j < r.doors.Count; j++)
                {
                    int x = r.bounds.x, y = r.bounds.y;
                    switch (r.doors[j].side)
                    {
                        case 0: // N, offset from W
                           x += r.doors[j].offset;
                           break;
                        case 1: // E, offset from N
                           x += r.bounds.w - 1;
                           y += r.doors[j].offset;
                           break;
                        case 2: // S, offset from W
                           x += r.doors[j].offset;
                           y += r.bounds.h - 1;
                           break;
                        case 3: // W, offset from N
                           y += r.doors[j].offset;
                           break;
                    }
                    map[x][y] = pixelTypes[2];
                }
            }

            return generatedRooms;
        }
        private List<MapRoom> BSPBlock(int levelsLeft, int corridorWidth, bool horizontalCut,
           bool[][] pixelIsProtected, int[][] map, MapRectangle fillRegion)
        {
            MapRectangle firstSubregion, secondSubregion;
            int dx = fillRegion.x;
            int dy = fillRegion.y;
            int minimumDim = corridorWidth + 2 * minimumRoomWidth + 4;
            int lowCutSpot = minimumRoomWidth + 2;
            if (horizontalCut)
            {
                if (fillRegion.h <= minimumDim)
                {
                    return new List<MapRoom>(new MapRoom[]{new MapRoom(fillRegion)});
                }
                // o r r r x c c x r r r o
                //         ^ 
                int highCutSpot = fillRegion.h - minimumRoomWidth - corridorWidth - 3;
                int cutSpot = NextRandom(lowCutSpot, highCutSpot + 1);
                for (int i = 0; i < fillRegion.w; i++) 
                {
                    map[i + dx][cutSpot + dy] = pixelTypes[0];
                    for (int j = 1; j <= corridorWidth; j++)
                    {
                        map[i + dx][cutSpot + j + dy] = pixelTypes[1];
                    }
                    map[i + dx][cutSpot + corridorWidth + 1 + dy] = pixelTypes[0];
                }
                firstSubregion = new MapRectangle(fillRegion.x, fillRegion.y,
                   fillRegion.w, cutSpot + 1);
                secondSubregion = new MapRectangle(fillRegion.x, fillRegion.y +
                   cutSpot + corridorWidth + 1, fillRegion.w, fillRegion.h - cutSpot -
                   corridorWidth - 1);
            }
            else
            {
                if (fillRegion.w <= minimumDim)
                {
                    return new List<MapRoom>(new MapRoom[]{new MapRoom(fillRegion)});
                }
                int highCutSpot = fillRegion.w - minimumRoomWidth - corridorWidth - 3;
                int cutSpot = NextRandom(lowCutSpot, highCutSpot + 1);
                for (int i = 0; i < fillRegion.h; i++) 
                {
                    map[cutSpot + dx][i + dy] = pixelTypes[0];
                    for (int j = 1; j <= corridorWidth; j++)
                    {
                        map[cutSpot + j + dx][i + dy] = pixelTypes[1];
                    }
                    map[cutSpot + corridorWidth + 1 + dx][i + dy] = pixelTypes[0];
                }
                firstSubregion = new MapRectangle(fillRegion.x, fillRegion.y,
                   cutSpot + 1, fillRegion.h);
                secondSubregion = new MapRectangle(fillRegion.x + cutSpot + 
                   corridorWidth + 1,
                   fillRegion.y, fillRegion.w - cutSpot - corridorWidth - 1,
                   fillRegion.h);
            }

            if (levelsLeft >= 1)
            {
                // split me

                int newCorridorWidth = corridorWidth - 1;
                if (newCorridorWidth <= 1)
                {
                    newCorridorWidth = 1;
                }
                List<MapRoom> list1 = BSPBlock(levelsLeft - 1, newCorridorWidth, !horizontalCut,
                   pixelIsProtected, map, firstSubregion);
                List<MapRoom> list2 = BSPBlock(levelsLeft - 1, newCorridorWidth, !horizontalCut,
                   pixelIsProtected, map, secondSubregion);
                list1.AddRange(list2);
                return list1;
            }
            else
            {
                return new List<MapRoom>(new MapRoom[]{new MapRoom(firstSubregion),
                   new MapRoom(secondSubregion)});
            }
        }
Esempio n. 29
0
        public override List<MapRoom> Run(int[][] map, MapRectangle fillRegion,
           List<MapRoom> roomsToInclude)
        {
            bool[][] pixelIsProtected = BuildProtectedMap(roomsToInclude,
               map.Length, map[0].Length);
          
            // clear to solid
            for (int i = fillRegion.x; i <= fillRegion.x2; i++)
            {
                for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                {
                    if (!pixelIsProtected[i][j])
                    {
                        map[i][j] = pixelTypes[0];
                    }
                }
            }

            // put in the horizontal seed corridors
            int n = fillRegion.h / seedCorridorAverageSpacing;
            for (int i = 0; i < n; i++)
            {
                int l = NextRandom(seedCorridorAverageLength / 2,
                   3 * seedCorridorAverageLength / 2 + 1);
                int offset = 0;
                if (l >= fillRegion.w)
                {
                    l = fillRegion.w;
                }
                else
                {
                    offset = NextRandom(0, fillRegion.w - l + 1);
                }
                int crossOffset = NextRandom(fillRegion.y, fillRegion.y2 + 1);
                for (int j = offset; j < offset + l; j++)
                {
                    if (!pixelIsProtected[j + fillRegion.x][crossOffset])
                    {
                        map[j + fillRegion.x][crossOffset] = pixelTypes[1];
                    }
                }
            }

            // put in the vertical seed corridors
            n = fillRegion.w / seedCorridorAverageSpacing;
            for (int i = 0; i < n; i++)
            {
                int l = NextRandom(seedCorridorAverageLength / 2,
                   3 * seedCorridorAverageLength / 2 + 1);
                int offset = 0;
                if (l >= fillRegion.h)
                {
                    l = fillRegion.h;
                }
                else
                {
                    offset = NextRandom(0, fillRegion.h - l + 1);
                }
                int crossOffset = NextRandom(fillRegion.x, fillRegion.x2 + 1);
                for (int j = offset; j < offset + l; j++)
                {
                    if (!pixelIsProtected[crossOffset][j + fillRegion.y])
                    {
                        map[crossOffset][j + fillRegion.y] = pixelTypes[1];
                    }
                }
            }

            for (int k = 0; k < numberOfDecays; k++)
            {
                for (int i = fillRegion.x; i <= fillRegion.x2; i++)
                {
                    for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                    {
                        if (map[i][j] == pixelTypes[0] && !pixelIsProtected[i][j])
                        {
                            int nNeighbors = 0;
                            if (i > 0)
                            {
                               if (j > 0)
                               {
                                   if (map[i - 1][j - 1] == pixelTypes[1])
                                   {
                                       nNeighbors++;
                                   }
                               }
                               if (j < map[i].Length - 1)
                               {
                                   if (map[i - 1][j + 1] == pixelTypes[1])
                                   {
                                       nNeighbors++;
                                   }
                               }
                               if (map[i - 1][j] == pixelTypes[1])
                               {
                                   nNeighbors++;
                               }
                            }
                            if (i < map.Length - 1)
                            {
                               if (j > 0)
                               {
                                   if (map[i + 1][j - 1] == pixelTypes[1])
                                   {
                                       nNeighbors++;
                                   }
                               }
                               if (j < map[i].Length - 1)
                               {
                                   if (map[i + 1][j + 1] == pixelTypes[1])
                                   {
                                       nNeighbors++;
                                   }
                               }
                               if (map[i + 1][j] == pixelTypes[1])
                               {
                                   nNeighbors++;
                               }
                            }
                            if (j > 0)
                            {
                                if (map[i][j - 1] == pixelTypes[1])
                                {
                                    nNeighbors++;
                                }
                            }
                            if (j < map[i].Length - 1)
                            {
                                if (map[i][j + 1] == pixelTypes[1])
                                {
                                    nNeighbors++;
                                }
                            }
                            int flipChance = nNeighbors * 
                               decayPercentPerDecayedNeighbor;
                            if (NextRandom(1, 101) < flipChance)
                            {
                                map[i][j] = -1;
                            }
                        }
                    }
                }
                for (int i = fillRegion.x; i <= fillRegion.x2; i++)
                {
                    for (int j = fillRegion.y; j <= fillRegion.y2; j++)
                    {
                        if (map[i][j] == -1 && !pixelIsProtected[i][j])
                        {
                            map[i][j] = pixelTypes[1];
                        }
                    }
                }
            }

            return new List<MapRoom>(new MapRoom[0]);
        }
Esempio n. 30
0
 public static void CalculateBresenhamProductsToRectangle(int fromX, int
    fromY, int[][] map, MapRectangle rectangle, UpdateProductForSquare
    update, int startingProduct, int[][] outputMap)
 {
     CalculateBresenhamProductsToRectangle(fromX, fromY, map,
        rectangle, update, startingProduct, false, true, outputMap);
 }
Esempio n. 31
0
        public static void CalculateBresenhamProductsToRectangle(int fromX, int
           fromY, int[][] map, MapRectangle rectangle, UpdateProductForSquare
           update, int startingProduct, bool includeFirstSquare, bool
           includeLastSquare, int[][] outputMap)
        {
            // top and bottom edges
            for (int x = rectangle.x; x <= rectangle.x2; x++)
            {
                outputMap[fromX][fromY] = startingProduct;
                CalculateBresenhamProductSquareToSquare(fromX, fromY,
                   x, rectangle.y, map,
                   (previous, mapval, xs, ys) => {
                      outputMap[xs][ys] = update(previous, mapval);
                      return outputMap[xs][ys];
                   }, startingProduct, includeFirstSquare, includeLastSquare);
                outputMap[fromX][fromY] = startingProduct;
                CalculateBresenhamProductSquareToSquare(fromX, fromY,
                   x, rectangle.y2, map,
                   (previous, mapval, xs, ys) => {
                      outputMap[xs][ys] = update(previous, mapval);
                      return outputMap[xs][ys];
                   }, startingProduct, includeFirstSquare, includeLastSquare);
            }

            // right and left edges
            for (int y = rectangle.y + 1; y <= rectangle.y2 - 1; y++)
            {
                outputMap[fromX][fromY] = startingProduct;
                CalculateBresenhamProductSquareToSquare(fromX, fromY,
                   rectangle.x, y, map,
                   (previous, mapval, xs, ys) => {
                      outputMap[xs][ys] = update(previous, mapval);
                      return outputMap[xs][ys];
                   }, startingProduct, includeFirstSquare, includeLastSquare);
                outputMap[fromX][fromY] = startingProduct;
                CalculateBresenhamProductSquareToSquare(fromX, fromY,
                   rectangle.x2, y, map,
                   (previous, mapval, xs, ys) => {
                      outputMap[xs][ys] = update(previous, mapval);
                      return outputMap[xs][ys];
                   }, startingProduct, includeFirstSquare, includeLastSquare);
            }
        }
Esempio n. 32
0
        static public void Main()
        {
            //UI d = new VT100UI();
            VT100UI d = new VT100UI();

            // This is just a placeholder

            for (int x = 0; x < 80; x++)
            {
                d.DrawAt(x, 3, " ", 0, 0, 0, 0, 0, 64);
            }

            for (int x = 0; x < 80; x++)
            {
                d.DrawAt(x, 22, " ", 0, 0, 0, 0, 0, 64);
            }

            UIMapElement map_element = d.MapElement(
                x: 0,
                y: 4,
                h: 17
                );

            ClearMapGenerator gen = new ClearMapGenerator(new int[] { 0, 0 },
                                                          MapCoordinate.GenerateRandom());

            map_element.map = new MapData(80, 40);
            ClearMapGenerator gen2 = new ClearMapGenerator(new int[] { 2, 1 },
                                                           MapCoordinate.GenerateRandom());

            gen2.Run(map_element.map.grid, new MapRectangle(10, 10, 10, 10), null);
            List <MapRoom> blockedList = new List <MapRoom>();
            MapRectangle   fullArea    = new MapRectangle(0, 0, 80, 40);

            blockedList.Add(new MapRoom(new MapRectangle(10, 10, 10, 10)));
            gen.Run(map_element.map.grid, fullArea, blockedList);

            DungeonRoomMapGenerator drmg = new DungeonRoomMapGenerator(new int[]
                                                                       { 5, 6, 7 }, MapCoordinate.GenerateRandom(), 5, 12, 10, 3);
            List <MapRoom> allRooms = drmg.Run(map_element.map.grid, fullArea, blockedList);

            DungeonCorridorMapGenerator dcmg = new DungeonCorridorMapGenerator(
                new int[] { 5, 6, 7 }, MapCoordinate.GenerateRandom(), 2,
                new int[] { 0, 100000, 100000, 0, 0, 100000, 0, 0 });

            dcmg.Run(map_element.map.grid, fullArea, allRooms);

            map_element.map.AddSpaceType(glyph: '#', r: 128, g: 128, b: 128);
            map_element.map.AddSpaceType(glyph: '#', r: 128, g: 128, b: 128);
            map_element.map.AddSpaceType(glyph: '#', r: 128, g: 128, b: 128);
            map_element.map.AddSpaceType(glyph: '*');
            map_element.map.AddSpaceType(glyph: '~', r:   0, g:  32, b: 255);
            map_element.map.AddSpaceType(glyph: '#', r: 128, g: 128, b: 128);
            map_element.map.AddSpaceType(glyph: '.', r:  64, g:  64, b:  64);
            map_element.map.AddSpaceType(glyph: '+', r: 128, g:  64, b:   0);

            d.DrawAt(54, 3, " 5 targets in range    ", 255, 255, 192, 0, 0, 0);
            d.DrawAt(74, 3, "[T] ", 192, 192, 255, 0, 0, 0);
            d.DrawAt(58, 22, " Press     for help ", 255, 255, 192, 0, 0, 0);
            d.DrawAt(65, 22, "[?]", 192, 192, 255, 0, 0, 0);

            map_element.Draw();

            d.DrawScreen();
        }
        private List <MapRoom> BSPBlock(int levelsLeft, int corridorWidth, bool horizontalCut,
                                        bool[][] pixelIsProtected, int[][] map, MapRectangle fillRegion)
        {
            MapRectangle firstSubregion, secondSubregion;
            int          dx         = fillRegion.x;
            int          dy         = fillRegion.y;
            int          minimumDim = corridorWidth + 2 * minimumRoomWidth + 4;
            int          lowCutSpot = minimumRoomWidth + 2;

            if (horizontalCut)
            {
                if (fillRegion.h <= minimumDim)
                {
                    return(new List <MapRoom>(new MapRoom[] { new MapRoom(fillRegion) }));
                }
                // o r r r x c c x r r r o
                //         ^
                int highCutSpot = fillRegion.h - minimumRoomWidth - corridorWidth - 3;
                int cutSpot     = NextRandom(lowCutSpot, highCutSpot + 1);
                for (int i = 0; i < fillRegion.w; i++)
                {
                    map[i + dx][cutSpot + dy] = pixelTypes[0];
                    for (int j = 1; j <= corridorWidth; j++)
                    {
                        map[i + dx][cutSpot + j + dy] = pixelTypes[1];
                    }
                    map[i + dx][cutSpot + corridorWidth + 1 + dy] = pixelTypes[0];
                }
                firstSubregion = new MapRectangle(fillRegion.x, fillRegion.y,
                                                  fillRegion.w, cutSpot + 1);
                secondSubregion = new MapRectangle(fillRegion.x, fillRegion.y +
                                                   cutSpot + corridorWidth + 1, fillRegion.w, fillRegion.h - cutSpot -
                                                   corridorWidth - 1);
            }
            else
            {
                if (fillRegion.w <= minimumDim)
                {
                    return(new List <MapRoom>(new MapRoom[] { new MapRoom(fillRegion) }));
                }
                int highCutSpot = fillRegion.w - minimumRoomWidth - corridorWidth - 3;
                int cutSpot     = NextRandom(lowCutSpot, highCutSpot + 1);
                for (int i = 0; i < fillRegion.h; i++)
                {
                    map[cutSpot + dx][i + dy] = pixelTypes[0];
                    for (int j = 1; j <= corridorWidth; j++)
                    {
                        map[cutSpot + j + dx][i + dy] = pixelTypes[1];
                    }
                    map[cutSpot + corridorWidth + 1 + dx][i + dy] = pixelTypes[0];
                }
                firstSubregion = new MapRectangle(fillRegion.x, fillRegion.y,
                                                  cutSpot + 1, fillRegion.h);
                secondSubregion = new MapRectangle(fillRegion.x + cutSpot +
                                                   corridorWidth + 1,
                                                   fillRegion.y, fillRegion.w - cutSpot - corridorWidth - 1,
                                                   fillRegion.h);
            }

            if (levelsLeft >= 1)
            {
                // split me

                int newCorridorWidth = corridorWidth - 1;
                if (newCorridorWidth <= 1)
                {
                    newCorridorWidth = 1;
                }
                List <MapRoom> list1 = BSPBlock(levelsLeft - 1, newCorridorWidth, !horizontalCut,
                                                pixelIsProtected, map, firstSubregion);
                List <MapRoom> list2 = BSPBlock(levelsLeft - 1, newCorridorWidth, !horizontalCut,
                                                pixelIsProtected, map, secondSubregion);
                list1.AddRange(list2);
                return(list1);
            }
            else
            {
                return(new List <MapRoom>(new MapRoom[] { new MapRoom(firstSubregion),
                                                          new MapRoom(secondSubregion) }));
            }
        }