Exemple #1
0
        /* Places a trap. All traps are untyped until discovered. */
        public static void place_trap(Cave c, int y, int x)
        {
            Misc.assert(Cave.cave_in_bounds(c, y, x));
            Misc.assert(Cave.cave_isempty(c, y, x));

            /* Place an invisible trap */
            Cave.cave_set_feat(c, y, x, Cave.FEAT_INVIS);
        }
Exemple #2
0
        /**
         * Create a tunnel connecting a region to one of its nearest neighbors.
         */
        static void join_region(Cave c, int[] colors, int[] counts, int color)
        {
            int i;
            int h = c.height;
            int w = c.width;
            int size = h * w;

            //struct queue *queue = q_new(size);
            Queue<int> queue = new Queue<int>();

            int[] previous = new int[size];//C_ZNEW(size, int);
            //array_filler(previous, -1, size);

            for (i = 0; i < size; i++) {
                previous[i] = -1;
                if (colors[i] == color) {
                    queue.Enqueue(i);
                    previous[i] = i;
                }
            }

            while (queue.Count() > 0) {
                int n = queue.Dequeue();

                int color2 = colors[n];
                if (color2 != 0 && color2 != color) {
                    while (colors[n] != color) {
                        int x, y;
                        lab_toyx(n, w, out y, out x);
                        colors[n] = color;
                        if (!cave_isperm(c, y, x) && !cave_isvault(c, y, x)) {
                            cave_set_feat(c, y, x, FEAT_FLOOR);
                        }
                        n = previous[n];
                    }
                    fix_colors(colors, counts, color2, color, size);
                    break;
                }

                for (i = 0; i < 4; i++) {
                    int y, x, y2, x2, n2;
                    lab_toyx(n, w, out y, out x);

                    y2 = y + yds[i];
                    x2 = x + xds[i];

                    /* make sure we stay inside the boundaries */
                    if (y2 < 0 || y2 >= h) continue;
                    if (x2 < 0 || x2 >= w) continue;

                    /* permanent walls and vault squares should not be handled */
                    //Nick: the below two were commented out... Did I do that?
                    if (cave_isperm(c, y2, x2)) continue;
                    if (cave_isvault(c, y2, x2)) continue;

                    n2 = lab_toi(y2, x2, w);
                    if (previous[n2] >= 0) continue;

                    queue.Enqueue(n2);
                    previous[n2] = n;
                }
            }

            //q_free(queue);
            //FREE(previous);
        }
Exemple #3
0
        /**
         * Build a greater vaults.
         *
         * Since Greater Vaults are so large (4x6 blocks, in a 6x18 dungeon) there is
         * a 63% chance that a randomly chosen quadrant to start a GV on won't work.
         * To balance this, we give Greater Vaults an artificially high probability
         * of being attempted, and then in this function use a depth check to cancel
         * vault creation except at deep depths.
         *
         * The following code should make a greater vault with frequencies:
         * dlvl  freq
         * 100+  18.0%
         * 90-99 16.0 - 18.0%
         * 80-89 10.0 - 11.0%
         * 70-79  5.7 -  6.5%
         * 60-69  3.3 -  3.8%
         * 50-59  1.8 -  2.1%
         * 0-49   0.0 -  1.0%
         */
        static bool build_greater_vault(Cave c, int y0, int x0)
        {
            throw new NotImplementedException();
            //int i;
            //int numerator   = 2;
            //int denominator = 3;

            ///* Only try to build a GV as the first room. */
            //if (dun.cent_n > 0) return false;

            ///* Level 90+ has a 2/3 chance, level 80-89 has 4/9, ... */
            //for(i = 90; i > c.depth; i -= 10) {
            //    numerator *= 2;
            //    denominator *= 3;
            //}

            ///* Attempt to pass the depth check and build a GV */
            //if (randint0(denominator) >= numerator) return false;

            //return build_vault_type(c, y0, x0, 8, "Greater vault");
        }
Exemple #4
0
        //#if 0 /* XXX d_m - is this meant to be in use? */
        //static void glow_point(Cave c, int y, int x) {
        //    int i, j;
        //    for (i = -1; i <= -1; i++)
        //        for (j = -1; j <= -1; j++)
        //            c.info[y + i][x + j] |= CAVE_GLOW;
        //}
        //#endif
        /**
         * Color a particular point, and all adjacent points.
         */
        static void build_color_point(Cave c, int[] colors, int[] counts, int y, int x, int color, bool diagonal)
        {
            int h = c.height;
            int w = c.width;
            int size = h * w;
            //struct queue *queue = q_new(size);
            Queue<int> queue = new Queue<int>();

            int dslimit = diagonal ? 8 : 4;

            int[] added = new int[size];//C_ZNEW(size, int);
            for(int i = 0; i < added.Length; i++) {
                added[i] = 0;
            }
            //array_filler(added, 0, size);

            queue.Enqueue(lab_toi(y, x, w));

            counts[color] = 0;

            while (queue.Count() > 0) {
                int i, y2, x2;
                int n2 = queue.Dequeue();

                lab_toyx(n2, w, out y2, out x2);

                if (ignore_point(cave, colors, y2, x2)) continue;

                colors[n2] = color;
                counts[color]++;

                /*if (lit) glow_point(c, y2, x2);*/

                for (i = 0; i < dslimit; i++) {
                    int y3 = y2 + yds[i];
                    int x3 = x2 + xds[i];
                    int n3 = lab_toi(y3, x3, w);
                    if (ignore_point(cave, colors, y3, x3)) continue;
                    if (added[n3] != 0) continue;

                    queue.Enqueue(n3);
                    added[n3] = 1;
                }
            }

            //FREE(added);
            //q_free(queue);
        }
