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

212
LINES

< > TinyBrain | #1007370 - Player VS Player [WORKS]

JavaX source code (desktop) [tags: use-pretranspiled] - run with: x30.jar - homepage

Uses 2245K of libraries. Click here for Pure Java version (7322L/51K).

!7

static CirclesAndLines cal;
static Thinker thinker;

!include #1007377 // traits

p-pretty {
  cal = new CirclesAndLines;
  makeGraph();
  Canvas canvas = cal.show(900, 600);
  (thinker = nu(Thinker, +cal, +canvas,
    resetGraph := f makeGraph, think := f think)).init();
}

svoid makeGraph {
  mergedNodes = 0;
  cal.clear();
  Circle a = cal.circle_autoVis("PLAYER", "Chess Player", 0.25, 0.7);
  Circle b = cal.circle_autoVis("PLAYER", "Chess Player", 0.75, 0.7);
  cal.arrow(a, "VS", b);
  cal.circle_autoVis("MAGNUS CARLSEN", 0.25, 0.25);
  cal.circle_autoVis("HIKARU NAKAMURA", 0.75, 0.25);
}

sbool think() {
  // Find an isolated node and try to merge it with another node
  if (!anyIsolatedNodes()) false;
  Pair<Circle, Circle> p = findTwoRandomNodes();
  if (p != null && isIsolated(p.a) && nodesAttract(p.a, p.b))
    mergeNodes(p.a, p.b);
  true;
}

sbool traitsAttract(S a, S b) {
  ret isPair(a, b, "player", "magnus carlsen")
    || isPair(a, b, "player", "hikaru nakamura");
}

sbool traitsDiverge(S a, S b) {
  ret isPair(a, b, "magnus carlsen", "hikaru nakamura");
}

sbool anyIsolatedNodes() {
  for (Circle c : cal.circles) if (isIsolated(c)) true; false;
}

sbool isIsolated(Circle c) {
  for (Line l : cal.lines)
    if (l.a == c || l.b == c)
      false;
  true;
}

static Pair<Circle, Circle> findTwoRandomNodes() {
  ret selectRandomPair(cal.circles);
}

sbool nodesAttract(Circle a, Circle b) {
  if (nodesDiverge(a, b)) false;
  for (S x : a.traits())
    for (S y : b.traits())
      if (traitsAttract(x, y))
        true;
  false;
}

sbool nodesDiverge(Circle a, Circle b) {
  for (S x : a.traits())
    for (S y : b.traits())
      if (traitsDiverge(x, y))
        true;
  false;
}

sbool isPair(S a, S b, S x, S y) {
  ret eqic(a, x) && eqic(b, y)
    || eqic(a, y) && eqic(b, x);
}

static int mergedNodes;

svoid mergeNodes(Circle a, Circle b) {
  assertTrue("Circle must be isolated to merge", isIsolated(a));
  b.img = a.img;
  b.addTraits(a.traits());
  cal.circles.remove(a);
  thinker.status("Merged " + n(mergedNodes += 2, "node") + ".");
}

sclass Thinker {
  double delay = 0.1; // seconds
  bool continueOnError = true;
  CirclesAndLines cal;
  Canvas canvas;
  JTextArea textArea;
  JButton btnThink;
  volatile bool thinking;
  S status, initialStatus = "Initial state.";
  int step;
  bool inited;
  O think; // func -> bool
  O resetGraph; // runnable
  Throwable error;
  
  void init {
    if (inited) ret;
    inited = true;
    addControls();
    thread "Think" { Thinker.this.run(); }
  }
  
  void addControls {
    swing {
      addToWindowRight(canvas, withMargin(vstackWithSpacing(
        jMaxWidth(167,
          jMinHeight(180, jscroll(textArea = setFontSize(16, makeBold(wordWrapTypeWriterTextArea()))))),
        btnThink = fatButton(100, "Think!", r { thinkOrStop() }),
        fatButton(60, "Think again!", r { thinkAgain() }),
        fatButton(60, "Reset", r { reset() })
        )));
      increaseFrameWidth(canvas, 180);
      status(initialStatus);
    }
  }
  
  void startOver {
    lock(cal.lock, "StartOver", 2000);
    try {
      step = 0; status(initialStatus);
      callF(resetGraph);
    } finally {
      unlock(cal.lock, "StartOver");
    }
    if (canvas != null) canvas.update();
  }
  
  void thinkAgain {
    startOver();
    thinking(true);
  }
  
  void reset {
    thinking(false);
    startOver();
  }
  
  void run {
    repeat {
      sleepSeconds(delay);
      if (thinking) pcall {
        print("Thinking");
        bool t;
        time { t = think(); }
        if (!t) {
          thinking(false);
          print("Done");
        } else {
          print("Updating");
          if (canvas != null) canvas.update();
        }
      }
    }
  }
  
  void thinking(bool b) {
    thinking = b; status();
    setText(btnThink, b ? "<html><center>Stop<br>thinking</center></html>" : "Think!");
  }
  
  void status(S s) {
    status = s; status();
  }
  
  void thinkOrStop {
    thinking(!thinking);
  }
  
  bool think() {
    if (think == null) false;
    lock(cal.lock, "Thinking", 5000);
    try {
      step++; status();
      if (isFalse(callF(think))) {
        step--; status();
        false;
      }
      true;
    } catch e {
      printStackTrace(e);
      error = getInnerException(e);
      ret continueOnError;
    } finally {
      unlock(cal.lock, "Done thinking");
    }
  }
  
  JButton fatButton(int h, S text, O action) {
    JButton btn = jbutton(text, action);
    btn.setFont(sansSerifBold(16));
    ret jMinSize(167, h, btn);
  }
  
  void status {
    setText(textArea, status + "\n\n" +
      (thinking ? "Thinking...\n\n" : "") +
      (step == 0 ? "No thoughts made yet."
        : "Thoughts made: " + step) +
      (error == null ? "" : "\n\nERROR: " + exceptionToStringShort(error)));
  }
}

download  show line numbers  debug dex   

Travelled to 3 computer(s): cfunsshuasjs, onxytkatvevr, tvejysmllsmz

No comments. add comment

Snippet ID: #1007370
Snippet name: Player VS Player [WORKS]
Eternal ID of this version: #1007370/70
Text MD5: b509dbf9497084f5f25c446989e38fef
Transpilation MD5: fc94b8766506fe7f94bb20459cd3a887
Author: stefan
Category: javax / a.i. / gui
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2017-03-19 18:02:03
Source code size: 5030 bytes / 212 lines
Pitched / IR pitched: No / No
Views / Downloads: 176 / 500
Version history: 69 change(s)
Referenced in: [show]