@Override
  public void finish() {
    ArrayList<EdgeRoom> edge_rooms = new ArrayList<EdgeRoom>();
    edge_rooms.add(new EdgeRoom(RoomSide.EAST, eastmost_room));
    edge_rooms.add(new EdgeRoom(RoomSide.NORTH, northmost_room));
    edge_rooms.add(new EdgeRoom(RoomSide.WEST, westmost_room));
    edge_rooms.add(new EdgeRoom(RoomSide.SOUTH, southmost_room));

    entrance_edge_room = edge_rooms.remove((int) (Math.random() * edge_rooms.size()));

    EdgeRoom pre_exit_edge_room = null;
    do {
      pre_exit_edge_room = edge_rooms.remove((int) (Math.random() * edge_rooms.size()));
      if (pre_exit_edge_room.room.equals(entrance_edge_room.room)) {
        pre_exit_edge_room = null;
      }
    } while (pre_exit_edge_room == null);
    RoomSide direction = pre_exit_edge_room.direction;
    Dimension exit_room_dims;
    if (direction.equals(RoomSide.EAST) || direction.equals(RoomSide.WEST)) {
      exit_room_dims = new Dimension(DEFAULT_EXIT_ROOM_LENGTH, 1);
    }
    else {
      exit_room_dims = new Dimension(1, DEFAULT_EXIT_ROOM_LENGTH);
    }
    RoomConnection connection = positionRoom(pre_exit_edge_room.room, exit_room_dims, direction);
    pre_exit_edge_room.room.addNeighbor(direction, connection);
    RoomSide opposite_direction = RoomSide.opposite(direction);
    Room exit_room = connection.neighbor;
    exit_room.addNeighbor(opposite_direction, new RoomConnection(exit_room, pre_exit_edge_room.room,
            opposite_direction));
    exit_edge_room = new EdgeRoom(direction, exit_room);
    all_rooms.add(exit_room);
    // no need to call updateMapRanges here because MineExteriorRoom will be in same direction

    Point exterior_nw_corner;
    if (direction.equals(RoomSide.EAST)) {
      exterior_nw_corner = exit_room.getNECorner();
    }
    else if (direction.equals(RoomSide.NORTH)) {
      Point base_corner = exit_room.getNWCorner();
      exterior_nw_corner = new Point(base_corner.x, base_corner.y - 1);
    }
    else if (direction.equals(RoomSide.WEST)) {
      Point base_corner = exit_room.getNWCorner();
      exterior_nw_corner = new Point(base_corner.x - 1, base_corner.y);
    }
    else {
      exterior_nw_corner = exit_room.getSWCorner();
    }
    exterior_room = new MineExteriorRoom(exterior_nw_corner);
    exit_room.addNeighbor(direction, new RoomConnection(exit_room, exterior_room, direction));
    exterior_room.addNeighbor(opposite_direction, new RoomConnection(exterior_room, exit_room,
            opposite_direction));
    all_rooms.add(exterior_room);
    updateMapRanges(exterior_room);
  }