anchor.diff:  
       setTile(new Vec(x, y), type);
     }
  +
  +  /// Invokes [callback] on each unique pair of [Room]s.
  +  void _forEachRoomPair(callback(_Room a, _Room b)) {
  +    for (var i = 0; i < _rooms.length - 1; i++) {
  +      for (var j = i + 1; j < _rooms.length; j++) {
  +        callback(_rooms[i], _rooms[j]);
  +      }
  +    }
  +  }
   }
   
  -class Room {
  +class _Room {
     final Rect bounds;
     int color;
     bool isOverlapping = false;
   
  -  Room(this.bounds, this.color);
  +  _Room(this.bounds, this.color);
   }
  
positive.code:       var nearestTo = null;
        var nearestDistance = 9999;
  
        // TODO(bob): Inner loop shouldn't go through all rooms. Redundantly
        // considers each pair twice.
        for (final fromRoom in _rooms) {
          if (fromRoom.color != fromColor) continue;
  
          for (final toRoom in _rooms) {
            if (toRoom.color == fromColor) continue;
  
            final distance = fromRoom.bounds.distanceTo(toRoom.bounds);
            if (distance < nearestDistance) {
              nearestFrom = fromRoom;
              nearestTo = toRoom;
              nearestDistance = distance;
            }
          }
        }
  
        carveCorridor(nearestFrom, nearestTo);
      }
  
      // Add some extra corridors so the dungeon isn't a minimum spanning tree.
      for (final fromRoom in _rooms) {
        for (final toRoom in _rooms) {
          if (fromRoom == toRoom) continue;
  
          final distance = fromRoom.bounds.distanceTo(toRoom.bounds);
          if ((distance < extraCorridorDistanceMax) &&
              rng.oneIn(extraCorridorOneIn + distance *
                  extraCorridorDistanceMultiplier)) {
            carveCorridor(fromRoom, toRoom);
          }
        }
      }
    }
  
    void carveCorridor(Room fromRoom, Room toRoom) {
      mergeColors(fromRoom, toRoom);
  
      // If the rooms overlap horizontally, carve a vertical path.
      final left = math.max(fromRoom.bounds.left, toRoom.bounds.left);
      final right = math.min(fromRoom.bounds.right, toRoom.bounds.right);
      if (left < right) {
        final top = math.min(fromRoom.bounds.top, toRoom.bounds.top);
        final bottom = math.max(fromRoom.bounds.bottom, toRoom.bounds.bottom);
  
        final x = rng.range(left, right);
        for (var y = top; y < bottom; y++) {
          setTile(new Vec(x, y), Tiles.floor);
        }
  
negative.code:     }
    }
  
    void _decorateRooms(void decorateRoom(Rect room)) {
      for (var i = 0; i < _rooms.length; i++) {
        var room = _rooms[i];
  
        // Don't decorate overlapping rooms.
        var overlap = false;
  