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

226
LINES

< > BotCompany Repo | #1004545 // Reproduce Image 3 (with formula)

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

Libraryless. Click here for Pure Java version (4636L/30K/101K).

!752

static BWImage bw;
static ImageSurface imageSurface;
static Reproducer reproducer;
static int pivotLength = -1; // no length punishment at start
static int pivotStep = 1;
static int maxQueueLength = 10;

static new LinkedBlockingQueue<S> newProducts;
static double bestScore;
static volatile S bestDesc;
static BWImage bestRendering;
static Thread producer;

!include #1000522 // image helper functions

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

    reproduceOpenEnd(bw, imageSurface);
  }
}

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

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 void push(S product) {
  if (product == null) ret;
  while (newProducts.size() >= maxQueueLength && mayRun())
    sleep(100);
  newProducts.add(product);
}

static BufferedImage descToImage(S desc) {
  try {
    ret makeRenderer(desc).render(bw.getWidth(), bw.getHeight()).getBufferedImage();
  } catch {
    fail(desc);
  }
}

static double formula(S desc, double pixelScore) {
  int lengthPunishment = pivotLength < 0 ? 0
    : max(0, l(desc)-pivotLength);
  ret pixelScore-lengthPunishment;
}

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 void reproduceOpenEnd(BWImage original, ImageSurface imageSurface) {
  bestDesc = null;
  bestScore = 0;
  bestRendering = null;
  Renderer best = null;
  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) + "%, structure size: " + structureSize(best, Renderer.class));
      }
    }
    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, original);
    double pixelScore = 100*(1-diff(original, 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;
      imageSurface.setImage(bestRendering.getBufferedImage());
    }
    
    if (solved()) {
      print("Solved! l=" + l(bestDesc));
      print(bestDesc);
      break;
    }
  }
}

sbool solved() {
  ret bestScore >= 100.0;
}

static Renderer makeRenderer(S desc) {
  ret (Renderer) unstructure(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 BWImage render(Renderer p, BWImage original) {
  ret p.render(original.getWidth(), original.getHeight());
}

Author comment

Began life as a copy of #1004544

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #1004545
Snippet name: Reproduce Image 3 (with formula)
Eternal ID of this version: #1004545/1
Text MD5: 9dbb9b935268109854604275f0fb9008
Transpilation MD5: 4830bb3ce94c8bb2cbc00f9124244480
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-20 21:55:54
Source code size: 5593 bytes / 226 lines
Pitched / IR pitched: No / No
Views / Downloads: 584 / 719
Referenced in: [show references]