Exemple #5
0
        //static void fill_xrange(Cave c, int y, int x1, int x2, int feat, int info) {
        //    int x;
        //    for (x = x1; x <= x2; x++) {
        //        cave_set_feat(c, y, x, feat);
        //        c.info[y][x] |= info;
        //    }
        //}
        //static void fill_yrange(Cave c, int x, int y1, int y2, int feat, int info) {
        //    int y;
        //    for (y = y1; y <= y2; y++) {
        //        cave_set_feat(c, y, x, feat);
        //        c.info[y][x] |= info;
        //    }
        //}
        //static void fill_circle(Cave c, int y0, int x0, int radius, int border, int feat, int info) {
        //    int i, last = 0;
        //    int r2 = radius * radius;
        //    for(i = 0; i <= radius; i++) {
        //        double j = sqrt(r2 - (i * i));
        //        int k = (int)(j + 0.5);
        //        int b = border;
        //        if (border && last > k) b++;
        //        fill_xrange(c, y0 - i, x0 - k - b, x0 + k + b, feat, info);
        //        fill_xrange(c, y0 + i, x0 - k - b, x0 + k + b, feat, info);
        //        fill_yrange(c, x0 - i, y0 - k - b, y0 + k + b, feat, info);
        //        fill_yrange(c, x0 + i, y0 - k - b, y0 + k + b, feat, info);
        //        last = k;
        //    }
        //}
        ///**
        // * Fill the lines of a cross/plus with a feature.
        // *
        // * The boundaries (y1, x1, y2, x2) are inclusive. When combined with
        // * draw_rectangle() this will generate a large rectangular room which is split
        // * into four sub-rooms.
        // */
        //static void generate_plus(Cave c, int y1, int x1, int y2, int x2, int feat) {
        //    int y, x;
        //    /* Find the center */
        //    int y0 = (y1 + y2) / 2;
        //    int x0 = (x1 + x2) / 2;
        //    assert(c);
        //    for (y = y1; y <= y2; y++) cave_set_feat(c, y, x0, feat);
        //    for (x = x1; x <= x2; x++) cave_set_feat(c, y0, x, feat);
        //}
        ///**
        // * Generate helper -- open all sides of a rectangle with a feature
        // */
        //static void generate_open(Cave c, int y1, int x1, int y2, int x2, int feat) {
        //    int y0, x0;
        //    /* Center */
        //    y0 = (y1 + y2) / 2;
        //    x0 = (x1 + x2) / 2;
        //    /* Open all sides */
        //    cave_set_feat(c, y1, x0, feat);
        //    cave_set_feat(c, y0, x1, feat);
        //    cave_set_feat(c, y2, x0, feat);
        //    cave_set_feat(c, y0, x2, feat);
        //}
        ///**
        // * Generate helper -- open one side of a rectangle with a feature
        // */
        //static void generate_hole(Cave c, int y1, int x1, int y2, int x2, int feat) {
        //    /* Find the center */
        //    int y0 = (y1 + y2) / 2;
        //    int x0 = (x1 + x2) / 2;
        //    assert(c);
        //    /* Open random side */
        //    switch (randint0(4)) {
        //        case 0: cave_set_feat(c, y1, x0, feat); break;
        //        case 1: cave_set_feat(c, y0, x1, feat); break;
        //        case 2: cave_set_feat(c, y2, x0, feat); break;
        //        case 3: cave_set_feat(c, y0, x2, feat); break;
        //    }
        //}
        /**
         * Build a circular room (interior radius 4-7).
         */
        static bool build_circular(Cave c, int y0, int x0)
        {
            throw new NotImplementedException();
            ///* Pick a room size */
            //int radius = 2 + Random.randint1(2) + Random.randint1(3);

            ///* Occasional light */
            //bool light = c.depth <= Random.randint1(25) ? true : false;

            ///* Mark interior squares as being in a room (optionally lit) */
            //int info = CAVE_ROOM | (light ? CAVE_GLOW : 0);

            ///* Generate outer walls and inner floors */
            //fill_circle(c, y0, x0, radius + 1, 1, FEAT_WALL_OUTER, info);
            //fill_circle(c, y0, x0, radius, 0, FEAT_FLOOR, info);

            ///* Especially large circular rooms will have a middle chamber */
            //if (radius - 4 > 0 && Random.randint0(4) < radius - 4) {
            //    /* choose a random direction */
            //    int cd, rd;
            //    Random.rand_dir(&rd, &cd);

            //    /* draw a room with a secret door on a random side */
            //    draw_rectangle(c, y0 - 2, x0 - 2, y0 + 2, x0 + 2, FEAT_WALL_INNER);
            //    cave_set_feat(c, y0 + cd * 2, x0 + rd * 2, FEAT_SECRET);

            //    /* Place a treasure in the vault */
            //    vault_objects(c, y0, x0, c.depth, Random.randint0(2));

            //    /* create some monsterss */
            //    vault_monsters(c, y0, x0, c.depth + 1, Random.randint0(3));
            //}

            //return true;
        }
Exemple #6
0
 /**
  * Allocates 'num' random objects in the dungeon.
  *
  * See alloc_object() for more information.
  */
 static void alloc_objects(Cave c, int set, int typ, int num, int depth, Origin origin)
 {
     int k;
     int l = 0;
     for (k = 0; k < num; k++) {
         bool ok = alloc_object(c, set, typ, depth, origin);
         if (!ok) l++;
     }
 }
Exemple #7
0
        /**
         * Place a random door at (x, y).
         *
         * The door generated could be closed, open, broken, or secret.
         */
        public static void place_random_door(Cave c, int y, int x)
        {
            int tmp = Random.randint0(100);

            if (tmp < 30)
                cave_set_feat(c, y, x, FEAT_OPEN);
            else if (tmp < 40)
                cave_set_feat(c, y, x, FEAT_BROKEN);
            else if (tmp < 60)
                cave_set_feat(c, y, x, FEAT_SECRET);
            else
                place_closed_door(c, y, x);
        }
Exemple #8
0
        /**
         * Place a random amount of gold at (x, y).
         */
        public static void place_gold(Cave c, int y, int x, int level, Origin origin)
        {
            Object.Object i_ptr;
            //object_type object_type_body;

            Misc.assert(cave_in_bounds(c, y, x));

            if (!cave_canputitem(c, y, x)) return;

            //i_ptr = &object_type_body;
            //object_wipe(i_ptr);
            i_ptr = new Object.Object();
            Object.Object.make_gold(ref i_ptr, level, (int)SVal.sval_gold.SV_GOLD_ANY);

            i_ptr.origin = origin;
            i_ptr.origin_depth = (byte)level;

            Object.Object.floor_carry(c, y, x, i_ptr);
        }
Exemple #9
0
 /**
  * Place rubble at (x, y).
  */
 static void place_rubble(Cave c, int y, int x)
 {
     cave_set_feat(c, y, x, FEAT_RUBBLE);
 }
