Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

258
LINES

< > BotCompany Repo | #1004556 // class "Reproducing" (image reproduction framework) + FullGrab etc.

JavaX fragment (include)

!include #1000522 // image helper functions

sclass Best {
  S desc;
  double score;
  Renderer renderer;
  BWImage image;
  
  *() {}
  *(S *desc, double *score, BWImage *image) {}
  *(S *desc, double *score, Renderer *renderer, BWImage *image) {}
  
  int l() { ret main.l(desc); }
}

static O rendererMaker; // optional maker function (S -> Renderer)

sclass Reproducing {
  BWImage bw; // original
  ImageSurface imageSurfaceToUpdateWithBest;
  new LinkedBlockingQueue<S> newProducts;
  int maxQueueLength = 10;
  volatile Best shortest100, best;
  int pivotLength = -1; // no length punishment at start
  int pivotStep = 1;
  int fullGrabLength; // length of full grab for reference
  O startProduction; // optional runnable that starts production
  int descPrintLength = 100;

  void push(S product) {
    if (product == null) ret;
    while (newProducts.size() >= maxQueueLength && mayRun())
      sleep(100);
    newProducts.add(product);
  }
  
  double formula(S desc, double pixelScore) {
    int lengthPunishment = pivotLength < 0 ? 0
      : max(0, l(desc)-pivotLength);
    ret pixelScore-lengthPunishment;
  }
  
  void loadShortest100() {
    S shortest = shortest100();
    if (shortest != null)
      shortest100 = new Best(shortest, 100, null);
  }
  
  void reproduceOpenEnd() {
    loadShortest100();
    best = null;
    fullGrabLength = l(fullGrab(bw));
    long lastPrint = 0, lastN = 0;
    for (long ntry = 1; ; ntry++) {
      ping();
      long now = now();
      if (now >= lastPrint+1000) {
        long tps = (ntry-lastN)*1000/(now-lastPrint);
        lastPrint = now;
        lastN = ntry;
        String s = "Try " + ntry + " (" + tps + "/s)";
        if (best == null)
          print(s);
        else {
          print("Best: " + shorten(best.desc, descPrintLength));
          print(s + ", score: " + formatDouble(best.score, 2) + "%, l=" + l(best.desc) + ", pivotL=" + pivotLength + "/" + fullGrabLength + (shortest100 == null ? "" : ", shortest100=" + shortest100.l()));
        }
      }
      S desc;
      try {
        desc = grabFromQueue(newProducts);
      } catch e {
        print("Production failed: " + exceptionToStringShort(e));
        continue;
      }
      Renderer p;
      try {
        p = makeRenderer(desc);
      } catch {
        print("Can't unstructure: " + desc);
        continue;
      }
      
      BWImage rendering = render(p, bw);
      double pixelScore = 100*(1-diff(bw, rendering));
      double score = formula(desc, pixelScore);
      
      if (best == null || p != null && score > getScore(best)) {
        //System.out.println("New best! " + score);
        best = new Best(desc, score, p, rendering);
        if (pixelScore >= 100 && (shortest100 == null || shortest100.l() > l(desc))) {
          shortest100 = new Best(desc, pixelScore, rendering);
          saveTextFile(getProgramFile("shortest100.txt"), bw.getWidth() + " " + bw.getHeight() + " " + desc);
        }
        imageSurfaceToUpdateWithBest.setImage(best.image.getBufferedImage());
      }
      
      if (solved()) {
        print("Solved! l=" + best.l());
        print(shorten(best.desc, descPrintLength));
        break;
      }
    }
  }
  
  bool solved() {
    ret getScore(best) >= 100.0;
  }
  
  S bestDesc() {
    ret getDesc(best);
  }
  
  BufferedImage descToImage(S desc) {
    try {
      ret makeRenderer(desc).render(bw.getWidth(), bw.getHeight()).getBufferedImage();
    } catch {
      fail(desc);
    }
  }
  
  void produce() {
    callF(startProduction);
  }
  
  void findShortest100_openEnd() {
    produce();
    reproduceOpenEnd();
  
    while (solved()) {
      pivotLength = best.l() - pivotStep;
      print("Trying pivot length " + pivotLength);
  
      produce();
      reproduceOpenEnd();
    }
  }
}

