コード例 #1
0
def _build_map(new_map):
    new_map.rng = libtcod.random_new_from_seed(new_map.random_seed)

    new_map.spare_terrain = copy.deepcopy(
        new_map.terrain
    )  # [[0 for y in range(new_map.height)] for x in range(new_map.width)]
    dig_ca_region(new_map, algebra.Rect(0, 0, new_map.width, new_map.height),
                  4, 3)

    center = algebra.Location(new_map.width / 2, new_map.height / 2)
    stair_loc = _probe_for_stair(new_map, range(new_map.width - 2, center.x,
                                                -1), center.y)
    if not stair_loc:
        # Uh-oh; no guarantee of completion
        print('Recursing with unenterable map:')
        # _dump(new_map)
        new_map.random_seed = libtcod.random_save(new_map.rng)
        return _build_map(new_map)

    pool_x = new_map.width / 4
    for x in range(pool_x - 6, pool_x + 7):
        for y in range(center.y - 6, center.y + 7):
            dx = x - pool_x
            dy = y - center.y
            if math.sqrt(dx**2 + dy**2) > 6:
                continue
            if new_map.terrain[x][y] == map.TERRAIN_WALL:
                new_map.terrain[x][y] = map.TERRAIN_GROUND

    new_map.pool_x = pool_x
    _scatter_ponds(new_map)

    # Can we reach from the stairs to the center of the pool?
    _floodfill(new_map, stair_loc.x, stair_loc.y, map.TERRAIN_GROUND,
               map.TERRAIN_FLOOR)
    if new_map.terrain[pool_x][center.y] != map.TERRAIN_FLOOR:
        # Uh-oh; no guarantee of completion
        print('Recursing with disconnected map:')
        # _dump(new_map)
        new_map.random_seed = libtcod.random_save(new_map.rng)
        return _build_map(new_map)

    # Close up any unconnected subcaves; flood any western bits
    for x in range(1, new_map.width - 1):
        for y in range(1, new_map.height - 1):
            if new_map.terrain[x][y] == map.TERRAIN_GROUND:
                new_map.terrain[x][y] = map.TERRAIN_WALL
            elif x < pool_x and new_map.terrain[x][y] == map.TERRAIN_FLOOR:
                new_map.terrain[x][y] = map.TERRAIN_WATER

    #for x in range(0, new_map.width):
    #    new_map.terrain[x][0] = map.TERRAIN_WALL
    #    new_map.terrain[x][new_map.height-1] = map.TERRAIN_WALL
    #for y in range(0, new_map.height):
    #    new_map.terrain[0][y] = map.TERRAIN_WALL
    #    new_map.terrain[new_map.width-1][y] = map.TERRAIN_WALL

    return stair_loc
コード例 #2
0
def _build_map(new_map):
    new_map.rng = libtcod.random_new_from_seed(new_map.random_seed)

    new_map.spare_terrain = copy.deepcopy(new_map.terrain) # [[0 for y in range(new_map.height)] for x in range(new_map.width)]
    dig_ca_region(new_map, algebra.Rect(0, 0, new_map.width, new_map.height), 4, 3)

    center = algebra.Location(new_map.width / 2, new_map.height / 2)
    stair_loc = _probe_for_stair(new_map,
                                 range(new_map.width - 2, center.x, -1),
                                 center.y)
    if not stair_loc:
        # Uh-oh; no guarantee of completion
        print('Recursing with unenterable map:')
        # _dump(new_map)
        new_map.random_seed = libtcod.random_save(new_map.rng)
        return _build_map(new_map)

    pool_x = new_map.width / 4
    for x in range(pool_x - 6, pool_x + 7):
        for y in range(center.y - 6, center.y + 7):
            dx = x - pool_x
            dy = y - center.y
            if math.sqrt(dx ** 2 + dy ** 2) > 6:
                continue
            if new_map.terrain[x][y] == map.TERRAIN_WALL:
                new_map.terrain[x][y] = map.TERRAIN_GROUND

    new_map.pool_x = pool_x
    _scatter_ponds(new_map)

    # Can we reach from the stairs to the center of the pool?
    _floodfill(new_map, stair_loc.x, stair_loc.y, map.TERRAIN_GROUND, map.TERRAIN_FLOOR)
    if new_map.terrain[pool_x][center.y] != map.TERRAIN_FLOOR:
         # Uh-oh; no guarantee of completion
        print('Recursing with disconnected map:')
        # _dump(new_map)
        new_map.random_seed = libtcod.random_save(new_map.rng)
        return _build_map(new_map)

    # Close up any unconnected subcaves; flood any western bits
    for x in range(1, new_map.width-1):
        for y in range(1, new_map.height-1):
            if new_map.terrain[x][y] == map.TERRAIN_GROUND:
                new_map.terrain[x][y] = map.TERRAIN_WALL
            elif x < pool_x and new_map.terrain[x][y] == map.TERRAIN_FLOOR:
                new_map.terrain[x][y] = map.TERRAIN_WATER

    #for x in range(0, new_map.width):
    #    new_map.terrain[x][0] = map.TERRAIN_WALL
    #    new_map.terrain[x][new_map.height-1] = map.TERRAIN_WALL
    #for y in range(0, new_map.height):
    #    new_map.terrain[0][y] = map.TERRAIN_WALL
    #    new_map.terrain[new_map.width-1][y] = map.TERRAIN_WALL

    return stair_loc