Exemple #10
0
        /**
         * Place hidden squares that will be used to generate feeling
         */
        static void place_feeling(Cave c)
        {
            int y,x,i,j;
            int tries = 500;

            for (i = 0; i < FEELING_TOTAL; i++){
                for(j = 0; j < tries; j++){

                    /* Pick a random dungeon coordinate */
                    y = Random.randint0(DUNGEON_HGT);
                    x = Random.randint0(DUNGEON_WID);

                    /* Check to see if it is not a wall */
                    if (cave_iswall(c,y,x))
                        continue;

                    /* Check to see if it is already marked */
                    if (cave_isfeel(c,y,x))
                        continue;

                    /* Set the cave square appropriately */
                    c.info2[y][x] |= CAVE2_FEEL;

                    break;

                }
            }

            /* Reset number of feeling squares */
            c.feeling_squares = 0;
        }
Exemple #11
0
        /**
         * Return how many cardinal directions around (x, y) contain walls.
         */
        static int next_to_walls(Cave c, int y, int x)
        {
            int k = 0;
            Misc.assert(cave_in_bounds(c, y, x));

            if (cave_iswall(c, y + 1, x)) k++;
            if (cave_iswall(c, y - 1, x)) k++;
            if (cave_iswall(c, y, x + 1)) k++;
            if (cave_iswall(c, y, x - 1)) k++;

            return k;
        }
Exemple #12
0
        /**
         * Count the number of corridor grids adjacent to the given grid.
         *
         * This routine currently only counts actual "empty floor" grids which are not
         * in rooms.
         *
         * TODO: count stairs, open doors, closed doors?
         */
        static int next_to_corr(Cave c, int y1, int x1)
        {
            int i, k = 0;
            Misc.assert(cave_in_bounds(c, y1, x1));

            /* Scan adjacent grids */
            for (i = 0; i < 4; i++) {
                /* Extract the location */
                int y = y1 + Misc.ddy_ddd[i];
                int x = x1 + Misc.ddx_ddd[i];

                /* Count only floors which aren't part of rooms */
                if (cave_isfloor(c, y, x) && !cave_isroom(c, y, x)) k++;
            }

            /* Return the number of corridors */
            return k;
        }
Exemple #13
0
        /**
         * Place the player at a random starting location.
         */
        static void new_player_spot(Cave c, Player.Player p)
        {
            int y, x;

            /* Try to find a good place to put the player */
            cave_find_in_range(c, out y, 0, c.height, out x, 0, c.width, cave_isstart);

            /* Create stairs the player came down if allowed and necessary */
            if (Option.birth_no_stairs.value) {
            } else if (p.create_down_stair) {
                cave_set_feat(c, y, x, FEAT_MORE);
                p.create_down_stair = false;
            } else if (p.create_up_stair) {
                cave_set_feat(c, y, x, FEAT_LESS);
                p.create_up_stair = false;
            }

            Monster_Make.player_place(c, p, y, x);
        }