static class FullGrab extends Renderer {
  int dw, dh;
  byte[] data;
  
  BWImage render(int w, int h) {
    if (w != dw || h != dh)
      fail("size: \*w*/ \*h*/ \*dw*/ \*dh*/");
    ret new BWImage(w, h, data);
  }
}

static class HRepeat extends Renderer {
  int width;
  S inner;
  
  BWImage render(int w, int h) {
    BWImage img = new BWImage(w, h);
    BWImage clip = ((Renderer) unstructure(inner)).render(width, h);
    for (int x = 0; x < w; x += width)
      copy(clip, 0, 0, img, x, 0, width, h);
    ret img;
  }
}
  
static S fullGrab(BWImage img) {
  DynamicObject d = new DynamicObject("FullGrab");
  int w = img.getWidth(), h = img.getHeight();
  d.put("dw", w);
  d.put("dh", h);
  byte[] data = new byte[w*h];
  for (int y = 0; y < h; y++)
    for (int x = 0; x < w; x++)
      data[y*w+x] = img.getByte(x, y);
  d.put("data", data);
  ret structure(d);
}

static S hrepeat(BWImage img, int width) {
  int h = img.getHeight();
  BWImage clip = img.clip(0, 0, width, h);
  ret structure(dynamicObject("HRepeat", "width", width, "inner", fullGrab(clip)));
}

static S varyFloat(S s) {
  L<S> tok = javaTok(s);
  int i = tok.indexOf("f");
  if (i < 0) null;
  float f = Float.parseFloat(unquote(tok.get(i+2)));
  f = (float) (f+random(-0.1, 0.1));
  tok.set(i+2, quote(str(f)));
  ret join(tok);
}

static BWImage render(Renderer p, BWImage original) {
  ret p.render(original.getWidth(), original.getHeight());
}

static interface Reproducer {
  public S reproduce(BWImage original);
}

static class Solid extends Renderer {
  float col;
  
  BWImage render(int w, int h) {
    ret new BWImage(w, h, col);
  }
}

static class RandomSolid implements Reproducer {
  int n = -1;
  public S reproduce(BWImage original) {
    ++n;
    DynamicObject p = new DynamicObject("Solid");
    if (n % 2 == 0) {
      p.put("col", randomBrightness());
    } else {
      p.put("col", probeRandomPixel(original));
    }
    ret structure(p);
  }
}

static abstract class Renderer {
  abstract BWImage render(int w, int h);
}

static S shortest100() {
  ret loadTextFile(getProgramFile("shortest100.txt"));
}

static BufferedImage renderShortest100() {
  ret render(shortest100());
}

static double getScore(Best b) {
  ret b == null ? 0 : b.score;
}

static S getDesc(Best b) {
  ret b == null ? null : b.desc;
}

static Renderer makeRenderer(S desc) {
  if (rendererMaker != null) {
    Renderer r = cast callF(rendererMaker, desc);
    if (r != null) ret r;
  }
  ret (Renderer) unstructure(desc);
}

static BufferedImage render(S fullDesc) {
  if (fullDesc == null) null;
  new Matches m;
  assertTrue(jmatchStart("* *", fullDesc, m));
  int w = m.psi(0), h = m.psi(1);
  S desc = m.unq(2);
  ret makeRenderer(desc).render(w, h).getBufferedImage();
}

Author comment

Began life as a copy of #1004551

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1004556
Snippet name: class "Reproducing" (image reproduction framework) + FullGrab etc.
Eternal ID of this version: #1004556/1
Text MD5: 4c8235723ff6b8de1a3288f59805c5c8
Author: stefan
Category: javax / a.i.
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-08-22 16:29:57
Source code size: 6802 bytes / 258 lines
Pitched / IR pitched: No / No
Views / Downloads: 632 / 1006
Referenced in: #1004557 - Reproduce Image 5 (using include)
#1004562 - class "Reproducing" for column prediction
#1004577 - Image Compressor ("go-basics.txt")