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

271
LINES

< > BotCompany Repo | #1009151 // AI Game 7.1 Include [dev.]

JavaX fragment (include)

///////////////////////////
// Your API to work with //
///////////////////////////

sinterface GameForAI {
  int round(); // starting from 1
  double submit(Submission data); // returns score (0-100)
}

abstract sclass AI {
  // stuff you get
  
  GameForAI game;
  RGBImage image;
  bool visualize = true;
  
  RGBImage image() { ret image; }
  int w() { ret image.w(); }
  int h() { ret image.h(); }
  int round() { ret game.round(); }
  double submit(Submission data) { ret game.submit(data); }
  <A extends AI> A initSubAI(A ai) { setOptAll(ai, +game, +image); ret ai; }

  // implement this method and call submit()
  abstract void go();
  
  void done() {}
}

///////////////
// Main Game //
///////////////

static int rounds = 10000;
static double targetScore = 99.0; // stop when this score is reached
static int fps = 50;
sS newImageText = "New Image";
sS instruction = "Reproduce this image:";
sS aiTitle = "AI";
sbool showConsoleOnError;

static int w, h;
static new UserGame userGame;
static int halfTime;
static ImageSurface is, isUser, isRepro;
static RGBImage img; // the main image
static double[][] integralImage;
static new HashMap<Rect, Int> words;
static L<Rect> solution;
volatile sbool aiMode;
static JLabel lblScore, lblTiming, lblInstruction;
static new HashMap<Class, AI> ais;
static S winner;
static JCheckBox keepRunning;