Exemple #14
0
        ///**
        // * Given an adjoining wall (a wall which separates two labyrinth cells)
        // * set a and b to point to the cell indices which are separated. Used by
        // * labyrinth_gen().
        // */
        //static void lab_get_adjoin(int i, int w, int *a, int *b) {
        //    int y, x;
        //    lab_toyx(i, w, &y, &x);
        //    if (x % 2 == 0) {
        //        *a = lab_toi(y - 1, x, w);
        //        *b = lab_toi(y + 1, x, w);
        //    } else {
        //        *a = lab_toi(y, x - 1, w);
        //        *b = lab_toi(y, x + 1, w);
        //    }
        //}
        ///**
        // * Return whether (x, y) is in a tunnel.
        // *
        // * For our purposes a tunnel is a horizontal or vertical path, not an
        // * intersection. Thus, we want the squares on either side to walls in one
        // * case (e.g. up/down) and open in the other case (e.g. left/right). We don't
        // * want a square that represents an intersection point.
        // *
        // * The high-level idea is that these are squares which can't be avoided (by
        // * walking diagonally around them).
        // */
        //static bool lab_is_tunnel(Cave c, int y, int x) {
        //    bool west = cave_isopen(c, y, x - 1);
        //    bool east = cave_isopen(c, y, x + 1);
        //    bool north = cave_isopen(c, y - 1, x);
        //    bool south = cave_isopen(c, y + 1, x);
        //    return north == south && west == east && north != west;
        //}
        /**
         * Build a labyrinth level.
         *
         * Note that if the function returns false, a level wasn't generated.
         * Labyrinths use the dungeon level's number to determine whether to generate
         * themselves (which means certain level numbers are more likely to generate
         * labyrinths than others).
         */
        static bool labyrinth_gen(Cave c, Player.Player p)
        {
            int i, j, k, y, x;

            /* Size of the actual labyrinth part must be odd. */
            /* NOTE: these are not the actual dungeon size, but rather the size of the
             * area we're genearting a labyrinth in (which doesn't count theh enclosing
             * outer walls. */
            int h = 15 + Random.randint0(c.depth / 10) * 2;
            int w = 51 + Random.randint0(c.depth / 10) * 2;

            /* This is the number of squares in the labyrinth */
            int n = h * w;

            /* NOTE: 'sets' and 'walls' are too large... we only need to use about
             * 1/4 as much memory. However, in that case, the addressing math becomes
             * a lot more complicated, so let's just stick with this because it's
             * easier to read. */

            /* 'sets' tracks connectedness; if sets[i] == sets[j] then cells i and j
             * are connected to each other in the maze. */
            int[] sets;

            /* 'walls' is a list of wall coordinates which we will randomize */
            int[] walls;

            /* Most labyrinths are lit */
            bool lit = Random.randint0(c.depth) < 25 || Random.randint0(2) < 1;

            /* Many labyrinths are known */
            bool known = lit && Random.randint0(c.depth) < 25;

            /* Most labyrinths have soft (diggable) walls */
            bool soft = Random.randint0(c.depth) < 35 || Random.randint0(3) < 2;

            /* There's a base 1 in 100 to accept the labyrinth */
            int chance = 1;

            /* If we're too shallow then don't do it */
            if (c.depth < 13) return false;

            /* Don't try this on quest levels, kids... */
            if (is_quest(c.depth)) return false;

            /* Certain numbers increase the chance of having a labyrinth */
            if (c.depth % 3 == 0) chance += 1;
            if (c.depth % 5 == 0) chance += 1;
            if (c.depth % 7 == 0) chance += 1;
            if (c.depth % 11 == 0) chance += 1;
            if (c.depth % 13 == 0) chance += 1;

            /* Only generate the level if we pass a check */
            /* NOTE: This test gets performed after we pass the test to use the
             * labyrinth cave profile. */
            if (Random.randint0(100) >= chance) return false;

            /* allocate our arrays */
            sets = new int[n];
            walls = new int[n];

            /* This is the dungeon size, which does include the enclosing walls */
            set_cave_dimensions(c, h + 2, w + 2);

            /* Fill whole level with perma-rock */
            fill_rectangle(c, 0, 0, DUNGEON_HGT - 1, DUNGEON_WID - 1, FEAT_PERM_SOLID);

            /* Fill the labyrinth area with rock */
            fill_rectangle(c, 1, 1, h, w, soft ? FEAT_WALL_SOLID : FEAT_PERM_SOLID);

            /* Initialize each wall. */
            for (i = 0; i < n; i++) {
                walls[i] = i;
                sets[i] = -1;
            }

            /* Cut out a grid of 1x1 rooms which we will call "cells" */
            for (y = 0; y < h; y += 2) {
                for (x = 0; x < w; x += 2) {
                    int k2 = lab_toi(y, x, w);
                    sets[k2] = k2;
                    cave_set_feat(c, y + 1, x + 1, FEAT_FLOOR);
                    if (lit) c.info[y + 1][x + 1] |= CAVE_GLOW;
                }
            }

            throw new NotImplementedException();

            ///* Shuffle the walls, using Knuth's shuffle. */
            //shuffle(walls, n);

            ///* For each adjoining wall, look at the cells it divides. If they aren't
            // * in the same set, remove the wall and join their sets.
            // *
            // * This is a randomized version of Kruskal's algorithm. */
            //for (i = 0; i < n; i++) {
            //    int a, b, x, y;

            //    j = walls[i];

            //    /* If this cell isn't an adjoining wall, skip it */
            //    lab_toyx(j, w, &y, &x);
            //    if ((x < 1 && y < 1) || (x > w - 2 && y > h - 2)) continue;
            //    if (x % 2 == y % 2) continue;

            //    /* Figure out which cells are separated by this wall */
            //    lab_get_adjoin(j, w, &a, &b);

            //    /* If the cells aren't connected, kill the wall and join the sets */
            //    if (sets[a] != sets[b]) {
            //        int sa = sets[a];
            //        int sb = sets[b];
            //        cave_set_feat(c, y + 1, x + 1, FEAT_FLOOR);
            //        if (lit) c.info[y + 1][x + 1] |= CAVE_GLOW;

            //        for (k = 0; k < n; k++) {
            //            if (sets[k] == sb) sets[k] = sa;
            //        }
            //    }
            //}

            ///* Determine the character location */
            //new_player_spot(c, p);

            ///* The level should have exactly one down and one up staircase */
            //if (OPT(birth_no_stairs)) {
            //    /* new_player_spot() won't have created stairs, so make both*/
            //    alloc_stairs(c, FEAT_MORE, 1, 3);
            //    alloc_stairs(c, FEAT_LESS, 1, 3);
            //} else if (p.create_down_stair) {
            //    /* new_player_spot() will have created down, so only create up */
            //    alloc_stairs(c, FEAT_LESS, 1, 3);
            //} else {
            //    /* new_player_spot() will have created up, so only create down */
            //    alloc_stairs(c, FEAT_MORE, 1, 3);
            //}

            ///* Generate a door for every 100 squares in the labyrinth */
            //for (i = n / 100; i > 0; i--) {
            //    /* Try 10 times to find a useful place for a door, then place it */
            //    for (j = 0; j < 10; j++) {
            //        find_empty(c, &y, &x);
            //        if (lab_is_tunnel(c, y, x)) break;

            //    }

            //    place_closed_door(c, y, x);
            //}

            ///* General some rubble, traps and monsters */
            //k = MAX(MIN(c.depth / 3, 10), 2);

            ///* Scale number of monsters items by labyrinth size */
            //k = (3 * k * (h * w)) / (DUNGEON_HGT * DUNGEON_WID);

            ///* Put some rubble in corridors */
            //alloc_objects(c, SET_BOTH, TYP_RUBBLE, randint1(k), c.depth, 0);

            ///* Place some traps in the dungeon */
            //alloc_objects(c, SET_BOTH, TYP_TRAP, randint1(k), c.depth, 0);

            ///* Put some monsters in the dungeon */
            //for (i = MIN_M_ALLOC_LEVEL + randint1(8) + k; i > 0; i--)
            //    pick_and_place_distant_monster(c, loc(p.px, p.py), 0, true, c.depth);

            ///* Put some objects/gold in the dungeon */
            //alloc_objects(c, SET_BOTH, TYP_OBJECT, Rand_normal(6, 3), c.depth,
            //    ORIGIN_LABYRINTH);
            //alloc_objects(c, SET_BOTH, TYP_GOLD, Rand_normal(6, 3), c.depth,
            //    ORIGIN_LABYRINTH);
            //alloc_objects(c, SET_BOTH, TYP_GOOD, randint0(2), c.depth,
            //    ORIGIN_LABYRINTH);

            ///* Unlit labyrinths will have some good items */
            //if (!lit)
            //    alloc_objects(c, SET_BOTH, TYP_GOOD, Rand_normal(3, 2), c.depth,
            //        ORIGIN_LABYRINTH);

            ///* Hard (non-diggable) labyrinths will have some great items */
            //if (!soft)
            //    alloc_objects(c, SET_BOTH, TYP_GREAT, Rand_normal(2, 1), c.depth,
            //        ORIGIN_LABYRINTH);

            ///* If we want the players to see the maze layout, do that now */
            //if (known) wiz_light();

            ///* Deallocate our lists */
            //FREE(sets);
            //FREE(walls);

            //return true;
        }
Exemple #15
0
        /**
         * Start connecting regions, stopping when the cave is entirely connected.
         */
        static void join_regions(Cave c, int[] colors, int[] counts)
        {
            int h = c.height;
            int w = c.width;
            int size = h * w;
            int num = count_colors(counts, size);

            while (num > 1) {
                int color = first_color(counts, size);
                join_region(c, colors, counts, color);
                num--;
            }
        }
