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

249
LINES

< > BotCompany Repo | #1006891 // AI Game Where User Has To Click [Include]

JavaX fragment (include)

1  
///////////////////////////
2  
// Your API to work with //
3  
///////////////////////////
4  
5  
sinterface GameForAI {
6  
  L<Rect> submit(Pt point); // returns correct solution so AI can learn from it
7  
}
8  
9  
abstract sclass AI {
10  
  // stuff you get
11  
  
12  
  GameForAI game;
13  
  RGBImage image;
14  
  int steps;
15  
  bool visualize = true;
16  
  
17  
  RGBImage image() { ret image; }
18  
  int w() { ret image.w(); }
19  
  int h() { ret image.h(); }
20  
  L<Rect> submit(Pt p) { ret game.submit(p); }
21  
  L<Rect> submit(Rect r) { ret submit(middleOfRect(r)); }
22  
  L<Rect> submitNothing() { ret game.submit(null); }
23  
24  
  // implement this method and call submit()
25  
  abstract void go();
26  
  
27  
  void done() {}
28  
}
29  
30  
///////////////
31  
// Main Game //
32  
///////////////
33  
34  
static int w = 150, h = 150;
35  
static int rounds = 1000;
36  
static bool alwaysNewImage = true; // prevents AIs being stuck on an image
37  
static double imageZoom = 2;
38  
static int fps = 50;
39  
static bool showBlunderWindow;
40  
sS nonClickName = null;
41  
42  
static int points, clicks, halfTime;
43  
static ImageSurface is, isWrong;
44  
static long isWrongLast;
45  
static RGBImage img;
46  
static new HashMap<Rect, Int> words;
47  
static L<Rect> solution;
48  
volatile sbool aiMode;
49  
static JLabel lblScore, lblTiming, lblInstruction;
50  
static new HashMap<Class, AI> ais;
51  
static S winner;
52  
53  
svoid pGame {
54  
  substance();
55  
  swing {
56  
    thread { loadBinarySnippet(#1004373); } // preload applause animation
57  
    lblInstruction = jcenteredBoldLabel();
58  
    nextImage();
59  
    addToWindowTop(is, withMargin(lblInstruction));
60  
    if (nempty(nonClickName))
61  
      addToWindow(is, withTopMargin(jCenteredLine(jbutton(nonClickName, r {
62  
        userClicked(null)
63  
      }))));
64  
    addToWindow(is, withMargin(lblScore = jcenteredBoldLabel("Your score: 0 of 0")));
65  
    for (final Class c : myNonAbstractClassesImplementing(AI)) {
66  
      final S name = shortClassName(c);
67  
      final JButton btn = jbutton(name);
68  
      onClick(btn, r {
69  
        if (aiMode) ret;
70  
        btn.setText(name + " Running...");
71  
        thread {
72  
          Game game = testAI(c, voidfunc(Game game) {
73  
            if (game.step < 50 || (game.step % 10) == 0 || game.step == rounds) {
74  
              S text = name + " scored " + game.points + " of " + game.step;
75  
              if (game.step > halfTime)
76  
                text += " (" + (game.points-game.halfTimeScore) + "/" + (game.step-halfTime) + ")";
77  
              if (game.error != null)
78  
                text += " - ERROR: " + game.error;
79  
              setText_noWait(btn, text);
80  
            }
81  
          });
82  
        }
83  
      });
84  
      addToWindow(is, withMargin(btn));
85  
    }
86  
    addToWindow(is, lblTiming = jCenteredLabel(;
87  
    titlePopupMenuItem(is, "Show Winner Code", f showWinnerCode);
88  
    titlePopupMenuItem(is, "Restart AIs", r { clearMapWithCleanUp(ais); });
89  
    titlePopupMenuItem(is, jCheckBoxMenuItem("Show Blunder Window", showBlunderWindow, r { showBlunderWindow = !showBlunderWindow; }));
90  
    addToWindow(is, withMargin(jbutton("Restart AIs", r { clearMapWithCleanUp(ais); })));
91  
    
92  
    packFrame(is);
93  
    setFrameWidth(is, 400);
94  
    centerTopFrame(is);
95  
    hideConsole();
96  
  }
97  
}
98  
99  
sclass Puzzle {
100  
  S instruction, nonClickName;
101  
  RGBImage image;
102  
  L<Rect> solution;
103  
  
104  
  *() {}
105  
  *(S *instruction, BufferedImage image, L<Rect> *solution) {
106  
    this.image = new RGBImage(image);
107  
  }
108  
  *(S *instruction, RGBImage *image, L<Rect> *solution) {}
109  
  *(S *instruction, S *nonClickName, RGBImage *image, L<Rect> *solution) {}
110  
}
111  
112  
svoid nextImage {
113  
  Puzzle puzzle = makePuzzle();
114  
  setText(lblInstruction, or2(puzzle.instruction, "?"));
115  
  assertNotNull("Image is null", puzzle.image);
116  
  main.img = puzzle.image;
117  
  solution = puzzle.solution;
118  
  nonClickName = puzzle.nonClickName;
119  
  if (aiMode) ret; // occasional updates only when AI is running
120  
  showTheImage();
121  
}
122  
123  
svoid showTheImage {
124  
  bool first = is == null;
125  
  is = showZoomedImage_centered(is, img, imageZoom);
126  
  if (first) {
127  
    onLeftClick(is, voidfunc(Pt p) { userClicked(p) });
128  
    disableImageSurfaceSelector(is);
129  
    
130  
    // animate if idle
131  
    awtEvery(is, 1000, r {
132  
      if (!aiMode && isInForeground(is) && !mouseInFrame(is))
133  
        nextImage();
134  
    });
135  
    
136  
    // show current image occasionally when AI is running
137  
    awtEvery(is, 1000/fps, r {
138  
      if (aiMode) showTheImage();
139  
    });
140  
  }
141  
}
142  
143  
// AI stuff
144  
145  
sclass Game implements GameForAI {
146  
  int points, step, halfTimeScore;
147  
  Pt submitted;
148  
  Throwable error;
149  
  
150  
  public L<Rect> submit(Pt p) {
151  
    if (submitted != null) fail("No multi-submit please");
152  
    submitted = p == null ? nonPoint() : p;
153  
    bool correct = empty(solution) ? p == null
154  
      : p != null && anyRectContains(solution, p);
155  
    // print("p=" + p + ", solution=" + solution + ", correct=" + correct);
156  
    if (correct) {
157  
      ++points;
158  
      if (!alwaysNewImage) nextImage();
159  
    }
160  
    ret solution;
161  
  }
162  
}
163  
164  
static Game scoreAI(final AI ai, O onScore) {
165  
  aiMode = true;
166  
  final long start = sysNow();
167  
  try {
168  
    final new Game game;
169  
    setOpt(ai, +game);
170  
    halfTime = rounds/2;
171  
    while (game.step < rounds) {
172  
      if (game.step == halfTime) game.halfTimeScore = game.points;
173  
      ++game.step;
174  
      ++ai.steps;
175  
      game.submitted = null;
176  
      int points = game.points;
177  
      RGBImage image = img;
178  
      try {
179  
        setOpt(ai, +image);
180  
        ai.go();
181  
      } catch e {
182  
        if (game.error == null) { // print first error to console
183  
          showConsole();
184  
          printStackTrace(e);
185  
        }
186  
        game.error = e;
187  
      } finally {
188  
        setOpt(ai, image := null);
189  
      }
190  
      if (showBlunderWindow && points == game.points && hasElapsed(isWrongLast, 50)) {
191  
        isWrongLast = sysNow();
192  
        bool first = isWrong == null;
193  
        S guess = ""; // game.submitted == null ? "no click" : game.submitted.x + "/" + game.submitted.y;
194  
        isWrong = showImage(isWrong, "Last Blunder" + (nempty(guess) ? " (" + guess + ")" : ""), rgbMarkPoint(rgbClone(image), game.submitted, Color.red, 3));
195  
        if (first) {
196  
          setFrameWidth(isWrong, 230);
197  
          moveToTopRightCorner(isWrong);
198  
          moveFrameDown(isWrong, 100);
199  
        }
200  
      }
201  
      pcallF(onScore, game);
202  
      if (alwaysNewImage) nextImage();
203  
    }
204  
    print("AI " + shortClassName(ai) + " points after " + rounds + " rounds: " + game.points);
205  
    ai.done();
206  
    // We consider the game solved when an AI scores 100% in second half
207  
    if (game.points-game.halfTimeScore >= rounds-halfTime) thread {
208  
      titleStatus(is, "Solved!");
209  
      showAnimationInTopLeftCorner(#1004373, game.points + " of " + rounds + " points!!", 3.0);
210  
      winner = structure(ai);
211  
      save("winner");
212  
    }
213  
    ret game;
214  
  } finally {
215  
    aiMode = false;
216  
    awt {
217  
      lblTiming.setText(formatDouble(toSeconds(sysNow()-start), 1) + " s");
218  
      nextImage();
219  
    }
220  
  }
221  
}
222  
223  
static AI getAI(Class<? extends AI> c) {
224  
  AI ai = ais.get(c);
225  
  if (ai == null) ais.put(c, ai = nu(c));
226  
  ret ai;
227  
}
228  
229  
// onScore: voidfunc(Game)
230  
static Game testAI(Class<? extends AI> c, O onScore) {
231  
  ret scoreAI(getAI(c), onScore);
232  
}
233  
234  
svoid userClicked(Pt p) {
235  
  ++clicks;
236  
  bool correct = empty(solution) ? p == null
237  
    : p != null && anyRectContains(solution, is.pointFromComponentCoordinates(p));
238  
  if (correct) {
239  
    ++points;
240  
    nextImage();
241  
  } else if (alwaysNewImage) nextImage();
242  
  lblScore.setText(print("Your score: " + points + " of " + clicks));
243  
}
244  
245  
svoid showWinnerCode {
246  
  if (winner == null) load("winner");
247  
  if (winner == null) messageBox("No winner yet");
248  
  else showWrappedText("Winner Code - " + programTitle(), winner);
249  
}

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #1006891
Snippet name: AI Game Where User Has To Click [Include]
Eternal ID of this version: #1006891/37
Text MD5: 58950d720448af75ab2da549150245db
Author: stefan
Category: javax / a.i.
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2017-03-08 17:09:26
Source code size: 7702 bytes / 249 lines
Pitched / IR pitched: No / No
Views / Downloads: 607 / 1527
Version history: 36 change(s)
Referenced in: [show references]