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

267
LINES

< > BotCompany Repo | #1004551 // Reproduce Image 4 (with class Reproducing)

JavaX source code [tags: use-pretranspiled] - run with: x30.jar

Libraryless. Click here for Pure Java version (4762L/31K/104K).

!752

static BWImage bw;
static ImageSurface imageSurface;
static Thread producer;
static Reproducing rp;

!include #1000522 // image helper functions

p {
  rp = new Reproducing;
  bw = rp.bw = loadBWImage("#1004541");
  imageSurface = showImage(rp.bw.getBufferedImage());
  rp.imageSurfaceToUpdateWithBest = imageSurface;
  
  //showImage("Full Grab", descToImage(fullGrab(bw)));
  
  produce();
  rp.reproduceOpenEnd();
  
  while (rp.solved()) {
    rp.pivotLength = l(rp.bestDesc) - rp.pivotStep;
    print("Trying pivot length " + rp.pivotLength);

    produce();
    rp.reproduceOpenEnd();
  }
}

static void produce() {
  cancelThread(producer);
  producer = new Thread(r {
    // STRATEGY!
    
    rp.push(fullGrab(bw));
    int w = 1;
    while licensed {
      rp.push(new RandomSolid().reproduce(bw));
      S best = rp.bestDesc;
      if (best != null)
        rp.push(varyFloat(best));
      if (w < rp.bw.getWidth())
        rp.push(hrepeat(bw, w++));
    }
  }, "Producer");
  producer.start();
}

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

sclass Reproducing {
  BWImage bw; // original
  ImageSurface imageSurfaceToUpdateWithBest;
  new LinkedBlockingQueue<S> newProducts;
  int maxQueueLength = 10;
  Best shortest100;
  double bestScore;
  volatile S bestDesc;
  BWImage bestRendering;
  int pivotLength = -1; // no length punishment at start
  int pivotStep = 1;
  int fullGrabLength; // length of full grab for reference

  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 reproduceOpenEnd() {
    bestDesc = null;
    bestScore = 0;
    bestRendering = null;
    Renderer 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)
          System.out.println(s);
        else {
          System.out.println("Best: " + bestDesc);
          System.out.println(s + ", score: " + formatDouble(bestScore, 2) + "%, l=" + l(bestDesc) + ", 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 (bestDesc == null || p != null && score > bestScore) {
        //System.out.println("New best! " + score);
        bestDesc = desc;
        bestScore = score;
        bestRendering = rendering;
        best = p;
        if (pixelScore >= 100 && (shortest100 == null || shortest100.l() > l(desc))) {
          shortest100 = new Best(desc, pixelScore, rendering);
          saveTextFile(getProgramFile("shortest100.txt"), bw.getWidth() + " " + bw.getHeight() + " " + desc);
        }
        imageSurface.setImage(bestRendering.getBufferedImage());
      }
      
      if (solved()) {
        print("Solved! l=" + l(bestDesc));
        print(bestDesc);
        break;
      }
    }
  }
  
  bool solved() {
    ret bestScore >= 100.0;
  }
  
  BufferedImage descToImage(S desc) {
    try {
      ret makeRenderer(desc).render(bw.getWidth(), bw.getHeight()).getBufferedImage();
    } catch {
      fail(desc);
    }
  }
}

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 = makeRenderer(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 Renderer makeRenderer(S desc) {
  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();
}

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

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

Author comment

Began life as a copy of #1004545

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #1004551
Snippet name: Reproduce Image 4 (with class Reproducing)
Eternal ID of this version: #1004551/1
Text MD5: aab8ce0320808195f71e45d0d3ffe72c
Transpilation MD5: f2dcafe1888ea6848cb4f49afbd564c5
Author: stefan
Category: javax / a.i.
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-08-21 02:15:43
Source code size: 6905 bytes / 267 lines
Pitched / IR pitched: No / No
Views / Downloads: 567 / 952
Referenced in: #1004552 - Show Shortest 100 from #1004551
#1004556 - class "Reproducing" (image reproduction framework) + FullGrab etc.
#1004557 - Reproduce Image 5 (using include)