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

319
LINES

< > BotCompany Repo | #1006931 // AI Game For Reproducing Images [Old Include, use #1015048 now]

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 = 1000;
static double targetScore = 99.0; // stop when this score is reached
static int fps = 50;
sS gameTitle;
sS newImageText = "New Image";
sS instruction = "Reproduce this image:";
sS aiTitle = "AI";
sbool showConsoleOnError;
static double reproZoom = 2;

static int w, h;
static new UserGame userGame;
static int halfTime;
static ImageSurface is, isUser, isRepro;
static RGBImage img;
static new HashMap<Rect, Int> words;
static L<Rect> solution;
volatile sbool aiMode;
static JLabel lblScore, lblTiming, lblInstruction, lblImageName;
static new HashMap<Class, AI> ais;
static S winner;
static JCheckBox keepRunning;
static L<JButton> aiButtons;
static Game game;

svoid pGame {
  substance();
  swing {
    thread { loadBinarySnippet(#1004373); } // preload applause animation
    lblInstruction = jcenteredBoldLabel(instruction);
    lblScore = jcenteredBoldLabel();
    nextImage();
    addToWindowTop(is, withMargin(lblInstruction));
    addToWindow(is, withMargin(lblScore));
    addToWindow(is, withMargin(lblImageName = jcenteredlabel()));
    
    // add AI bjuttons
    aiButtons = ll();
    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 =*/ 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(); });
      aiButtons.add(btn);
      addToWindow(is, withMargin(btn));
    }
    
    addToWindow(is, lblTiming = jCenteredLabel(;
    titlePopupMenuItem(is, "Show Winner Code", f showBestCode);
    titlePopupMenuItem(is, "Restart AIs", r { restartAIs() });
    titlePopupMenuItem(is, "Diff", r {
      setImage(subtractRGBImages(img, renderImage(game.best!)))
    });
    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();
      setImage(main.img);
    })));
    addToWindow(is, withMargin(jbutton("Load image...", r {
      frameTitle("Load image", selectSnippetID_v1(voidfunc(S imageID) {
        loadImageSnippet(imageID);
      }));
    })));
    addToWindow(is, withMargin(jbutton("Scale down", f scaleDown)));
    addToWindow(is, withMargin(jbutton("Random image", r-thread {
      loadImageSnippet(randomImageServerID());
    })));

    packFrame(is);
    setFrameWidth(is, 500);
    centerTopFrame(is);
    hideConsole();
  }
}

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

svoid showTheImage {
  bool first = is == null;
  is = showZoomedImage_centered(is, img, 1);
  w = img.w();
  h = img.h();
    
  if (first) {
    if (gameTitle == null) gameTitle = programTitle();
    setFrameTitle(is, gameTitle);

    disableImageSurfaceSelector(is);
    
    isUser = new ImageSurface(newBufferedImage(w, h, Color.white));
    JComponent form = cast callOptMC('makeTheForm, userGame); // make form for user participation
    
    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 {
  volatile int step;
  new Best<Submission> best;
  RGBImage bestImage;
  double score;
  Submission submitted; // what was submitted in this round
  Throwable error;
  volatile bool cancelled;
  
  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;
    RGBImage image = renderImage(data);
    double score = scoreImage(image);
    if (best.put(data, score)) {
      bestImage = image;
      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;
    main.game = game;
    while (game.step < rounds && !game.cancelled) {
      ++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;
        S title = dropSpaces(formatScore(game.score)) + " - " + aiTitle;
        isRepro = showZoomedImage_centered(isRepro, title, renderWithHints(game.best.get()), reproZoom);
        if (first) {
          //coActivateAllMyFrames();
          moveToTopRightCorner(isRepro);
          enlargeFrameLeftAndBottom(isRepro, 100, 100);
        }
      }
      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 showBestCode {
  Submission s = game.best!;
  showWrappedText("Best code (" + formatScore(game.best.score()) + ")", structure(s));
}

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

static double scoreImage(RGBImage image) {
  ret 100*(1.0-rgbDistance(image, img));
}

svoid restartAIs {
  clearMapWithCleanUp(ais);
  // whatever I do, it doesn't get cancelled, haha
  //if (game != null) game.cancelled = true;
}

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

svoid setImage(final RGBImage img) {
  swing {
    main.img = img;
    showTheImage();
    restartAIs();
  }
}

svoid scaleDown() {
  setImage(rgbScale(main.img, 0.5));
}

svoid loadImageSnippet(S id) {
  setImage(RGBImage(changeTransparencyToWhiteBackground(loadImage2(id))));
  setText(lblImageName, snippetWithTitle(id));
}

Author comment

Began life as a copy of #1006891

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: #1006931
Snippet name: AI Game For Reproducing Images [Old Include, use #1015048 now]
Eternal ID of this version: #1006931/107
Text MD5: 015ee824c98f9a36e48576b29cba2c8d
Author: stefan
Category: javax / a.i.
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2018-05-07 14:16:29
Source code size: 9082 bytes / 319 lines
Pitched / IR pitched: No / No
Views / Downloads: 634 / 2025
Version history: 106 change(s)
Referenced in: [show references]