Exemple #16
0
        /**
         * Locate a square in y1 <= y < y2, x1 <= x < x2 which satisfies the given
         * predicate.
         */
        static void _find_in_range(Cave c, out int y, int y1, int y2, out int x,
								   int x1, int x2, int[] squares, cave_predicate_func pred)
        {
            int yd = y2 - y1;
            int xd = x2 - x1;
            int i, n = yd * xd;
            bool done = false;
            x = 0;
            y = 0;

            /* Test each square in (random) order for openness */
            for (i = 0; i < n && !done; i++) {
                int j = Random.randint0(n - i) + i;
                int k = squares[j];
                squares[j] = squares[i];
                squares[i] = k;

                y = (k / xd) + y1;
                x = (k % xd) + x1;
                if (pred(c, y, x)) done = true;
            }

            /* Deallocate memory, make sure we found an empty square, and return */
            Misc.assert(done);
        }
Exemple #17
0
        ///**
        // * Place a secret door at (x, y).
        // */
        //void place_secret_door(Cave c, int y, int x) {
        //    cave_set_feat(c, y, x, FEAT_SECRET);
        //}
        /**
         * Place a closed door at (x, y).
         */
        public static void place_closed_door(Cave c, int y, int x)
        {
            int tmp = Random.randint0(400);

            if (tmp < 300)
                cave_set_feat(c, y, x, FEAT_DOOR_HEAD + 0x00);
            else if (tmp < 399)
                cave_set_feat(c, y, x, FEAT_DOOR_HEAD + Random.randint1(7));
            else
                cave_set_feat(c, y, x, FEAT_DOOR_HEAD + 0x08 + Random.randint0(8));
        }
Exemple #18
0
 /**
  * Place stairs (of the requested type 'feat' if allowed) at (x, y).
  *
  * All stairs from town go down. All stairs on an unfinished quest level go up.
  */
 static void place_stairs(Cave c, int y, int x, int feat)
 {
     if (c.depth == 0)
         cave_set_feat(c, y, x, FEAT_MORE);
     else if (is_quest(c.depth) || c.depth >= Misc.MAX_DEPTH - 1)
         cave_set_feat(c, y, x, FEAT_LESS);
     else
         cave_set_feat(c, y, x, feat);
 }
Exemple #19
0
        ///**
        // * Place random stairs at (x, y).
        // */
        //static void place_random_stairs(Cave c, int y, int x) {
        //    int feat = randint0(100) < 50 ? FEAT_LESS : FEAT_MORE;
        //    if (cave_canputitem(c, y, x))
        //        place_stairs(c, y, x, feat);
        //}
        /**
         * Place a random object at (x, y).
         */
        public static void place_object(Cave c, int y, int x, int level, bool good, bool great, Origin origin)
        {
            int rating = 0;
            Object.Object otype;

            Misc.assert(cave_in_bounds(c, y, x));

            if (!cave_canputitem(c, y, x)) return;

            otype = new Object.Object();
            //object_wipe(&otype);
            if (!Object.Object.make_object(c, ref otype, level, good, great, ref rating)) return;

            otype.origin = origin;
            otype.origin_depth = (byte)c.depth;

            /* Give it to the floor */
            /* XXX Should this be done in floor_carry? */
            if (Object.Object.floor_carry(c, y, x, otype) == 0) {
                if (otype.artifact != null)
                    otype.artifact.created = false;
                return;
            } else {
                if (otype.artifact != null)
                    c.good_item = true;
                c.obj_rating += (uint)rating;
            }
        }
Exemple #20
0
        /**
         * Returns whether a doorway can be built in a space.
         *
         * To have a doorway, a space must be adjacent to at least two corridors and be
         * between two walls.
         */
        static bool possible_doorway(Cave c, int y, int x)
        {
            Misc.assert(cave_in_bounds(c, y, x));

            if (next_to_corr(c, y, x) < 2)
                return false;

            if (cave_isstrongwall(c, y - 1, x) && cave_isstrongwall(c, y + 1, x))
                return true;

            if (cave_isstrongwall(c, y, x - 1) && cave_isstrongwall(c, y, x + 1))
                return true;

            return false;
        }
Exemple #21
0
        /**
         * Allocates a single random object in the dungeon.
         *
         * 'set' controls where the object is placed (corridor, room, either).
         * 'typ' conrols the kind of object (rubble, trap, gold, item).
         */
        static bool alloc_object(Cave c, int set, int typ, int depth, Origin origin)
        {
            int x = 0, y = 0;
            int tries = 0;
            bool room;

            /* Pick a "legal" spot */
            while (tries < 2000) {
                tries++;

                find_empty(c, out y, out x);

                /* See if our spot is in a room or not */
                room = (c.info[y][x] & CAVE_ROOM) != 0 ? true : false;

                /* If we are ok with a corridor and we're in one, we're done */
                if ((set & SET_CORR) != 0 && !room) break;

                /* If we are ok with a room and we're in one, we're done */
                if ((set & SET_ROOM) != 0 && room) break;
            }

            if (tries == 2000) return false;

            /* Place something */
            switch (typ) {
                case TYP_RUBBLE: place_rubble(c, y, x); break;
                case TYP_TRAP: Trap.place_trap(c, y, x); break;
                case TYP_GOLD: place_gold(c, y, x, depth, origin); break;
                case TYP_OBJECT: place_object(c, y, x, depth, false, false, origin); break;
                case TYP_GOOD: place_object(c, y, x, depth, true, false, origin); break;
                case TYP_GREAT: place_object(c, y, x, depth, true, true, origin); break;
            }
            return true;
        }
Exemple #22
0
        /**
         * Attempt to build a room of the given type at the given block
         *
         * Note that we restrict the number of "crowded" rooms to reduce
         * the chance of overflowing the monster list during level creation.
         */
        static bool room_build(Cave c, int by0, int bx0, room_profile profile)
        {
            /* Extract blocks */
            int by1 = by0;
            int bx1 = bx0;
            int by2 = by0 + profile.height;
            int bx2 = bx0 + profile.width;

            int allocated;
            int y, x;
            int by, bx;

            /* Enforce the room profile's minimum depth */
            if (c.depth < profile.level) return false;

            /* Only allow one crowded room per level */
            if (dun.crowded && profile.crowded) return false;

            /* Never run off the screen */
            if (by1 < 0 || by2 >= dun.row_rooms) return false;
            if (bx1 < 0 || bx2 >= dun.col_rooms) return false;

            /* Verify open space */
            for (by = by1; by <= by2; by++) {
                for (bx = bx1; bx <= bx2; bx++) {
                    if (true) {
                        /* previous rooms prevent new ones */
                        if (dun.room_map[by, bx]) return false;
                    } else {
                        return false; /* XYZ */
                    }
                }
            }

            /* Get the location of the room */
            y = ((by1 + by2 + 1) * BLOCK_HGT) / 2;
            x = ((bx1 + bx2 + 1) * BLOCK_WID) / 2;

            /* Try to build a room */
            if (!profile.builder(c, y, x)) return false;

            /* Save the room location */
            if (dun.cent_n < CENT_MAX) {
                dun.cent[dun.cent_n] = new Loc();
                dun.cent[dun.cent_n].y = y;
                dun.cent[dun.cent_n].x = x;
                dun.cent_n++;
            }

            /* Reserve some blocks */
            allocated = 0;
            for (by = by1; by < by2; by++) {
                for (bx = bx1; bx < bx2; bx++) {
                    dun.room_map[by, bx] = true;
                    allocated++;
                }
            }

            /* Count "crowded" rooms */
            if (profile.crowded) dun.crowded = true;

            /* Success */
            return true;
        }
