Uses 3874K of libraries. Click here for Pure Java version (6012L/43K/157K).
| 1 | !7 | 
| 2 | |
| 3 | /////////////////////////// | 
| 4 | // Your API to work with // | 
| 5 | /////////////////////////// | 
| 6 | |
| 7 | abstract sclass GameForAI {
 | 
| 8 | abstract RGBImage getImage(); | 
| 9 | abstract L<Rect> submit(Pt point); // returns correct solution so AI can learn from it | 
| 10 | } | 
| 11 | |
| 12 | abstract sclass AI {
 | 
| 13 | // stuff you get | 
| 14 | |
| 15 | GameForAI game; | 
| 16 | RGBImage image; | 
| 17 | int steps; | 
| 18 |   RGBImage image() { ret image; }
 | 
| 19 |   int w() { ret image.w(); }
 | 
| 20 |   int h() { ret image.h(); }
 | 
| 21 |   L<Rect> submit(Pt p) { ret game.submit(p); }
 | 
| 22 |   L<Rect> submit(Rect r) { ret submit(middleOfRect(r)); }
 | 
| 23 |   L<Rect> submitNothing() { ret game.submit(null); }
 | 
| 24 | |
| 25 | // implement this method and call submit() | 
| 26 | abstract void go(); | 
| 27 | |
| 28 |   void done() {}
 | 
| 29 | } | 
| 30 | |
| 31 | ////////////////////////////////////// | 
| 32 | // Test AIs. Just add your own here // | 
| 33 | ////////////////////////////////////// | 
| 34 | |
| 35 | AI > TestAI {
 | 
| 36 |   void go {
 | 
| 37 | submit(new Pt(random(image().w()), random(image().h()))); | 
| 38 | } | 
| 39 | } | 
| 40 | |
| 41 | AI > ErrorAI {
 | 
| 42 |   void go {
 | 
| 43 | throw new NullPointerException; | 
| 44 | } | 
| 45 | } | 
| 46 | |
| 47 | /////////////// | 
| 48 | // Main Game // | 
| 49 | /////////////// | 
| 50 | |
| 51 | static int w = 150, h = 150; | 
| 52 | static int border = 10, fontSize = 30, numberMargin = 3; | 
| 53 | static int rounds = 1000, numbers = 2; | 
| 54 | static S font = #1004887; | 
| 55 | static bool alwaysNewImage = true; // prevents AIs being stuck on an image | 
| 56 | static int fps = 50; | 
| 57 | |
| 58 | static int points, clicks; | 
| 59 | static ImageSurface is, isWrong; | 
| 60 | static long isWrongLast; | 
| 61 | static RGBImage img; | 
| 62 | static new HashMap<Rect, Int> words; | 
| 63 | static L<Rect> solution; | 
| 64 | volatile sbool aiMode; | 
| 65 | static JLabel lblScore, lblTiming; | 
| 66 | static new HashMap<Class, AI> ais; | 
| 67 | |
| 68 | p-substance {
 | 
| 69 |   thread { loadBinarySnippet(#1004373); } // preload applause animation
 | 
| 70 | nextImage(); | 
| 71 |   addToWindow(is, withMargin(lblScore = jcenteredBoldLabel("Your score: 0 of 0")));
 | 
| 72 |   for (final Class c : myNonAbstractClassesImplementing(AI)) {
 | 
| 73 | final S name = shortClassName(c); | 
| 74 | final JButton btn = jbutton(name); | 
| 75 |     onClick(btn, r {
 | 
| 76 | if (aiMode) ret; | 
| 77 | btn.setText(name + " Running..."); | 
| 78 |       thread {
 | 
| 79 |         Game game = testAI(c, voidfunc(Game game) {
 | 
| 80 |           if (game.step < 50 || (game.step % 10) == 0 || game.step == rounds) {
 | 
| 81 | S text = name + " scored " + game.points + " of " + game.step; | 
| 82 | if (game.error != null) | 
| 83 | text += " - ERROR: " + game.error; | 
| 84 | setText_noWait(btn, text); | 
| 85 | } | 
| 86 | }); | 
| 87 | } | 
| 88 | }); | 
| 89 | addToWindow(is, withMargin(btn)); | 
| 90 | } | 
| 91 | addToWindow(is, lblTiming = jCenteredLabel(; | 
| 92 |   titlePopupMenuItem(is, "Restart AIs", r { clearMapWithCleanUp(ais); });
 | 
| 93 |   addToWindow(is, withMargin(jbutton("Restart AIs", r { clearMapWithCleanUp(ais); })));
 | 
| 94 | |
| 95 | packFrame(is); | 
| 96 | setFrameWidth(is, 400); | 
| 97 | centerTopFrame(is); | 
| 98 | hideConsole(); | 
| 99 | } | 
| 100 | |
| 101 | svoid nextImage {
 | 
| 102 | RGBImage img = rgbImage(Color.white, w, h); | 
| 103 | words.clear(); | 
| 104 | new L<Rect> taken; | 
| 105 |   for i to numbers: {
 | 
| 106 | int num = random(10); | 
| 107 | S s = str(num); | 
| 108 | RGB color = new RGB(random(0.5), random(0.5), random(0.5)); | 
| 109 | renderText_fg.set(color.getColor()); | 
| 110 | BufferedImage ti = renderText(font, fontSize, s); | 
| 111 | Rect r; | 
| 112 | int safety = 0; | 
| 113 |     do {
 | 
| 114 | r = randomRect(w, h, border, ti.getWidth(), ti.getHeight()); | 
| 115 |       if (r == null || ++safety >= 1000) fail("Image too small: \*ti.getWidth()*/*\*ti.getHeight()*/ > \*w*/*\*h*/");
 | 
| 116 | } while (anyRectOverlaps(taken, r)); | 
| 117 | rgbCopy(ti, img, r.x, r.y); | 
| 118 | words.put(r, num); | 
| 119 | taken.add(growRect(r, numberMargin)); | 
| 120 | } | 
| 121 | solution = keysWithBiggestValue(words); | 
| 122 | |
| 123 | main.img = img; | 
| 124 | if (aiMode) ret; // occasional updates only when AI is running | 
| 125 | showTheImage(); | 
| 126 | } | 
| 127 | |
| 128 | svoid showTheImage {
 | 
| 129 | bool first = is == null; | 
| 130 | is = showZoomedImage_centered(is, img, "Click On The Highest Number!", 1.5); | 
| 131 |   if (first) {
 | 
| 132 |     onLeftClick(is, voidfunc(Pt p) {
 | 
| 133 | ++clicks; | 
| 134 |       if (anyRectContains(solution, is.pointFromComponentCoordinates(p))) {
 | 
| 135 | ++points; | 
| 136 | nextImage(); | 
| 137 | } else if (alwaysNewImage) nextImage(); | 
| 138 |       lblScore.setText(print("Your score: " + points + " of " + clicks));
 | 
| 139 | }); | 
| 140 | disableImageSurfaceSelector(is); | 
| 141 | |
| 142 | // animate if idle | 
| 143 |     awtEvery(is, 1000, r {
 | 
| 144 | if (!aiMode && isInForeground(is) && !mouseInComponent(is)) | 
| 145 | nextImage(); | 
| 146 | }); | 
| 147 | |
| 148 | // show current image occasionally when AI is running | 
| 149 |     awtEvery(is, 1000/fps, r {
 | 
| 150 | if (aiMode) showTheImage(); | 
| 151 | }); | 
| 152 | } | 
| 153 | } | 
| 154 | |
| 155 | // AI stuff | 
| 156 | |
| 157 | sclass Game extends GameForAI {
 | 
| 158 | int points, step; | 
| 159 | Pt submitted; | 
| 160 | Throwable error; | 
| 161 | |
| 162 |   RGBImage getImage() { ret img; }
 | 
| 163 | |
| 164 |   L<Rect> submit(Pt p) {
 | 
| 165 |     if (submitted != null) fail("No multi-submit please");
 | 
| 166 | submitted = p == null ? new Pt(-9, -9) : p; | 
| 167 |     if (p != null && anyRectContains(solution, p)) {
 | 
| 168 | ++points; | 
| 169 | if (!alwaysNewImage) nextImage(); | 
| 170 | } | 
| 171 | ret solution; | 
| 172 | } | 
| 173 | } | 
| 174 | |
| 175 | static Game scoreAI(AI ai, O onScore) {
 | 
| 176 | aiMode = true; | 
| 177 | final long start = sysNow(); | 
| 178 |   try {
 | 
| 179 | final new Game game; | 
| 180 | setOpt(ai, +game); | 
| 181 |     while (game.step < rounds) {
 | 
| 182 | ++game.step; | 
| 183 | ++ai.steps; | 
| 184 | game.submitted = null; | 
| 185 | int points = game.points; | 
| 186 | RGBImage image = img; | 
| 187 |       try {
 | 
| 188 | setOpt(ai, +image); | 
| 189 | ai.go(); | 
| 190 |       } catch e {
 | 
| 191 |         if (game.error == null) { // print first error to console
 | 
| 192 | showConsole(); | 
| 193 | printStackTrace(e); | 
| 194 | } | 
| 195 | game.error = e; | 
| 196 |       } finally {
 | 
| 197 | setOpt(ai, image := null); | 
| 198 | } | 
| 199 |       if (points == game.points && hasElapsed(isWrongLast, 50)) {
 | 
| 200 | isWrongLast = sysNow(); | 
| 201 | bool first = isWrong == null; | 
| 202 | isWrong = showImage(isWrong, "Last Blunder", rgbMarkPoint(image, game.submitted, Color.red, 3)); | 
| 203 |         if (first) {
 | 
| 204 | setFrameWidth(isWrong, 230); | 
| 205 | moveToTopRightCorner(isWrong); | 
| 206 | moveFrameDown(isWrong, 100); | 
| 207 | } | 
| 208 | } | 
| 209 | pcallF(onScore, game); | 
| 210 | if (alwaysNewImage) nextImage(); | 
| 211 | } | 
| 212 |     print("AI " + shortClassName(ai) + " points after " + rounds + " rounds: " + game.points);
 | 
| 213 | ai.done(); | 
| 214 |     if (game.points >= rounds) thread { showAnimationInTopLeftCorner(#1004373, game.points + " of " + rounds + " points!!", 3.0); }
 | 
| 215 | ret game; | 
| 216 |   } finally {
 | 
| 217 | aiMode = false; | 
| 218 |     awt {
 | 
| 219 | lblTiming.setText(formatDouble(toSeconds(sysNow()-start), 1) + " s"); | 
| 220 | nextImage(); | 
| 221 | } | 
| 222 | } | 
| 223 | } | 
| 224 | |
| 225 | static AI getAI(Class<? extends AI> c) {
 | 
| 226 | AI ai = ais.get(c); | 
| 227 | if (ai == null) ais.put(c, ai = nu(c)); | 
| 228 | ret ai; | 
| 229 | } | 
| 230 | |
| 231 | // onScore: voidfunc(Game) | 
| 232 | static Game testAI(Class<? extends AI> c, O onScore) {
 | 
| 233 | ret scoreAI(getAI(c), onScore); | 
| 234 | } | 
Began life as a copy of #1006674
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: | #1006752 | 
| Snippet name: | Second A. I. Game Simplified | 
| Eternal ID of this version: | #1006752/4 | 
| Text MD5: | 7e4d01641311e24e7d520e3ec1d2d156 | 
| Transpilation MD5: | da09b70e0d4df1d9765678da92c0a8eb | 
| Author: | stefan | 
| Category: | javax / gui | 
| Type: | JavaX source code | 
| Public (visible to everyone): | Yes | 
| Archived (hidden from active list): | No | 
| Created/modified: | 2017-02-04 00:01:10 | 
| Source code size: | 6621 bytes / 234 lines | 
| Pitched / IR pitched: | No / No | 
| Views / Downloads: | 593 / 741 | 
| Version history: | 3 change(s) | 
| Referenced in: | [show references] |