コード例 #3
0
def _test_map_repeatability():
    """
    Require that two calls to _build_map() with the same seed produce the
    same corridors and rooms.
    """
    map1 = map.DungeonMap(config.MAP_WIDTH, config.MAP_HEIGHT, 3)
    map1.random_seed = libtcod.random_save(0)
    _build_map(map1)

    map2 = map.DungeonMap(config.MAP_WIDTH, config.MAP_HEIGHT, 3)
    map2.random_seed = map1.random_seed
    _build_map(map2)

    assert map1.terrain == map2.terrain
コード例 #4
0
def _test_map_repeatability():
    """
    Require that two calls to _build_map() with the same seed produce the
    same corridors and rooms.
    """
    map1 = map.DungeonMap(config.MAP_WIDTH, config.MAP_HEIGHT, 3)
    map1.random_seed = libtcod.random_save(0)
    _build_map(map1)

    map2 = map.DungeonMap(config.MAP_WIDTH, config.MAP_HEIGHT, 3)
    map2.random_seed = map1.random_seed
    _build_map(map2)

    assert map1.terrain == map2.terrain
コード例 #5
0
def make_map(player, dungeon_level):
    """
    Creates a new simple map at the given dungeon level.
    Sets player.current_map to the new map, and adds the player as the first
    object.
    """
    new_map = map.Map(config.MAP_HEIGHT, config.MAP_WIDTH, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    _build_map(new_map)
    for new_room in new_map.rooms:
        _place_objects(new_map, new_room, player)
    player.pos = new_map.rooms[0].center()

    new_map.initialize_fov()
    return new_map
コード例 #6
0
def make_map(player, dungeon_level):
    """
    Creates a new simple map at the given dungeon level.
    Sets player.current_map to the new map, and adds the player as the first
    object.
    """
    new_map = map.Map(config.MAP_HEIGHT, config.MAP_WIDTH, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    _build_map(new_map)
    for new_room in new_map.rooms:
        _place_objects(new_map, new_room, player)
    player.pos = new_map.rooms[0].center()

    new_map.initialize_fov()
    return new_map
コード例 #7
0
def test_random():
    rand = libtcodpy.random_get_instance()
    rand = libtcodpy.random_new()
    libtcodpy.random_delete(rand)
    rand = libtcodpy.random_new_from_seed(42)
    libtcodpy.random_set_distribution(rand, libtcodpy.DISTRIBUTION_LINEAR)
    libtcodpy.random_get_int(rand, 0, 1)
    libtcodpy.random_get_int_mean(rand, 0, 1, 0)
    libtcodpy.random_get_float(rand, 0, 1)
    libtcodpy.random_get_double(rand, 0, 1)
    libtcodpy.random_get_float_mean(rand, 0, 1, 0)
    libtcodpy.random_get_double_mean(rand, 0, 1, 0)

    backup = libtcodpy.random_save(rand)
    libtcodpy.random_restore(rand, backup)

    libtcodpy.random_delete(rand)
    libtcodpy.random_delete(backup)
コード例 #8
0
def make_map(player, dungeon_level):
    """
    Creates a new simple map at the given dungeon level.
    Sets player.current_map to the new map, and adds the player as the first
    object.
    """
    new_map = map.DungeonMap(config.MAP_WIDTH, config.MAP_HEIGHT, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    player.pos = _build_map(new_map)

    _inhabit_pool(new_map)
    _place_random_creatures(new_map, player)

    new_map.initialize_fov()
    return True
コード例 #9
0
def make_map(player, dungeon_level):
    """
    Creates a new simple map at the given dungeon level.
    Sets player.current_map to the new map, and adds the player as the first
    object.
    """
    new_map = map.DungeonMap(config.MAP_WIDTH, config.MAP_HEIGHT,
                             dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    player.pos = _build_map(new_map)

    _inhabit_pool(new_map)
    _place_random_creatures(new_map, player)

    new_map.initialize_fov()
    return True
コード例 #10
0
def make_map(player, dungeon_level):
    """
    Creates a new simple map at the given dungeon level.
    Sets player.current_map to the new map, and adds the player as the first
    object.
    """
    new_map = map.OutdoorMap(config.OUTDOOR_MAP_WIDTH,
                             config.OUTDOOR_MAP_HEIGHT, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    _build_map(new_map)

    # Might want to change this later, but this is required in creature placement
    # routines so we know what region the player starts in so there isn't a
    # wandering monster jumping down their throat. Unless, of course, this
    # start point is on a *region border* and there's a monster in the next
    # region over...
    player.pos = algebra.Location(config.OUTDOOR_MAP_WIDTH - 8, 12)

    _place_random_creatures(new_map, player)
    _inhabit_rotunda(new_map, new_map.peak)
    if new_map.caravanserai:
        compound_cartographer.inhabit_caravanserai(new_map, player)
    if new_map.quarry_regions:
        _inhabit_quarry(new_map, player)

    # make sure we're not starting on top of an object or terrain feature
    while (new_map.terrain_at(player.pos).name != 'ground'):
        # subtle bug? doesn't use the map-building random number generator
        player.pos = player.pos + actions.random_direction()
        player.pos.bound(
            algebra.Rect(0, 0, new_map.width - 1, new_map.height - 1))

    new_map.initialize_fov()
    # setting an instancemethod breaks shelve save games
    # new_map.xp_visit = type(map.BaseMap.xp_visit)(_mountain_exploration, new_map, map.BaseMap)
    new_map.xp_visit = _mountain_exploration
    return True
コード例 #11
0
def make_map(player, dungeon_level):
    """
    Creates a new simple map at the given dungeon level.
    Sets player.current_map to the new map, and adds the player as the first
    object.
    """
    new_map = map.OutdoorMap(config.OUTDOOR_MAP_WIDTH, config.OUTDOOR_MAP_HEIGHT, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    _build_map(new_map)

    # Might want to change this later, but this is required in creature placement
    # routines so we know what region the player starts in so there isn't a
    # wandering monster jumping down their throat. Unless, of course, this
    # start point is on a *region border* and there's a monster in the next
    # region over...
    player.pos = algebra.Location(config.OUTDOOR_MAP_WIDTH - 8, 12)

    _place_random_creatures(new_map, player)
    _inhabit_rotunda(new_map, new_map.peak)
    if new_map.caravanserai:
        compound_cartographer.inhabit_caravanserai(new_map, player)
    if new_map.quarry_regions:
        _inhabit_quarry(new_map, player)

    # make sure we're not starting on top of an object or terrain feature
    while (new_map.terrain_at(player.pos).name != 'ground'):
        # subtle bug? doesn't use the map-building random number generator
        player.pos = player.pos + actions.random_direction()
        player.pos.bound(algebra.Rect(0, 0, new_map.width - 1, new_map.height - 1))

    new_map.initialize_fov()
    # setting an instancemethod breaks shelve save games
    # new_map.xp_visit = type(map.BaseMap.xp_visit)(_mountain_exploration, new_map, map.BaseMap)
    new_map.xp_visit = _mountain_exploration
    return True
コード例 #12
0
def make_map(player, dungeon_level):
    """
    """
    old_map = player.current_map

    new_map = map.DungeonMap(MINE_SIZE, MINE_SIZE, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    new_map.rng = libtcod.random_new_from_seed(new_map.random_seed)

    old_quarry_stairs = old_map.quarry_stairs
    _link_up_stairs(new_map, old_map, old_quarry_stairs)
    _create_entries(new_map, old_quarry_stairs)
    _descend_stairs(new_map, player, old_quarry_stairs)
    _dig_some_caves(new_map, old_quarry_stairs)
    _dig_mine_tunnels(new_map)

    map_bounds = algebra.Rect(1, 1, new_map.width - 1, new_map.height - 1)
    for x in range(1, new_map.width - 1):
        for y in range(1, new_map.height - 1):
            if libtcod.random_get_float(new_map.rng, 0., 1.) < 0.2:
                new_map.terrain[x][y] = map.TERRAIN_GROUND

    ca_cartographer._generation(new_map, map_bounds, 7, 1)
    ca_cartographer._generation(new_map, map_bounds, 5, 1)

    # Redig the initial rooms because the CA can fill in the stairs
    for i in range(3):
        _create_room(new_map, new_map.rooms[i])

    for i in range(3):
        stair_pos = old_quarry_stairs[i].dest_position
        ca_cartographer._floodfill(new_map, stair_pos.x, stair_pos.y,
                                   map.TERRAIN_GROUND, map.TERRAIN_FLOOR)

    for x in range(1, new_map.width - 1):
        for y in range(1, new_map.height - 1):
            if new_map.terrain[x][y] == map.TERRAIN_GROUND:
                new_map.terrain[x][y] = map.TERRAIN_WALL

    #for x in range(0, new_map.width):
    #    new_map.terrain[x][0] = map.TERRAIN_WALL
    #    new_map.terrain[x][new_map.height-1] = map.TERRAIN_WALL
    #for y in range(0, new_map.height):
    #    new_map.terrain[0][y] = map.TERRAIN_WALL
    #    new_map.terrain[new_map.width-1][y] = map.TERRAIN_WALL

    zone_divisor = MINE_SIZE / 3
    slime_zone = new_map.rnd(0, 2)
    while True:
        undead_zone = new_map.rnd(0, 2)
        if undead_zone != slime_zone:
            break

    for r in range(3, len(new_map.rooms)):
        if new_map.rnd(1, 4) < 3:
            room = new_map.rooms[r]
            zone = room.center().x / zone_divisor
            if zone == slime_zone:
                if new_map.rnd(1, 2) == 1:
                    bestiary.slime(new_map,
                                   _find_floor_near_room(new_map,
                                                         room), player)
                    bestiary.slime(new_map,
                                   _find_floor_near_room(new_map,
                                                         room), player)
                else:
                    bestiary.jelly(new_map,
                                   _find_floor_near_room(new_map,
                                                         room), player)
            elif zone == undead_zone:
                bestiary.ghul(new_map, _find_floor_near_room(new_map, room),
                              player)
            else:
                bestiary.worm(new_map, _find_floor_near_room(new_map, room),
                              player)

    r = new_map.rnd(3, len(new_map.rooms) - 1)
    pos = new_map.rooms[r].center()
    while new_map.is_blocked_at(pos):
        pos += actions.random_direction()

    new_map.objects.insert(0,
                           Object(pos, '%', "hero's corpse", libtcod.dark_red))
    sword = miscellany.the_black_sword()
    sword.pos = pos
    new_map.objects.insert(0, sword)

    new_map.initialize_fov()
    new_map.xp_visit = _dungeon_exploration
    return False  # Don't need to generate stairs in caller thanks to _link_up_stairs()
コード例 #13
0
def make_map(player, dungeon_level):
    """
    """
    old_map = player.current_map

    new_map = map.DungeonMap(MINE_SIZE, MINE_SIZE, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    new_map.rng = libtcod.random_new_from_seed(new_map.random_seed)

    old_quarry_stairs = old_map.quarry_stairs
    _link_up_stairs(new_map, old_map, old_quarry_stairs)
    _create_entries(new_map, old_quarry_stairs)
    _descend_stairs(new_map, player, old_quarry_stairs)
    _dig_some_caves(new_map, old_quarry_stairs)
    _dig_mine_tunnels(new_map)

    map_bounds = algebra.Rect(1, 1, new_map.width-1, new_map.height-1)
    for x in range(1, new_map.width-1):
        for y in range(1, new_map.height-1):
            if libtcod.random_get_float(new_map.rng, 0., 1.) < 0.2:
                new_map.terrain[x][y] = map.TERRAIN_GROUND

    ca_cartographer._generation(new_map, map_bounds, 7, 1)
    ca_cartographer._generation(new_map, map_bounds, 5, 1)

    # Redig the initial rooms because the CA can fill in the stairs
    for i in range(3):
        _create_room(new_map, new_map.rooms[i])

    for i in range(3):
        stair_pos = old_quarry_stairs[i].dest_position
        ca_cartographer._floodfill(new_map, stair_pos.x, stair_pos.y,
            map.TERRAIN_GROUND, map.TERRAIN_FLOOR)

    for x in range(1, new_map.width-1):
        for y in range(1, new_map.height-1):
            if new_map.terrain[x][y] == map.TERRAIN_GROUND:
                new_map.terrain[x][y] = map.TERRAIN_WALL

    #for x in range(0, new_map.width):
    #    new_map.terrain[x][0] = map.TERRAIN_WALL
    #    new_map.terrain[x][new_map.height-1] = map.TERRAIN_WALL
    #for y in range(0, new_map.height):
    #    new_map.terrain[0][y] = map.TERRAIN_WALL
    #    new_map.terrain[new_map.width-1][y] = map.TERRAIN_WALL

    zone_divisor = MINE_SIZE / 3
    slime_zone = new_map.rnd(0, 2)
    while True:
        undead_zone = new_map.rnd(0, 2)
        if undead_zone != slime_zone:
            break

    for r in range(3, len(new_map.rooms)):
        if new_map.rnd(1, 4) < 3:
            room = new_map.rooms[r]
            zone = room.center().x / zone_divisor
            if zone == slime_zone:
                if new_map.rnd(1, 2) == 1:
                    bestiary.slime(new_map, _find_floor_near_room(new_map, room), player)
                    bestiary.slime(new_map, _find_floor_near_room(new_map, room), player)
                else:
                    bestiary.jelly(new_map, _find_floor_near_room(new_map, room), player)
            elif zone == undead_zone:
                bestiary.ghul(new_map, _find_floor_near_room(new_map, room), player)
            else:
                bestiary.worm(new_map, _find_floor_near_room(new_map, room), player)

    r = new_map.rnd(3, len(new_map.rooms) - 1)
    pos = new_map.rooms[r].center()
    while new_map.is_blocked_at(pos):
        pos += actions.random_direction()

    new_map.objects.insert(0, Object(pos, '%', "hero's corpse", libtcod.dark_red))
    sword = miscellany.the_black_sword()
    sword.pos = pos
    new_map.objects.insert(0, sword)

    new_map.initialize_fov()
    new_map.xp_visit = _dungeon_exploration
    return False  # Don't need to generate stairs in caller thanks to _link_up_stairs()
コード例 #14
0
def make_final_map(player, dungeon_level):
    """
    """
    old_map = player.current_map

    new_map = map.DungeonMap(FINAL_DUNGEON_SIZE, FINAL_DUNGEON_SIZE, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    new_map.rng = libtcod.random_new_from_seed(new_map.random_seed)

    entry_stairs = old_map.dungeon_stairs
    mine_cartographer._link_up_stairs(new_map, old_map, entry_stairs)
    mine_cartographer._create_entries(new_map, entry_stairs)
    mine_cartographer._descend_stairs(new_map, player, entry_stairs)

    num_rooms = 3
    for r in range(3, MAX_ROOMS):
        w = libtcod.random_get_int(new_map.rng, ROOM_MIN_SIZE, ROOM_MAX_SIZE)
        h = libtcod.random_get_int(new_map.rng, ROOM_MIN_SIZE, ROOM_MAX_SIZE)
        x = libtcod.random_get_int(new_map.rng, 0, new_map.width - w - 1)
        y = libtcod.random_get_int(new_map.rng, 0, new_map.height - h - 1)

        new_room = map.Room(x, y, w, h)

        failed = False
        for other_room in new_map.rooms:
            if new_room.intersect(other_room):
                failed = True
                break

        if not failed:
            # There are no intersections, so this room is valid.
            _create_room(new_map, new_room, num_rooms)
            new_ctr = new_room.center()
            prev_ctr = new_map.rooms[num_rooms-3].center()

            if libtcod.random_get_int(new_map.rng, 0, 1) == 1:
                _create_h_tunnel(new_map, prev_ctr.x, new_ctr.x, prev_ctr.y)
                _create_v_tunnel(new_map, prev_ctr.y, new_ctr.y, new_ctr.x)
            else:
                _create_v_tunnel(new_map, prev_ctr.y, new_ctr.y, prev_ctr.x)
                _create_h_tunnel(new_map, prev_ctr.x, new_ctr.x, new_ctr.y)

            new_map.rooms.append(new_room)
            new_map.room_entered.append(False)
            num_rooms += 1

    # TODO: should be floodfill from one stair, make *sure* the other two are
    # connected
    for i in range(3):
        stair_pos = entry_stairs[i].dest_position
        ca_cartographer._floodfill(new_map, stair_pos.x, stair_pos.y,
            map.TERRAIN_GROUND, map.TERRAIN_FLOOR)

    _add_doors(new_map)

    for i in range(3, num_rooms - 1):
        if (new_map.rnd(1, 2) == 1):
            foe = bestiary.dvergr(new_map, new_map.rooms[i].center(), player)
            _new_equipment(foe, miscellany.handaxe())
            _new_equipment(foe, miscellany.roundshield())
            if new_map.rnd(1, 2) == 1:
                _new_item(foe, miscellany.bandage(1))
            if new_map.rnd(1, 2) == 1:
                _new_item(foe, miscellany.kumiss(1))

    foe = bestiary.tepegoz(new_map, new_ctr, player)
    _new_equipment(foe, miscellany.maguffin())
    _new_equipment(foe, miscellany.spear())
    _new_equipment(foe, miscellany.roundshield())

    new_map.initialize_fov()
    new_map.xp_visit = _dungeon_exploration
    return False  # Don't need to generate stairs in caller thanks to _link_up_stairs()
コード例 #15
0
def make_final_map(player, dungeon_level):
    """
    """
    old_map = player.current_map

    new_map = map.DungeonMap(FINAL_DUNGEON_SIZE, FINAL_DUNGEON_SIZE,
                             dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    new_map.rng = libtcod.random_new_from_seed(new_map.random_seed)

    entry_stairs = old_map.dungeon_stairs
    mine_cartographer._link_up_stairs(new_map, old_map, entry_stairs)
    mine_cartographer._create_entries(new_map, entry_stairs)
    mine_cartographer._descend_stairs(new_map, player, entry_stairs)

    num_rooms = 3
    for r in range(3, MAX_ROOMS):
        w = libtcod.random_get_int(new_map.rng, ROOM_MIN_SIZE, ROOM_MAX_SIZE)
        h = libtcod.random_get_int(new_map.rng, ROOM_MIN_SIZE, ROOM_MAX_SIZE)
        x = libtcod.random_get_int(new_map.rng, 0, new_map.width - w - 1)
        y = libtcod.random_get_int(new_map.rng, 0, new_map.height - h - 1)

        new_room = map.Room(x, y, w, h)

        failed = False
        for other_room in new_map.rooms:
            if new_room.intersect(other_room):
                failed = True
                break

        if not failed:
            # There are no intersections, so this room is valid.
            _create_room(new_map, new_room, num_rooms)
            new_ctr = new_room.center()
            prev_ctr = new_map.rooms[num_rooms - 3].center()

            if libtcod.random_get_int(new_map.rng, 0, 1) == 1:
                _create_h_tunnel(new_map, prev_ctr.x, new_ctr.x, prev_ctr.y)
                _create_v_tunnel(new_map, prev_ctr.y, new_ctr.y, new_ctr.x)
            else:
                _create_v_tunnel(new_map, prev_ctr.y, new_ctr.y, prev_ctr.x)
                _create_h_tunnel(new_map, prev_ctr.x, new_ctr.x, new_ctr.y)

            new_map.rooms.append(new_room)
            new_map.room_entered.append(False)
            num_rooms += 1

    # TODO: should be floodfill from one stair, make *sure* the other two are
    # connected
    for i in range(3):
        stair_pos = entry_stairs[i].dest_position
        ca_cartographer._floodfill(new_map, stair_pos.x, stair_pos.y,
                                   map.TERRAIN_GROUND, map.TERRAIN_FLOOR)

    _add_doors(new_map)

    for i in range(3, num_rooms - 1):
        if (new_map.rnd(1, 2) == 1):
            foe = bestiary.dvergr(new_map, new_map.rooms[i].center(), player)
            _new_equipment(foe, miscellany.handaxe())
            _new_equipment(foe, miscellany.roundshield())
            if new_map.rnd(1, 2) == 1:
                _new_item(foe, miscellany.bandage(1))
            if new_map.rnd(1, 2) == 1:
                _new_item(foe, miscellany.kumiss(1))

    foe = bestiary.tepegoz(new_map, new_ctr, player)
    _new_equipment(foe, miscellany.maguffin())
    _new_equipment(foe, miscellany.spear())
    _new_equipment(foe, miscellany.roundshield())

    new_map.initialize_fov()
    new_map.xp_visit = _dungeon_exploration
    return False  # Don't need to generate stairs in caller thanks to _link_up_stairs()