Exemple #23
0
        ///**
        // * Chooses a vault of a particular kind at random.
        // *
        // * Each vault has equal probability of being chosen. One weird thing is that
        // * currently the v.typ indices are one off from the room type indices, which
        // * means that build_greater_vault will call this function with "typ=8".
        // *
        // * TODO: Fix the weird type-off-by-one issue.
        // */
        //struct vault *random_vault(int typ) {
        //    struct vault *v = vaults;
        //    struct vault *r = null;
        //    int n = 1;
        //    do {
        //        if (v.typ == typ) {
        //            if (one_in_(n)) r = v;
        //            n++;
        //        }
        //        v = v.next;
        //    } while(v);
        //    return r;
        //}
        /**
         * Place some staircases near walls.
         */
        static void alloc_stairs(Cave c, int feat, int num, int walls)
        {
            int y, x, i, j;
            bool done;

            /* Place "num" stairs */
            for (i = 0; i < num; i++) {
                /* Place some stairs */
                for (done = false; !done; ) {
                    /* Try several times, then decrease "walls" */
                    for (j = 0; !done && j <= 1000; j++) {
                        find_empty(c, out y, out x);

                        if (next_to_walls(c, y, x) < walls) continue;

                        place_stairs(c, y, x, feat);
                        done = true;
                    }

                    /* Require fewer walls */
                    if (walls != 0) walls--;
                }
            }
        }
Exemple #24
0
 static void set_cave_dimensions(Cave c, int h, int w)
 {
     int i, n = h * w;
     c.height = h;
     c.width  = w;
     if(cave_squares != null)
         cave_squares = null;
     cave_squares = new int[n];
     for (i = 0; i < n; i++) cave_squares[i] = i;
 }
Exemple #25
0
        /**
         * Create a color for each "NESW contiguous" region of the dungeon.
         */
        static void build_colors(Cave c, int[] colors, int[] counts, bool diagonal)
        {
            int y, x;
            int h = c.height;
            int w = c.width;
            int color = 1;

            for (y = 0; y < h; y++) {
                for (x = 0; x < w; x++) {
                    if (ignore_point(cave, colors, y, x)) continue;
                    build_color_point(cave, colors, counts, y, x, color, diagonal);
                    color++;
                }
            }
        }
Exemple #26
0
        /**
         * Town logic flow for generation of new town.
         *
         * We start with a fully wiped cave of normal floors. This function does NOT do
         * anything about the owners of the stores, nor the contents thereof. It only
         * handles the physical layout.
         */
        static bool town_gen(Cave c, Player.Player p)
        {
            int i;
            bool daytime = Misc.turn % (10 * TOWN_DAWN) < (10 * TOWN_DUSK);
            int residents = daytime ? MIN_M_ALLOC_TD : MIN_M_ALLOC_TN;

            Misc.assert(c != null);

            set_cave_dimensions(c, TOWN_HGT, TOWN_WID);

            /* NOTE: We can't use c.height and c.width here because then there'll be
             * a bunch of empty space in the level that monsters might spawn in (or
             * teleport might take you to, or whatever).
             *
             * TODO: fix this to use c.height and c.width when all the 'choose
             * random location' things honor them.
             */

            /* Start with solid walls, and then create some floor in the middle */
            fill_rectangle(c, 0, 0, DUNGEON_HGT - 1, DUNGEON_WID - 1, FEAT_PERM_SOLID);
            fill_rectangle(c, 1, 1, c.height -2, c.width - 2, FEAT_FLOOR);

            /* Build stuff */
            town_gen_hack(c, p);

            /* Apply illumination */
            cave_illuminate(c, daytime);

            /* Make some residents */
            for (i = 0; i < residents; i++)
                Monster_Make.pick_and_place_distant_monster(c, new Loc(p.px, p.py), 3, true, c.depth);

            return true;
        }
