sclass FindURLBox1 { Color color = Color.white; int maxHeight = 50, minWidth = 100; int g = 2; // grid size double fullScanEvery = 10.0; // if we get stuck on a wrong box new L encouragedBoxes; new L discouragedBoxes; RGBImage img; L clips; Rect bestClip; RGBImage bestImage; bool verbose; long recogTime; // includes shooting the screen long lastFullScan; // returns true if smth was found bool go() { long time = sysNow(); try { if (lastFullScan >= now()-toMS(fullScanEvery) && stillThere()) ret true; lastFullScan = now(); img = shootScreen(); ret calc(); } finally { recogTime = sysNow()-time; } } bool calc() { clips = [Rect r : areasColored(img, color, g) | r.h <= maxHeight && r.w >= minWidth]; if (verbose) print(n(clips, "areas") + " found for color " + new RGB(color) + ": " + struct(clips)); bestClip = bestAccordingTo(clips, func(Rect r) { scoreClip(r) }); bestImage = img.clip(bestClip); ret bestClip != null; } double scoreClip(Rect r) { int i = encouragedBoxes.indexOf(r); if (i >= 0) ret 1000-i; i = discouragedBoxes.indexOf(r); if (i >= 0) ret -1000+i; double width = min(1, r.w/(double) img.w()*2); double top = r.y/(double) img.h(); double height = r.h/(double) img.h(); ret width-(top+height)*2; // thin, wide, high up } RGBImage bestImage() { ret bestImage; } void reset() { bestClip = null; } bool stillThere() { if (bestClip == null) false; Rect r = intersectWithScreen(growRect(bestClip, g)); RGBImage img = shootScreen(r); L clips = areasColored(img, color, g); Rect r2 = translateRect(bestClip, -r.x, -r.y); //print("r2=" + r2 + ", clips=" + struct(clips)); if (clips.contains(r2)) { bestImage = img.clip(r2); true; } else { bestClip = null; bestImage = null; false; } } }