svoid pGame {
  substance();
  swing {
    thread { loadBinarySnippet(#1004373); } // preload applause animation
    lblInstruction = jcenteredBoldLabel(instruction);
    lblScore = jcenteredBoldLabel();
    nextImage();
    addToWindowTop(is, withMargin(lblInstruction));
    addToWindow(is, withMargin(lblScore));
    for (final Class c : myNonAbstractClassesImplementing(AI)) {
      final S name = shortClassName(c);
      final JButton btn = jbutton(name);
      final Runnable go = r {
        if (aiMode) ret;
        setText(btn, name + " Running...");
        final Runnable again = this;
        thread {
          Game game = testAI(c, voidfunc(Game game) {
            if (!(game.step >= rounds || (game.step % 10) == 0)) ret;
            S text = name + " scored " + formatScore(game.score) + " in " + n(game.step, "round");
            if (game.error != null)
              text += " - ERROR: " + game.error;
            setText_noWait_sync(btn, text);
          });
          if (isChecked(keepRunning)) again.run();
        }
      };
      onClick(btn, r { if (aiMode) setChecked(keepRunning, false); else go.run(); });
      addToWindow(is, withMargin(btn));
    }
    addToWindow(is, lblTiming = jCenteredLabel(;
    titlePopupMenuItem(is, "Show Winner Code", f showWinnerCode);
    titlePopupMenuItem(is, "Restart AIs", r { restartAIs() });
    addToWindow(is, withMargin(jRightAlignedLine(keepRunning = jcheckbox("Keep AI Running", true))));
    addToWindow(is, withMargin(jbutton("Restart AIs", r { clearMapWithCleanUp(ais); })));
    addToWindow(is, withMargin(jbutton(newImageText, r {
      nextImage();
      if (aiMode) showTheImage();
      restartAIs();
    })));

    packFrame(is);
    setFrameWidth(is, 400);
    centerTopFrame(is);
    //hideConsole();
  }
}

svoid nextImage {
  img = makeImage();
  w = img.w();
  h = img.h();
  integralImage = integralImage(img);
  if (aiMode) ret; // occasional updates only when AI is running
  showTheImage();
}

svoid showTheImage {
  bool first = is == null;
  is = showZoomedImage_centered(is, img, 1);
    
  if (first) {
    disableImageSurfaceSelector(is);
    
    isUser = new ImageSurface(newBufferedImage(w, h, Color.white));
    JComponent form = makeTheForm(userGame);
    
    if (form != null) {
      addToWindow(is, withTitle("Your Reproduction:", jscroll_centered(isUser)));
      addToWindow(is, form);
    }
    
    // animate if idle
    /*awtEvery(is, 1000, r {
      if (!aiMode && isInForeground(is) && !mouseInFrame(is))
        nextImage();
    });*/
    
    // show current image occasionally when AI is running
    /*awtEvery(is, 1000/fps, r {
      if (aiMode) showTheImage();
    });*/
  }
}

// AI stuff

sclass Game implements GameForAI {
  int step;
  new Best<Submission> best;
  double score;
  Submission submitted; // what was submitted in this round
  Throwable error;
  
  public int round() { ret step; }
  
  public double submit(Submission data) {
    if (data == null) ret 0;
    if (submitted != null) fail("No multi-submit please");
    submitted = data;
    double score = scoreSubmission(data);
    //print("Score " + score + " for submission: " + sfu(submitted));
    if (best.put(data, score))
      this.score = best.score;
    ret score;
  }
}

Game > UserGame {
  public double submit(Submission data) {
    submitted = null;
    double score = super.submit(data);
    RGBImage image = renderImage(data);
    isUser.setImage(image);
    lblScore.setText("Current score: " + formatScore(score)
      + " / Best: " + formatScore(userGame.score));
    ret score;
  }
}

static S formatScore(double score) {
  ret formatDouble(score, 2) + " %";
}

svoid initAI(AI ai, GameForAI game) {
  setOpt(ai, +game);
}

static Game scoreAI(final AI ai, O onScore) {
  aiMode = true;
  final long start = sysNow();
  try {
    final new Game game;
    initAI(ai, game);
    halfTime = rounds/2;
    game.step = 0;
    while (game.step < rounds) {
      ++game.step;
      game.submitted = null;
      double score = game.score;
      RGBImage image = img;
      try {
        setOpt(ai, +image);
        ai.go();
      } catch e {
        if (game.error == null) { // print first error to console
          if (showConsoleOnError) showConsole();
          printStackTrace(e);
        }
        game.error = e;
      } finally {
        setOpt(ai, image := null);
      }
      if (game.score > score) {
        bool first = isRepro == null;
        isRepro = showZoomedImage_centered(isRepro, aiTitle, renderWithHints(game.best.get()), 2);
        if (first)
          moveToTopRightCorner(isRepro);
      }
      pcallF(onScore, game);
      //if (alwaysNewImage) nextImage();
    }
    ai.done();
    
    // TODO: winner saving
    /*if (game.points-game.halfTimeScore >= rounds-halfTime) thread {
      titleStatus(is, "Solved!");
      showAnimationInTopLeftCorner(#1004373, game.points + " of " + rounds + " points!!", 3.0);
      winner = structure(ai);
      save("winner");
    }*/
    ret game;
  } finally {
    aiMode = false;
    awt {
      lblTiming.setText(formatDouble(toSeconds(sysNow()-start), 1) + " s");
      //nextImage();
    }
  }
}

static AI getAI(Class<? extends AI> c) {
  AI ai = ais.get(c);
  if (ai == null) ais.put(c, ai = nu(c));
  ret ai;
}

// onScore: voidfunc(Game)
static Game testAI(Class<? extends AI> c, O onScore) {
  ret scoreAI(getAI(c), onScore);
}

svoid showWinnerCode {
  if (winner == null) load("winner");
  if (winner == null) messageBox("No winner yet");
  else showWrappedText("Winner Code - " + programTitle(), winner);
}

svoid restartAIs {
  clearMapWithCleanUp(ais);
}

svoid setInstruction(S s) {
  setText(lblInstruction, instruction = s);
}

static double scoreSubmission(Submission data) {
  double sum = 0;
  new L<Rect> rects;
  for (Haar h : data.features)
    addAll(rects, h.black, h.white);
  if (anyRectsOverlap(rects)) ret 0;
  for (Haar h : data.features)
    sum += calcHaar(integralImage, h.black, h.white);
  ret sum;
}

Author comment

Began life as a copy of #1006931

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: #1009151
Snippet name: AI Game 7.1 Include [dev.]
Eternal ID of this version: #1009151/13
Text MD5: 469f48e8575e8baa95be2337f04243ec
Author: stefan
Category: javax / a.i.
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2017-07-06 01:19:52
Source code size: 7628 bytes / 271 lines
Pitched / IR pitched: No / No
Views / Downloads: 560 / 910
Version history: 12 change(s)
Referenced in: [show references]