Exemple #27
0
        /**
         * Builds a cross-shaped room.
         *
         * Room "a" runs north/south, and Room "b" runs east/east
         * So a "central pillar" would run from x1a,y1b to x2a,y2b.
         *
         * Note that currently, the "center" is always 3x3, but I think that the code
         * below will work for 5x5 (and perhaps even for unsymetric values like 4x3 or
         * 5x3 or 3x4 or 3x5).
         */
        static bool build_crossed(Cave c, int y0, int x0)
        {
            throw new NotImplementedException();
            //int y, x;

            //int y1a, x1a, y2a, x2a;
            //int y1b, x1b, y2b, x2b;

            //int dy, dx, wy, wx;

            //int light = false;

            ///* Occasional light */
            //if (c.depth <= randint1(25)) light = true;

            ///* Pick inner dimension */
            //wy = 1;
            //wx = 1;

            ///* Pick outer dimension */
            //dy = rand_range(3, 4);
            //dx = rand_range(3, 11);

            ///* Determine extents of room (a) */
            //y1a = y0 - dy;
            //x1a = x0 - wx;
            //y2a = y0 + dy;
            //x2a = x0 + wx;

            ///* Determine extents of room (b) */
            //y1b = y0 - wy;
            //x1b = x0 - dx;
            //y2b = y0 + wy;
            //x2b = x0 + dx;

            ///* Generate new room (a) */
            //generate_room(c, y1a-1, x1a-1, y2a+1, x2a+1, light);

            ///* Generate new room (b) */
            //generate_room(c, y1b-1, x1b-1, y2b+1, x2b+1, light);

            ///* Generate outer walls (a) */
            //draw_rectangle(c, y1a-1, x1a-1, y2a+1, x2a+1, FEAT_WALL_OUTER);

            ///* Generate outer walls (b) */
            //draw_rectangle(c, y1b-1, x1b-1, y2b+1, x2b+1, FEAT_WALL_OUTER);

            ///* Generate inner floors (a) */
            //fill_rectangle(c, y1a, x1a, y2a, x2a, FEAT_FLOOR);

            ///* Generate inner floors (b) */
            //fill_rectangle(c, y1b, x1b, y2b, x2b, FEAT_FLOOR);

            ///* Special features */
            //switch (randint1(4)) {
            //    /* Nothing */
            //    case 1: break;

            //    /* Large solid middle pillar */
            //    case 2: {
            //        fill_rectangle(c, y1b, x1a, y2b, x2a, FEAT_WALL_INNER);
            //        break;
            //    }

            //    /* Inner treasure vault */
            //    case 3: {
            //        /* Generate a small inner vault */
            //        draw_rectangle(c, y1b, x1a, y2b, x2a, FEAT_WALL_INNER);

            //        /* Open the inner vault with a secret door */
            //        generate_hole(c, y1b, x1a, y2b, x2a, FEAT_SECRET);

            //        /* Place a treasure in the vault */
            //        place_object(c, y0, x0, c.depth, false, false, ORIGIN_SPECIAL);

            //        /* Let's guard the treasure well */
            //        vault_monsters(c, y0, x0, c.depth + 2, randint0(2) + 3);

            //        /* Traps naturally */
            //        vault_traps(c, y0, x0, 4, 4, randint0(3) + 2);

            //        break;
            //    }

            //    /* Something else */
            //    case 4: {
            //        if (one_in_(3)) {
            //            /* Occasionally pinch the center shut */

            //            /* Pinch the east/west sides */
            //            for (y = y1b; y <= y2b; y++) {
            //                if (y == y0) continue;
            //                cave_set_feat(c, y, x1a - 1, FEAT_WALL_INNER);
            //                cave_set_feat(c, y, x2a + 1, FEAT_WALL_INNER);
            //            }

            //            /* Pinch the north/south sides */
            //            for (x = x1a; x <= x2a; x++) {
            //                if (x == x0) continue;
            //                cave_set_feat(c, y1b - 1, x, FEAT_WALL_INNER);
            //                cave_set_feat(c, y2b + 1, x, FEAT_WALL_INNER);
            //            }

            //            /* Open sides with secret doors */
            //            if (one_in_(3))
            //                generate_open(c, y1b-1, x1a-1, y2b+1, x2a+1, FEAT_SECRET);

            //        } else if (one_in_(3)) {
            //            /* Occasionally put a "plus" in the center */
            //            generate_plus(c, y1b, x1a, y2b, x2a, FEAT_WALL_INNER);

            //        } else if (one_in_(3)) {
            //            /* Occasionally put a "pillar" in the center */
            //            cave_set_feat(c, y0, x0, FEAT_WALL_INNER);
            //        }

            //        break;
            //    }
            //}

            //return true;
        }
Exemple #28
0
        /**
         * Generate the "consistent" town features, and place the player
         *
         * HACK: We seed the simple RNG, so we always get the same town layout,
         * including the size and shape of the buildings, the locations of the
         * doorways, and the location of the stairs. This means that if any of the
         * functions used to build the town change the way they use the RNG, the
         * town layout will be generated differently.
         *
         * XXX: Remove this gross hack when this piece of code is fully reentrant -
         * i.e., when all we need to do is swing a pointer to change caves, we just
         * need to generate the town once (we will also need to save/load the town).
         */
        static void town_gen_hack(Cave c, Player.Player p)
        {
            int y, x, n, k;
            int[] rooms = new int[(int)STORE.MAX_STORES];

            int n_rows = 2;
            int n_cols = ((int)STORE.MAX_STORES + 1) / n_rows;

            /* Switch to the "simple" RNG and use our original town seed */
            Random.Rand_quick = true;
            Random.Rand_value = (uint)Misc.seed_town;

            /* Prepare an Array of "remaining stores", and count them */
            for (n = 0; n < (int)STORE.MAX_STORES; n++) rooms[n] = n;

            /* Place rows of stores */
            for (y = 0; y < n_rows; y++) {
                for (x = 0; x < n_cols; x++) {
                    if (n < 1) break;

                    /* Pick a remaining store */
                    k = Random.randint0(n);

                    /* Build that store at the proper location */
                    build_store(c, rooms[k], y, x);

                    /* Shift the stores down, remove one store */
                    rooms[k] = rooms[--n];
                }
            }

            /* Place the stairs */
            find_empty_range(c, out y, 3, TOWN_HGT - 3, out x, 3, TOWN_WID - 3);

            /* Clear previous contents, add down stairs */
            cave_set_feat(c, y, x, FEAT_MORE);

            /* Place the player */
            Monster_Make.player_place(c, p, y, x);

            /* go back to using the "complex" RNG */
            Random.Rand_quick = false;
        }
