public boolean equal(TargetLevel other) {
   if (distribution.size() != other.distribution.size()) return false;
   for (Distribution d : distribution) {
     Distribution d2 = other.get(d.level);
     if (d2 == null || d.count != d2.count) return false;
   }
   return true;
 }
  public static TargetLevel parseJson(Repository repo, String str) {
    if (str == null || str.isEmpty()) return null;

    try {
      TargetLevel target = new TargetLevel();
      JSONArray arr = new JSONObject(str).getJSONArray("target");
      for (int i = 0; i < arr.length(); i++) {
        JSONObject obj = arr.getJSONObject(i);
        String name = (String) obj.keys().next();
        int count = obj.getInt(name);
        Level level = Level.parseOrCreate(repo, name);
        Distribution dist = target.getOrCreate(level);
        dist.count += count;
      }
      return target;
    } catch (Exception ex) {
    }
    return null;
  }
 public Level getNextGameLevel(TargetLevel played) {
   TargetLevel tl = new TargetLevel(this);
   for (Distribution d : played.distribution) {
     Distribution d2 = tl.get(d.level);
     while (d.count >= d2.count) {
       tl.add(1);
     }
     d2.count -= d.count;
   }
   Level l = null;
   double max = 0;
   for (Distribution d : tl.distribution) {
     if (d.count > max) {
       l = d.level;
       max = d.count;
     }
   }
   return l;
 }