!7 static int points; static ImageSurface is; static RGBImage img; static int w = 400, h = 300; static int border = 10, fontSize = 30; static int rounds = 1000; static S font = #1004887; static new HashMap words; static L solution; volatile sbool aiMode; p-substance { nextImage(); for (final Class c : nonAbstractClassesImplementing(AI)) addToWindow(is, jbutton("Test AI " + shortClassName(c), r { testAI(c) })); } svoid nextImage { RGBImage img = rgbImage(Color.white, w, h); words.clear(); for i to 5: { int num = random(100); S s = str(num); RGB color = new RGB(random(0.5), random(0.5), random(0.5)); renderText_fg.set(color.getColor()); BufferedImage ti = renderText(font, fontSize, s); Rect r; do { r = randomRect(w, h, border, ti.getWidth(), ti.getHeight()); if (r == null) fail("Image too small: \*ti.getWidth()*/*\*ti.getHeight()*/ > \*w*/*\*h*/"); } while (anyRectOverlaps(keys(words), r) && licensed()); rgbCopy(ti, img, r.x, r.y); words.put(r, num); } solution = keysWithBiggestValue(words); bool first = is == null; is = showImage(is, main.img = img); if (first) { onLeftClick(is, voidfunc(Pt p) { if (anyRectContains(solution, p)) { ++points; print("Points: " + points); nextImage(); } }); disableImageSurfaceSelector(is); // animate if idle awtEvery(is, 1000, r { if (!aiMode && isInForeground(is) && !mouseInComponent(is)) nextImage(); }); } } // AI stuff abstract sclass GameForAI { abstract RGBImage getImage(); abstract L cheat(); } sclass Game extends GameForAI { int points; RGBImage getImage() { ret img; } L cheat() { ret solution; } void click(Pt p) { if (anyRectContains(solution, p)) { ++points; nextImage(); } } } abstract sclass AI { GameForAI game; RGBImage image() { ret game.getImage(); } int w() { ret image().w(); } int h() { ret image().h(); } abstract Pt nextClick(); } static void scoreAI(AI ai, long rounds) { aiMode = true; try { new Game game; setOpt(ai, +game); long step = 0; pcall { while (step < rounds) { ++step; Pt p = ai.nextClick(); if (p == null) { print("AI resigned"); break; } game.click(p); //print("Step " + step + ", move: " + p + ", points: " + game.points); } } print("AI " + shortClassName(ai) + " points after " + rounds + " rounds: " + game.points); } finally { aiMode = false; } } svoid testAI(Class c) { scoreAI(nu(c), rounds); } // Test AI AI > TestAI { Pt nextClick() { ret new Pt(random(image().w()), random(image().h())); } }