Exemple #29
0
        /**
         * Build a large room with an inner room.
         *
         * Possible sub-types:
         *	1 - An inner room
         *	2 - An inner room with a small inner room
         *	3 - An inner room with a pillar or pillars
         *	4 - An inner room with a checkerboard
         *	5 - An inner room with four compartments
         */
        static bool build_large(Cave c, int y0, int x0)
        {
            throw new NotImplementedException();
            //int y, x, y1, x1, y2, x2;

            //int light = false;

            ///* Occasional light */
            //if (c.depth <= randint1(25)) light = true;

            ///* Large room */
            //y1 = y0 - 4;
            //y2 = y0 + 4;
            //x1 = x0 - 11;
            //x2 = x0 + 11;

            ///* Generate new room */
            //generate_room(c, y1-1, x1-1, y2+1, x2+1, light);

            ///* Generate outer walls */
            //draw_rectangle(c, y1-1, x1-1, y2+1, x2+1, FEAT_WALL_OUTER);

            ///* Generate inner floors */
            //fill_rectangle(c, y1, x1, y2, x2, FEAT_FLOOR);

            ///* The inner room */
            //y1 = y1 + 2;
            //y2 = y2 - 2;
            //x1 = x1 + 2;
            //x2 = x2 - 2;

            ///* Generate inner walls */
            //draw_rectangle(c, y1-1, x1-1, y2+1, x2+1, FEAT_WALL_INNER);

            ///* Inner room variations */
            //switch (randint1(5)) {
            //    /* An inner room */
            //    case 1: {
            //        /* Open the inner room with a secret door and place a monster */
            //        generate_hole(c, y1-1, x1-1, y2+1, x2+1, FEAT_SECRET);
            //        vault_monsters(c, y0, x0, c.depth + 2, 1);
            //        break;
            //    }

            //    /* An inner room with a small inner room */
            //    case 2: {
            //        /* Open the inner room with a secret door */
            //        generate_hole(c, y1-1, x1-1, y2+1, x2+1, FEAT_SECRET);

            //        /* Place another inner room */
            //        draw_rectangle(c, y0-1, x0-1, y0+1, x0+1, FEAT_WALL_INNER);

            //        /* Open the inner room with a locked door */
            //        generate_hole(c, y0-1, x0-1, y0+1, x0+1, FEAT_DOOR_HEAD + randint1(7));

            //        /* Monsters to guard the treasure */
            //        vault_monsters(c, y0, x0, c.depth + 2, randint1(3) + 2);

            //        /* Object (80%) or Stairs (20%) */
            //        if (randint0(100) < 80)
            //            place_object(c, y0, x0, c.depth, false, false, ORIGIN_SPECIAL);
            //        else
            //            place_random_stairs(c, y0, x0);

            //        /* Traps to protect the treasure */
            //        vault_traps(c, y0, x0, 4, 10, 2 + randint1(3));

            //        break;
            //    }

            //    /* An inner room with an inner pillar or pillars */
            //    case 3: {
            //        /* Open the inner room with a secret door */
            //        generate_hole(c, y1-1, x1-1, y2+1, x2+1, FEAT_SECRET);

            //        /* Inner pillar */
            //        fill_rectangle(c, y0-1, x0-1, y0+1, x0+1, FEAT_WALL_INNER);

            //        /* Occasionally, two more Large Inner Pillars */
            //        if (one_in_(2)) {
            //            if (one_in_(2)) {
            //                fill_rectangle(c, y0-1, x0-7, y0+1, x0-5, FEAT_WALL_INNER);
            //                fill_rectangle(c, y0-1, x0+5, y0+1, x0+7, FEAT_WALL_INNER);
            //            } else {
            //                fill_rectangle(c, y0-1, x0-6, y0+1, x0-4, FEAT_WALL_INNER);
            //                fill_rectangle(c, y0-1, x0+4, y0+1, x0+6, FEAT_WALL_INNER);
            //            }
            //        }

            //        /* Occasionally, some Inner rooms */
            //        if (one_in_(3)) {
            //            /* Inner rectangle */
            //            draw_rectangle(c, y0-1, x0-5, y0+1, x0+5, FEAT_WALL_INNER);

            //            /* Secret doors (random top/bottom) */
            //            place_secret_door(c, y0 - 3 + (randint1(2) * 2), x0 - 3);
            //            place_secret_door(c, y0 - 3 + (randint1(2) * 2), x0 + 3);

            //            /* Monsters */
            //            vault_monsters(c, y0, x0 - 2, c.depth + 2, randint1(2));
            //            vault_monsters(c, y0, x0 + 2, c.depth + 2, randint1(2));

            //            /* Objects */
            //            if (one_in_(3))
            //                place_object(c, y0, x0 - 2, c.depth, false, false,
            //                    ORIGIN_SPECIAL);
            //            if (one_in_(3))
            //                place_object(c, y0, x0 + 2, c.depth, false, false,
            //                    ORIGIN_SPECIAL);
            //        }

            //        break;
            //    }

            //    /* An inner room with a checkerboard */
            //    case 4: {
            //        /* Open the inner room with a secret door */
            //        generate_hole(c, y1-1, x1-1, y2+1, x2+1, FEAT_SECRET);

            //        /* Checkerboard */
            //        for (y = y1; y <= y2; y++)
            //            for (x = x1; x <= x2; x++)
            //                if ((x + y) & 0x01)
            //                    cave_set_feat(c, y, x, FEAT_WALL_INNER);

            //        /* Monsters just love mazes. */
            //        vault_monsters(c, y0, x0 - 5, c.depth + 2, randint1(3));
            //        vault_monsters(c, y0, x0 + 5, c.depth + 2, randint1(3));

            //        /* Traps make them entertaining. */
            //        vault_traps(c, y0, x0 - 3, 2, 8, randint1(3));
            //        vault_traps(c, y0, x0 + 3, 2, 8, randint1(3));

            //        /* Mazes should have some treasure too. */
            //        vault_objects(c, y0, x0, c.depth, 3);

            //        break;
            //    }

            //    /* Four small rooms. */
            //    case 5: {
            //        /* Inner "cross" */
            //        generate_plus(c, y1, x1, y2, x2, FEAT_WALL_INNER);

            //        /* Doors into the rooms */
            //        if (randint0(100) < 50) {
            //            int i = randint1(10);
            //            place_secret_door(c, y1 - 1, x0 - i);
            //            place_secret_door(c, y1 - 1, x0 + i);
            //            place_secret_door(c, y2 + 1, x0 - i);
            //            place_secret_door(c, y2 + 1, x0 + i);
            //        } else {
            //            int i = randint1(3);
            //            place_secret_door(c, y0 + i, x1 - 1);
            //            place_secret_door(c, y0 - i, x1 - 1);
            //            place_secret_door(c, y0 + i, x2 + 1);
            //            place_secret_door(c, y0 - i, x2 + 1);
            //        }

            //        /* Treasure, centered at the center of the cross */
            //        vault_objects(c, y0, x0, c.depth, 2 + randint1(2));

            //        /* Gotta have some monsters */
            //        vault_monsters(c, y0 + 1, x0 - 4, c.depth + 2, randint1(4));
            //        vault_monsters(c, y0 + 1, x0 + 4, c.depth + 2, randint1(4));
            //        vault_monsters(c, y0 - 1, x0 - 4, c.depth + 2, randint1(4));
            //        vault_monsters(c, y0 - 1, x0 + 4, c.depth + 2, randint1(4));

            //        break;
            //    }
            //}

            //return true;
        }
Exemple #30
0
        /**
         * Places door at y, x position if at least 2 walls found
         */
        static void try_door(Cave c, int y, int x)
        {
            Misc.assert(cave_in_bounds(c, y, x));

            if (cave_isstrongwall(c, y, x)) return;
            if (cave_isroom(c, y, x)) return;

            if (Random.randint0(100) < dun.profile.tun.jct && possible_doorway(c, y, x))
                place_random_door(c, y, x);
        }