Warning: session_start(): open(/var/lib/php/sessions/sess_rrevftrf0n1j6cq9lg5t02tm93, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
//set flag Reparse.
set flag OurSyncCollections. // allow to run on newer JDKs without illegal-access command line flags
import javax.swing.filechooser.*;
!include #1031138 // Smarty AI Include
static int defaultSpacing = 10, spacing;
static JFrame mainFrame;
static LL gridComponents;
static JComponent mainGrid;
static JCheckBoxMenuItem miShowLocations;
static SingleComponentPanel scpMainGrid, scpVisionConfig, scpWheelsConfig, scpCurrentSmarty,
scpStimuliAndResponse;
static JFrame historyFrame, memoryFrame;
static JSpinner worldSizeSpinner;
static JTextArea historyTextArea1, historyTextArea2, memoryTextArea;
static new Smarty smarty; // AI instance
static Q smartyQ = startQ("Smarty Q"); // queue for Smarty operations
sS wallSymbol = unicode_blackSquare(), noWallSymbol = unicode_dottedSquare();
static Color lightBlue = colorFromHex("4169e1");
sS locationLetters = charRange('A', 'Z') + "[\\]^_`" + charRange('a', 'z') + charRange(123, 128);
sS smartyUnicode = unicode_slightlySmilingFace();
static int smartyFontSize = 40;
sS windowsFontID = #1400468;
sS emojiFontID = #1400470;
sS frameIconID = #1102983;
sS smartyImageID = #1102987;
sS worldFileExtension = "WLD";
sS bodyFileExtension = "BDY";
sS historyHelp = unindent_mls([[
A percept is the stimulus or simultaneous combination of stimuli observed.
An action is the response or simultaneous combination of responses produced.
Binon # numbers refer to the binons in memory that represent the percepts, actions, expectations, and perceptual or action sequences.
P = Percept, E = Expectation, PP = Perceptual sequence A = Action, AA = Action sequence
Read the paper: "The Perception-Action Hierarchy and its Implementation Using Binons (Binary Neurons)" on the www.adaptroninc.com website for more information.
]]);
sbool showTabs = true;
static int defaultWorldSize = 7, maxWorldSize = 8;
svoid rearrangeLetters {
int iLetter = 0;
for (int y = 0; y < state.gridRows; y++)
for (int x = 0; x < state.gridCols; x++) {
JCell cell = getCell(x, y);
if (cell.obstacle())
cell.letter = ' ';
else
cell.letter = locationLetters.charAt(iLetter++);
}
}
sclass VisionMode {
sS nextSquare = "next square";
sS distanceToWall = "distance to wall";
sS wallOrNot = "wall or not";
}
sclass CameraDirection {
sS down = "down";
sS left = "left";
sS right = "right";
sS inFront = "in front";
sS behind = "behind";
static LS all = ll(down, left, right, inFront, behind);
}
concept SmartyBody {
S name = "Smarty0";
Set cameraDirections = litset(CameraDirection.down);
S visionMode = VisionMode.nextSquare; // see VisionMode
Set wheels = litset("MoveForward", "MoveLeft", "MoveRight", "MoveBackward");
bool changed; // changed w.r.t. file
bool used; // used in Smarty execution
// for saving
S wheelsFlag(S flag) { ret wheels.contains(flag) ? "1" : "0"; }
void userCausedChange {
print("Body: User caused change");
changed = true;
change();
}
}
concept State {
float fontScale = 1.5f;
S worldName = "Empty";
int gridRows = defaultWorldSize, gridCols = defaultWorldSize; // actually these are always identical, could merge into one
bool showLocations = true;
bool worldChanged;
int smartyX, smartyY;
Rect selection = rect(1, 1, 1, 1);
Pt cursorDirection = pt(1, 0);
new BitSet obstacles;
new Ref body;
// value is just true
Map recentWorldFiles = synchronizedMRUCache(5);
Map recentBodyFiles = synchronizedMRUCache(5);
void setSelection(Rect r) {
if (!cset_trueIfChanged(this, selection := r)) ret;
if (selection.h == 1 && selection.w > 1) _setField(cursorDirection := pt(1, 0));
else if (selection.w == 1 && selection.h > 1) _setField(cursorDirection := pt(0, 1));
repaint(mainGrid);
}
void clearSelectedArea {
fillSelection(false);
}
void invertSelection {
JCell cell1 = getCell(selection.x, selection.y);
fillSelection(!cell1.obstacle());
}
void fillSelection(bool b) {
for (Pt p : pointsInRect(selection))
getCell(p.x, p.y).setObstacle(b);
rearrangeLetters();
moveCursor();
}
void moveCursor {
setCursor(selection.x+cursorDirection.x, selection.y+cursorDirection.y);
}
void setCursor(int x, int y) {
setSelection(rect(mod(x, gridCols), mod(y, gridRows), 1, 1));
}
void moveCursor(int dx, int dy) {
_setField(cursorDirection := pt(dx, dy));
setCursor(selection.x+cursorDirection.x, selection.y+cursorDirection.y);
}
void placeSmarty {
getCell(selection.x, selection.y).setObstacle(false);
moveSmarty(selection.x, selection.y);
moveCursor();
}
void moveSmarty(int x, int y) {
if (!inRange(x, 0, gridCols) || !inRange(y, 0, gridRows))
fail("Smarty position not in range: " + x + "/" + y);
if (cset_trueIfChanged(this, smartyX := x, smartyY := y))
cset(this, worldChanged := true);
}
void moveSmartyRelative(int x, int y) {
moveSmarty(smartyX+x, smartyY+y);
}
} // end of State
static State state;
sclass JCell > JComponent {
int x, y;
char letter;
*(int *x, int *y) {}
public void paint(Graphics _g) {
Graphics2D g = cast _g;
int w = getWidth(), h = getHeight();
Color color = Color.white;
if (state.selection.contains(x, y)) color = lightBlue;
else if (obstacle()) color = Color.black;
fillRect(g, 0, 0, w, h, color);
if (state.showLocations && !obstacle()) {
temp tempSetFont(g, loadFont_cached(windowsFontID));
drawTextWithTopLeftCornerAt(g, str(letter), Pt(2, 0), Color.black);
}
if (state.smartyX == x && state.smartyY == y) {
temp tempSetFontSize(g, smartyFontSize);
/*temp tempSetFont(g, loadFont_cached(emojiFontID));
drawCenteredText(g, smartyUnicode, 0, 0, w, h, Color.black);*/
double size = 0.6;
int dx = iround((1-size)/2*w);
int dy = iround((1-size)/2*h);
drawScaledImage(g, loadImage2_cached(smartyImageID), rectFromPoints(dx, dy, w-dx, h-dy));
}
}
int index() { ret y*state.gridCols+x; }
bool obstacle() { ret main contains(state.obstacles, index()); }
void setObstacle(bool b) {
if (setBit_trueIfChanged(state.obstacles, index(), b)) {
cset(state, worldChanged := true);
state.change();
}
}
{
addMouseListener(new MouseAdapter {
public void mousePressed(MouseEvent e) {
main requestFocus(mainGrid);
if (!isLeftButton(e)) ret;
state.setSelection(new Rect(x, y, 1, 1));
}
});
addMouseMotionListener(new MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
//_print("Drag in " + x + "/" + y + ": " + e.getPoint());
Component dest = componentAtScreenLocationInWindow(mainFrame, e);
if (dest cast JCell) {
//_print("Target: " + dest);
state.setSelection(rectFromPointsInclusiveSorted(x, y, dest.x, dest.y));
}
}
});
}
toString { ret x + "/" + y; }
}
static JCell getCell(int x, int y) {
ret gridComponents.get(y).get(x);
}
svoid makeMainGrid {
gridComponents = map(iotaZeroList(state.gridRows), y
-> map(iotaZeroList(state.gridCols), x
-> new JCell(x, y)));
mainGrid = setFocusable(setBackground(Color.black, hvgrid(gridComponents, 1)));
scpMainGrid.setComponent(mainGrid);
rearrangeLetters();
}
// always clears the world
svoid setWorldSize(int size) {
state.obstacles.clear();
state.gridCols = state.gridRows = size;
setSpinnerValue(worldSizeSpinner, size);
state.selection = rect(1, 1);
state.moveSmarty(0, 0);
cset(state, worldChanged := false);
state.change();
makeMainGrid();
}
p {
if (javax() == null)
getJavaXDirectly();
else
autoRestart(2.0);
// print all vm bus msgs from concepts
//vmBus_snoopToPrint((msg, arg) -> firstOfArrayOrSame(arg) instanceof Concepts);
setProgramDir(print("Using directory: ", mainDir()));
logProgramOutput();
_handleException_showThreadCancellations = true;
initSmarty();
if (!isDevVersion()) hideConsole();
else veryBigConsole();
db();
uniq(SmartyBody); // make at least one instance
state = uniq(State);
if (!state.body.has()) cset(state, body := conceptWhere(SmartyBody)); // default body
cset(state.body, used := false); // XXX
jtattoo_mcWin();
//set swingFontScale_debug;
updateFontScale(state.fontScale);
loadLibrary(windowsFontID);
defaultFrameIcon(frameIconID);
mainFrame = showFrame(makeMainTitle());
exitOnClose(mainFrame);
historyTextArea1 = typeWriterTextArea();
historyTextArea2 = typeWriterTextArea();
memoryTextArea = typeWriterTextArea();
makeMenus();
registerCtrlKey(mainFrame, KeyEvent.VK_N, "New world", r { print("new") });
registerCtrlKey(mainFrame, KeyEvent.VK_R, "Retrieve world", r {});
registerCtrlKey(mainFrame, KeyEvent.VK_S, "Save world", r {});
addMenu(mainFrame, "View",
miShowLocations = jCheckBoxMenuItem("Locations (Ctrl+L)", state.showLocations, b -> {
cset(state, showLocations := b);
repaint(mainGrid);
}),
jMenu("UI Zoom",
"100%", r { uiZoom(100) },
"112%", r { uiZoom(112) },
"125%", r { uiZoom(125) },
"140%", r { uiZoom(140) })
);
registerCtrlKey(mainFrame, KeyEvent.VK_L, "Locations", r {
cset(state, showLocations := !state.showLocations);
setChecked(miShowLocations, state.showLocations);
repaint(mainGrid);
});
JMenuBar menuBar = getMenuBar(mainFrame);
JMenuItem helpItem = jMenuItem("Help F1", rThread showHelp);
/*print(minSize := getMinimumSize(helpItem));
print(preferredSize := getPreferredSize(helpItem));*/
addMenuItem(menuBar, jPreferredWidthToMaxWidth(helpItem));
addAndRevalidate(menuBar, jHorizontalGlue()); // spacer
registerFunctionKey(mainFrame, 1, rThread showHelp);
registerKeyCode(mainFrame, KeyEvent.VK_SPACE, r { state.invertSelection() });
registerKeyCode(mainFrame, KeyEvent.VK_UP, r { state.moveCursor(0, -1) });
registerKeyCode(mainFrame, KeyEvent.VK_LEFT, r { state.moveCursor(-1, 0) });
registerKeyCode(mainFrame, KeyEvent.VK_DOWN, r { state.moveCursor(0, 1) });
registerKeyCode(mainFrame, KeyEvent.VK_RIGHT, r { state.moveCursor(1, 0) });
for (int key = KeyEvent.VK_A; key <= KeyEvent.VK_Z; key++)
registerKeyCode(mainFrame, key, r { state.placeSmarty() });
worldSizeSpinner = jSpinner(state.gridCols, 1, maxWorldSize);
onChange(worldSizeSpinner, r {
int size = intFromSpinner(worldSizeSpinner);
if (state.gridCols != size) {
if (state.worldChanged) {
int result = swingShowConfirmDialog(mainFrame,
"World has changed! - Save it before resizing?", "Smarty",
JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION) {
saveWorldDialog(r { newWorldWithoutConfirmation(size) });
ret;
} else if (result == JOptionPane.CANCEL_OPTION) {
setSpinnerValue(worldSizeSpinner, state.gridCols);
ret;
}
}
newWorldWithoutConfirmation(size);
}
});
scpCurrentSmarty = singleComponentPanel();
JComponent middleArea = westAndCenterWithMargin(spacing,
jvstackWithSpacing(spacing,
withTitle("World size (max=\*maxWorldSize*/)", worldSizeSpinner),
jbutton("Clear Selected Area", rThread { state.clearSelectedArea() }),
withTitle("Current world", disableTextField(jLiveValueTextField(conceptFieldLiveValue worldName(state)))),
showTabs ? null : fontSizePlus(2, setForeground(Color.ORANGE, jCenteredLabel("Design or Select a body for Smarty"))),
showTabs ? null : jbutton("Design or Select Smarty's Body", r showSmartyConfig),
withTitle("Current Smarty", scpCurrentSmarty),
),
jvgridWithSpacing(spacing,
withTitle("Sensors Values are", jTextArea()),
withTitle("Devices Values are", jTextArea())
)
);
JComponent controlArea = northCenterAndSouthWithMargin(spacing,
fontSizePlus(2, setForeground(Color.blue, jlabel("Design the World - Read the Help F1"))),
middleArea,
jCenteredSection("Run Smarty",
jflow(
jbutton("Go / Continue", rThread goCmd),
jButton("See History", r showHistory),
jbutton("See Memory", r showMemory),
jbutton("Reset"),
jbutton("EXIT", rThread killVM),
))
);
scpMainGrid = singleComponentPanel();
makeMainGrid();
var mainPanel = westAndCenterWithMargins(spacing,
jvstackWithSpacing(spacing,
jFixedSize(500, scpMainGrid),
scpStimuliAndResponse = singleComponentPanel()
),
controlArea);
if (showTabs) {
scpVisionConfig = singleComponentPanel();
scpWheelsConfig = singleComponentPanel();
updateTabs();
setFrameContents(mainFrame, jtabs(
"Smarty", mainPanel,
"Vision", scpVisionConfig,
"Wheels", scpWheelsConfig,
));
} else
setFrameContents(mainFrame, mainPanel);
centerPackFrame(mainFrame);
// set minimum width
jMinWidth_pure(mainFrame, swingScale(800));
centerFrameWithMinWidth(mainFrame);
// disable height changes entirely
jMinHeight_pure(mainFrame, getHeight(mainFrame));
frameMaxHeight(mainFrame, getHeight(mainFrame));
enableBodyControls(false); // XXX
if (!isDevVersion()) showHelp();
else goCmd();
} // end of main function
sbool isDevVersion() {
ret isProgramID(#1031104);
}
svoid updateTabs {
scpVisionConfig.setComponent(visionConfigPanel(state.body!));
scpWheelsConfig.setComponent(wheelsConfigPanel(state.body!));
scpCurrentSmarty.setComponent(disableTextField(jLiveValueTextField(conceptFieldLiveValue name(state.body!))));
updateMainTitle();
}
svoid enableBodyControls(bool b) {
var panels = ll(scpVisionConfig, scpWheelsConfig);
for (var c : concatMap(panel -> allChildrenOfType JComponent(panel), panels))
if (isInstanceOfAny(c, JCheckBox.class, JRadioButton.class, JTextField.class))
setEnabled(c, b);
// Modify body button is enabled iff controls are not enabled
for (var c : concatMap(panel -> allChildrenOfType ModifyBodyButton(panel), panels))
setEnabled(c, !b);
}
svoid showHelp() {
S text = loadSnippet(#1031105);
S heading = firstLine(text);
trim(dropFirstLine(text));
showCenterFrame(swingScale(650), swingScale(500), heading, makeUneditableWithTextColor(Color.black, wordWrapTextArea(text)));
}
// run in Swing thread
svoid showHistory {
Font ttFont = typeWriterFont(12), helpFont = sansSerifFont(13);
if (historyFrame == null)
historyFrame = getFrame(showCenterFrame(scalePt(600, 350, swingFontScale()),
"Stimulus/Response, Percept/Action History",
withMargin(centerAndSouthWithMargin(spacing,
centerAndSouthWithMargin(
historyTextArea1,
westAndCenterWithMargin(spacing, setFont(ttFont, topAlignLabel(jMultiLineLabel(
linesLL("Step #", "Percept", "Binon #", "", "Expect", "Binon #",
"", "Action", "Binon #", "", "Action", "Binon #", "")))),
setFont(ttFont, historyTextArea2))
),
centerAndEastWithMargin(
setFont(helpFont, jMultiLineLabel(historyHelp)),
jvstackWithSpacing(
jButton("See World", r showWorld),
jButton("See Memory", r showMemory))
)))));
else
frameToFront(historyFrame);
}
// run in Swing thread
svoid showMemory {
Font ttFont = typeWriterFont(12), helpFont = sansSerifFont(13);
if (memoryFrame == null)
memoryFrame = getFrame(showCenterFrame(scalePt(600, 350, swingFontScale()),
"Smarty's Memory",
jvsplit(0.5, 100,
centerAndEastWithMargins(
northAndCenterWithMargin(
setFont(ttFont, jLabel("bla bla bla")),
setFont(ttFont, memoryTextArea)),
jvstackWithSpacing(
jButton("See World", r showWorld),
jButton("See History", r showHistory))
),
jTextArea(),
)
));
else
frameToFront(memoryFrame);
}
svoid showWorld {
frameToFront(mainFrame);
}
static JRadioButton visionModeRadioButton(SmartyBody body, ButtonGroup buttonGroup, S visionMode, S text) {
var rb = jradiobutton(buttonGroup, text, eq(body.visionMode, visionMode));
onChange(rb, r { if (isChecked(rb)) { cset(body, +visionMode); body.userCausedChange(); } });
ret rb;
}
sclass ModifyBodyButton extends JButton {
*() {
super("Modify Smarty's Body");
main addActionListener(this, r modifyBody);
}
}
// enable the controls to edit the body, after confirmation
svoid modifyBody {
if (state.body->used) {
if (!confirmOKCancel("Modifying Smarty's body will reset its state. Do you wish to continue?"))
ret;
cset(state.body, used := false);
}
enableBodyControls(true);
}
static JComponent bodyNamePanel(SmartyBody body) {
SimpleLiveValue lv = conceptFieldLiveValue name(body);
lv.onChange(r { body.userCausedChange() });
ret hstackWithSpacing(
jMinWidth(swingScale(250), withLabel("Body name:", jLiveValueTextField_bothWays(lv))),
swing(() -> new ModifyBodyButton));
}
static JComponent visionConfigPanel(SmartyBody body) {
var buttonGroup = buttonGroup();
ret northAndCenterWithMargins(spacing,
bodyNamePanel(body),
westAndCenterWithMargin(spacing,
jCenteredSection("Camera",
withLeftMargin(spacing, jvstackWithSpacing(spacing,
itemPlus(jlabel("Select the camera directions"),
map(CameraDirection.all, direction -> {
var cb = jCheckBox(direction, body.cameraDirections.contains(direction));
onChange(cb, r { addOrRemove(body.cameraDirections, direction, isChecked(cb)); body.userCausedChange(); });
ret cb;
}))))),
jCenteredSection("Vision mode",
jvstack(
visionModeRadioButton(body, buttonGroup, VisionMode.nextSquare,
"Looking at the next square (symbolic values = letter in square)"),
withLeftMargin(spacing*2, jMultiLineLabel(unindentMLS(replaceSymbols([[
Square locations are identified with a letter.
Looking down provides the letter of the current square.
Looking in other directions provides the letter in the next square
depending on the direction Smarty is facing.
If it is a wall then the symbolic stimulus is a $wallSymbol
]])))),
verticalStrut(20),
visionModeRadioButton(body, buttonGroup, VisionMode.distanceToWall,
"Distance to wall (magnitude values = number of squares)"),
withLeftMargin(spacing*2, jMultiLineLabel(unindentMLS([[
Looking at the distance to the nearest wall will provide the
number of squares from the current position to the wall in
the direction the camera is facing. A wall next to the robot
is one square away. Looking down will always return 1.
]]))),
verticalStrut(20),
visionModeRadioButton(body, buttonGroup, VisionMode.wallOrNot,
replaceSymbols("Wall or not (symbolic values = $wallSymbol for a wall and $noWallSymbol for no wall)")),
withLeftMargin(spacing*2, jMultiLineLabel(unindentMLS([[
Looking at the next square will either see a wall or an empty square
]]))),
))));
}
svoid showVisionConfig(SmartyBody body) {
showPackedFrame("Configure Smarty's Vision",
visionConfigPanel(body));
}
static JCheckBox wheelsConfigCheckBox(SmartyBody body, S symbol, S text) {
var cb = jCheckBox(text, body.wheels.contains(symbol));
onChange(cb, r { addOrRemove(body.wheels, symbol, isChecked(cb)); body.userCausedChange(); });
ret cb;
}
static JComponent wheelsConfigPanel(SmartyBody body) {
ret northAndCenterWithMargins(spacing,
bodyNamePanel(body),
vstackWithSpacing(spacing,
westAndCenterWithMargin(spacing,
jCenteredSection("Movement",
withLeftMargin(spacing, jvstackWithSpacing(
jlabel("Select the wheel motions"),
wheelsConfigCheckBox(body, "MoveForward", "Forward = f"),
wheelsConfigCheckBox(body, "MoveLeft", "Left = l"),
wheelsConfigCheckBox(body, "MoveRight", "Right = r"),
wheelsConfigCheckBox(body, "MoveBackward", "Backward = b"),
))),
jCenteredSection("Help", withLeftMargin(jMultiLineLabel(unindentMLS([[
Motion in any direction will move one square.
If there is a wall in the way it will not move. A "-" indicates no motion.
The direction moved depends on the direction Smarty is facing.
Smarty will appear as a if it cannot turn. It will then always be
facing North (up) so moving right will move to the East (right).
]]))))),
westAndCenterWithMargin(spacing,
jCenteredSection("Turning",
withLeftMargin(spacing, vstackWithSpacing(
wheelsConfigCheckBox(body, "TurnRight", "Turn to the right = Rotate clockwise 90 degrees = X"),
wheelsConfigCheckBox(body, "TurnLeft", "Turn to the left = Rotate anti-clockwise 90 degrees = X"),
wheelsConfigCheckBox(body, "TurnAround", "Turn around = Rotate 180 degrees = X"),
))),
jCenteredSection("Help", withLeftMargin(jMultiLineLabel(unindentMLS([[
Turning will stay on the same square. If Smarty is able to turn then it will appear as < , > , ^ or v to indicate the direction it is facing.
]]))))),
jCenteredSection("Sensing",
withLeftMargin(spacing, wheelsConfigCheckBox(body, "AddAWheelSensor", "Add a wheel sensor to detect if it moved or failed because it was up against a wall"))
)
));
}
svoid showWheelsConfig(SmartyBody body) {
var buttonGroup = buttonGroup();
showPackedFrame("Configure Smarty's Wheels",
wheelsConfigPanel(body));
}
svoid showSmartyConfig {
showPackedFrameMinWidth(400, "Design or Select a body for Smarty",
withMargin(centeredButtons(
"Vision", r { showVisionConfig(state.body!) },
"Wheels", r { showWheelsConfig(state.body!) },
))
);
}
// e.g. $wallSymbol and $noWallSymbol
sS replaceSymbols(S s) {
ret replaceDollarVars(s, +wallSymbol, +noWallSymbol);
}
svoid saveWorld(File f) {
new LS lines;
lines.add(" " + state.gridRows);
for (int y = 0; y < state.gridRows; y++)
for (int x = 0; x < state.gridCols; x++) {
JCell cell = getCell(x, y);
lines.add(state.smartyX == x && state.smartyY == y ? "A" : cell.obstacle() ? "#" : " ");
}
saveTextFile(f, lines(lines));
infoBox("World saved: " + fileName(f));
cset(state, worldName := fileNameWithoutExtension(f));
addRecentWorldFile(f);
}
svoid addRecentWorldFile(File f) swing {
removeAndPut(state.recentWorldFiles, f, true);
state.change();
makeMenus();
}
svoid addRecentBodyFile(File f) swing {
removeAndPut(state.recentBodyFiles, f, true);
state.change();
makeMenus();
}
svoid loadWorld(File f) {
pcall-messagebox {
LS lines = linesFromFile_list(f);
int i = 0;
int gridRows = parseInt(trim(lines.get(i++)));
if (gridRows < 1 || gridRows > maxWorldSize) fail("Bad world size: " + gridRows);
setWorldSize(gridRows);
for y to gridRows:
for x to gridRows: {
S line = lines.get(i++);
JCell cell = getCell(x, y);
if (eq(line, "#"))
cell.setObstacle(true);
else if (eq(line, "A"))
state.moveSmarty(x, y);
}
rearrangeLetters();
repaint(mainGrid);
cset(state, worldName := fileNameWithoutExtension(f));
cset(state, worldChanged := false);
infoBox("World loaded: " + fileName(f));
addRecentWorldFile(f);
}
}
svoid saveWorldDialog(Runnable whenDone default null) {
swing {
JFileChooser fileChooser = new(mainDir());
fileChooser.setFileFilter(new FileNameExtensionFilter("Smarty World files (*.\*worldFileExtension*/)", worldFileExtension));
if (fileChooser.showSaveDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
File f = defaultExtension(worldFileExtension, fileChooser.getSelectedFile());
saveWorld(f);
infoBox("World saved as " + f.getName());
} else
messageBox("World NOT saved");
callF(whenDone);
}
}
svoid withWorldSave(Runnable r) {
if (state.worldChanged) {
int result = swingShowConfirmDialog(mainFrame,
"World has changed! - Save it?", "Smarty",
JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION) {
saveWorldDialog(r);
ret;
} else if (result == JOptionPane.CANCEL_OPTION)
ret;
}
r.run();
}
svoid loadWorldDialog {
withWorldSave(r loadWorldDialogWithoutConfirmation);
}
svoid loadWorldDialogWithoutConfirmation swing {
JFileChooser fileChooser = new(mainDir());
fileChooser.setFileFilter(new FileNameExtensionFilter("Smarty World files (*.\*worldFileExtension*/)", worldFileExtension));
if (fileChooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION)
loadWorld(fileChooser.getSelectedFile());
}
svoid newWorld {
withWorldSave(r newWorldWithoutConfirmation);
}
svoid newWorldWithoutConfirmation(int size default defaultWorldSize) {
setWorldSize(size);
cset(state, worldName := "Empty", worldChanged := false);
updateMainTitle();
}
static File mainDir() {
ret mkdirs(userDir("Adaptron/Smarty"));
}
svoid saveBody(File f) {
S[] Body = new[22];
SmartyBody b = state.body!;
bodyToArray(b, Body);
saveTextFile(f, lines(dropFirst(Body)));
cset(b, changed := false);
addRecentBodyFile(f);
}
svoid bodyToArray(SmartyBody b, S[] Body) {
Body[1] = escapeNewLines(b.name);
// TODO: remaining values from AI?
Body[2] = "1"; //Vision.Value = 1 - checked
Body[3] = "0"; //Touch.Value
Body[4] = b.wheelsFlag("AddAWheelSensor");
Body[5] = "1"; //Wheels.Value
Body[6] = "0"; //Arms.Value
Body[7] = b.cameraDirections.contains(CameraDirection.down) ? "1" : "0"; //VisionConfig.VisionDown
Body[8] = b.cameraDirections.contains(CameraDirection.left) ? "1" : "0"; //VisionConfig.VisionLeft
Body[9] = b.cameraDirections.contains(CameraDirection.right) ? "1" : "0"; //VisionConfig.VisionRight
Body[10] = b.cameraDirections.contains(CameraDirection.inFront) ? "1" : "0"; //VisionConfig.VisionInFront
Body[11] = b.cameraDirections.contains(CameraDirection.behind) ? "1" : "0"; //VisionConfig.VisionBehind
Body[12] = eq(b.visionMode, VisionMode.nextSquare) ? "True" : "False"; //VisionConfig.VisionSymbolicOrMagnitude(0)
Body[13] = eq(b.visionMode, VisionMode.distanceToWall) ? "True" : "False"; //VisionConfig.VisionSymbolicOrMagnitude(1)
Body[14] = b.wheelsFlag("MoveForward");
Body[15] = b.wheelsFlag("MoveLeft");
Body[16] = b.wheelsFlag("MoveRight");
Body[17] = b.wheelsFlag("MoveBackward");
Body[18] = b.wheelsFlag("TurnRight");
Body[19] = b.wheelsFlag("TurnLeft");
Body[20] = b.wheelsFlag("TurnAround");
Body[21] = eq(b.visionMode, VisionMode.wallOrNot) ? "True" : "False"; //VisionConfig.VisionSymbolicOrMagnitude(2)
}
svoid withBodySave(Runnable r) {
if (state.body->changed) {
int result = swingShowConfirmDialog(mainFrame,
"Body has changed! - Save it?", "Smarty",
JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION) {
saveBodyDialog(r);
ret;
} else if (result == JOptionPane.CANCEL_OPTION)
ret;
}
r.run();
}
svoid newBody {
withBodySave(r newBodyWithoutConfirmation);
}
svoid newBodyWithoutConfirmation {
cdelete(state.body!);
cset(state, body := cnew(SmartyBody));
updateTabs();
}
svoid loadBody(File f) {
pcall-messagebox {
LS lines = linesFromFile_list(f);
S[] Body = asStringArray(itemPlusList("", lines));
newBody();
var b = state.body!;
// TODO: remaining values
cset(b, name := Body[1]);
if (eq(Body[4], "1")) b.wheels.add("AddAWheelSensor");
if (eq(Body[7], "1")) b.cameraDirections.add(CameraDirection.down);
if (eq(Body[8], "1")) b.cameraDirections.add(CameraDirection.left);
if (eq(Body[9], "1")) b.cameraDirections.add(CameraDirection.right);
if (eq(Body[10], "1")) b.cameraDirections.add(CameraDirection.inFront);
if (eq(Body[11], "1")) b.cameraDirections.add(CameraDirection.behind);
if (eq(Body[12], "True")) b.visionMode = VisionMode.nextSquare;
if (eq(Body[13], "True")) b.visionMode = VisionMode.distanceToWall;
if (eq(Body[14], "1")) b.wheels.add("MoveForward");
if (eq(Body[15], "1")) b.wheels.add("MoveLeft");
if (eq(Body[16], "1")) b.wheels.add("MoveRight");
if (eq(Body[17], "1")) b.wheels.add("MoveBackward");
if (eq(Body[18], "1")) b.wheels.add("TurnRight");
if (eq(Body[19], "1")) b.wheels.add("TurnLeft");
if (eq(Body[20], "1")) b.wheels.add("TurnAround");
if (eq(Body[21], "True")) b.visionMode = VisionMode.wallOrNot;
cset(b, changed := false);
b.change();
updateTabs();
infoBox("Body loaded: " + fileName(f));
addRecentBodyFile(f);
}
}
svoid saveBodyDialog(Runnable whenDone default null) {
swing {
new JFileChooser fileChooser;
fileChooser.setSelectedFile(newFile(mainDir(), sanitizeFileName(state.body->name)));
fileChooser.setFileFilter(new FileNameExtensionFilter("Smarty Body files (*.\*bodyFileExtension*/)", bodyFileExtension));
if (fileChooser.showSaveDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
File f = defaultExtension(bodyFileExtension, fileChooser.getSelectedFile());
saveBody(f);
infoBox("Body saved as " + f.getName());
}
callF(whenDone);
}
}
svoid loadBodyDialog {
withBodySave(r loadBodyDialogWithoutConfirmation);
}
svoid loadBodyDialogWithoutConfirmation swing {
JFileChooser fileChooser = new(mainDir());
fileChooser.setFileFilter(new FileNameExtensionFilter("Smarty Body files (*.\*bodyFileExtension*/)", bodyFileExtension));
if (fileChooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION)
loadBody(fileChooser.getSelectedFile());
}
sS makeMainTitle() {
ret "Smarty's World - World= " + state.worldName + ", Body= " + state.body->name
+ ", Run done on " + simpleDateFormat_defaultTZ_now("MM-dd-YYYY") + " (mm-dd-yyyy) "
+ simpleDateFormat_defaultTZ_now("HH:mm:ss");
}
svoid updateMainTitle {
frameTitle(mainFrame, makeMainTitle());
}
// Make the dynamic menus
svoid makeMenus {
addMenu(mainFrame, "Worlds",
"New... (Ctrl+N)", r newWorld,
"Retrieve... (Ctrl+R)", r loadWorldDialog,
"Save... (Ctrl+S)", r saveWorldDialog,
"---",
mapWithIndexStartingAt1(reversed(keys(state.recentWorldFiles)), (idx, f)
-> jMenuItem(idx + " " + fileName(f), r { withWorldSave(r { loadWorld(f) }) })),
empty(state.recentWorldFiles) ? null : "---",
"Exit", rThread killVM);
addMenu(mainFrame, "Bodies",
"New... (Ctrl+N)", r newBody,
"Retrieve... (Ctrl+R)", r loadBodyDialog,
"Save... (Ctrl+S)", r saveBodyDialog,
"---",
mapWithIndexStartingAt1(reversed(keys(state.recentBodyFiles)), (idx, f)
-> jMenuItem(idx + " " + fileName(f), r { withBodySave(r { loadBody(f) }) })),
empty(state.recentBodyFiles) ? null : "---",
"Exit", rThread killVM);
}
svoid goCmd { smartyQ.add(r goCmd_impl); }
svoid goCmd_impl {
pcall-messagebox {
evalWithTimeout(10.0, r {
print("goCmd");
if (!state.body->used) {
finishBodySetup();
cset(state.body, used := true);
}
smarty.bodies.BodyFunction2();
});
}
}
sclass TheWorld extends Smarty.TheWorld {
void moveRelative(int x, int y) {
x += state.smartyX; y += state.smartyY;
if (!inRange(x, 0, state.gridCols) || !inRange(y, 0, state.gridRows)
|| getCell(x, y).obstacle())
smarty.Motion = smarty.NoMove;
else {
smarty.Motion = "Y";
state.moveSmarty(x, y);
}
}
public void MoveWest() {
moveRelative(-1, 0);
}
public void MoveSouth() {
moveRelative(0, 1);
}
public void MoveEast() {
moveRelative(1, 0);
}
public void MoveNorth() {
moveRelative(0, -1);
}
public void DisplayStimuliAndResponse(int[][][] inputValues, char resp) {
new L leftStack;
new L rightStack;
for (int Sens = 1; Sens <= smarty.NumSenses; Sens++) {
int NumSensors = smarty.Senses[Sens][smarty.NumberOfSensors];
if (NumSensors == 0) continue;
if (NumSensors != 1) warn("More than one sensor in sense");
S label = smarty.Sense[Sens] + ":";
var inputValue = inputValues[Sens][smarty.Valu][smarty.Fired];
S text;
if (smarty.Senses[Sens][smarty.SymbolicOrMagnitude] == smarty.Magnitude)
text = str(charPlus(inputValue , '0'));
else
text = str((char) inputValue); // A, B, C etc
leftStack.add(withLabel(label, jlabel(text)));
}
for (int Devs = 1; Devs <= smarty.NumDevices; Devs++) {
S label = smarty.Device[Devs] + ":";
// TODO: where is text set?
rightStack.add(withLabel(label, jlabel()));
}
scpStimuliAndResponse.set(jhgridWithSpacing(
vstackWithSpacing(leftStack),
vstackWithSpacing(rightStack)));
}
public void Update_View() { // called by World.LookInside_Click() to SeeHistory and Bodies.BodyFunction2()
// refreshes all the subwindows
historyDisplay();
dumpLTM();
}
} // end of TheWorld
svoid initSmarty {
smarty.World = new TheWorld;
smarty.Initialize_Adaptron();
}
svoid finishBodySetup {
print("Finishing body setup");
//Smarty.world.ResetSmartyLocation();
smarty.Reset_Adaptron(); // set all memory, S-List, Habit stack
setText(historyTextArea1, "");
setText(historyTextArea2, "");
setText(memoryTextArea, "");
bodyToArray(state.body!, smarty.BodySetting);
pnl("BodySetting", smarty.BodySetting);
/*if (Vision.Value = 1)*/ smarty.SetupVision();
//if (Touch.Value = 1) smarty.SetupTouch();
/*if (Wheels.Value = 1)*/ smarty.SetupWheels();
//if (Arms.Value = 1) smarty.SetupArms();
SetupStimulusResponseDisplay(); //Setup display of stimuli at bottom of World screen
}
svoid SetupStimulusResponseDisplay {}
// from Adapt.frm / HISTORYDISPLAY
svoid historyDisplay {
new LS lines;
StringBuilder[] ILines$ = new[10+1];
int GroupSize = 250; // After 250 events the IO.Text area wraps the lines
new StringBuilder NumberLine$;
new StringBuilder OLine1$;
for (int Group = 0; Group <= (smarty.LIN - 1) / GroupSize; Group++) {
int EndLIN = min(GroupSize * Group + GroupSize, smarty.LIN);
for (int E = GroupSize * Group + 1; E <= EndLIN; E++) {
if (E == GroupSize * Group + 1) { // If it is the 1st position / event in the line then
NumberLine$ = new StringBuilder("Step # : ");
for (int Sn = 1; Sn <= smarty.NumSenses; Sn++) // Add labels to start of lines
ILines$[Sn] = new StringBuilder(takeFirst(smarty.Sense[Sn] + ": ", 9)); // The name of the sense
OLine1$ = new StringBuilder(takeFirst(smarty.Device[1] + ": ", 9)); // The name of the action device
}
S E_str = " " + E; // visual-basic style int-to-string!
NumberLine$.append(E_str); // the event number
int Wdth = l(E_str); // the space taken up by the event number
for (int Sn = 1; Sn <= smarty.NumSenses; Sn++)
ILines$[Sn].append(takeLast(" " + smarty.INPUTS[E][Sn], Wdth));
OLine1$.append(takeLast(" " + smarty.OUTPUTS[E][1], Wdth));
}
lines.add(str(NumberLine$));
for (int Sn = 1; Sn <= smarty.NumSenses; Sn++)
lines.add(str(ILines$[Sn]));
lines.add(str(OLine1$));
lines.add("");
}
setText(historyTextArea1, rtrim(lines(lines)));
} // end of historyDisplay
svoid dumpLTM { //Called by Update_View
String MemValT = null;
int[] MemSize = new[2000 + 1];
String Sen = null;
String Att = null;
String Pe = null;
String Ob = null;
Object BinTyp = null;
boolean DisplayIt = false; //a Spac$,
//'-------------------- Long Term Memory (LTM) - Monitoring Info. -------------------------
// 'For Display purposes only by Adapt.DUMPLTM in Adapt.LTMem
// 'Long term memory contains a list of the stimuli that have been paid attention to.
// 'It stores Perceptual sequences as a pair of sequential memory locations.
//
// Public LTMEMORY&(1 To 2000, 1 To 6)
// '1st index is StoreAt cycle number
// '2nd index is what type of information is in the LTM
//
// '---- LTMEMORY() 2nd index values - type of information in LTMEMORY()
// Public LtmPerceptTyp '1 Percept binon type
// Public LtmPerceptBin '2 Percept binon
// Public LtmESType '3 Type of ES Binon - may be an SS
// Public LtmESActBin '4 ES Actbin
// Public LtmARType '5 Type of AR Binon - may be an RR
// Public LtmARActBin '6 AR ActBin
// Public LtmActionTyp '7 Action binon type
// Public LtmActionBin '8 Action binon
for (var I = 1; I <= smarty.StoreAt; I++) //find the widest binon # for all the StoreAt positions
{
MemSize[I] = intMax(
l(str(I))+1,
3,
l(vbToStr(smarty.LTMEMORY[I][smarty.LtmPerceptBin])),
l(vbToStr(smarty.LTMEMORY[I][smarty.LtmESActBin])),
l(vbToStr(smarty.LTMEMORY[I][smarty.LtmARActBin])),
l(vbToStr(smarty.LTMEMORY[I][smarty.LtmActionBin])));
}
new StringBuffer text;
int GroupSize = 250;
var tempVar = (smarty.StoreAt - 1) / GroupSize;
for (int Group = 0; Group <= (smarty.StoreAt - 1) / GroupSize; Group++) {
int EndLIN = GroupSize * Group + GroupSize; //Only put up the available values
if (EndLIN > smarty.StoreAt) EndLIN = smarty.StoreAt;
new StringBuilder MemLine;
for (int E = GroupSize * Group + 1; E <= EndLIN; E++) //For each event in LTM display the event number
MemLine.append(pad(MemSize[E], str(E)));
text.append(MemLine + "\r\n");
//------Percepts(.., Fired) Type
MemLine = new StringBuilder;
for (int E = GroupSize * Group + 1; E <= EndLIN; E++) //For each event in LTM
{
Att = smarty.BinonTypeName(smarty.LTMEMORY[E][smarty.LtmPerceptTyp], smarty.BinAbbreviation); //Att$ = Str$(STM(1, BinTp, Current))
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n");
//------Percepts(.., Fired) Binon
MemLine = new StringBuilder; //Trigger STIMULUS intensity
for (int E = GroupSize * Group + 1; E <= EndLIN; E++) //For each event in LTM
{
Att = str(smarty.LTMEMORY[E][smarty.LtmPerceptBin]); //Att$ = Str$(STM(1, BinId, Current))
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n\r\n");
//------ES ActBin type
MemLine = new StringBuilder;
for (int E = GroupSize * Group + 1; E <= EndLIN; E++) //For each event in LTM
{
Att = smarty.AESR(smarty.LTMEMORY[E][smarty.LtmESActBin]);
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n");
//------ LTMEMORY ActBin Object binon
MemLine = new StringBuilder;
for (int E = GroupSize * Group + 1; E <= EndLIN; E++) //For each event in LTM
{
Att = String.valueOf(smarty.LTMEMORY[E][smarty.LtmESActBin]);
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n\r\n");
//------AR ActBin type
MemLine = new StringBuilder;
for (int E = GroupSize * Group + 1; E <= EndLIN; E++) //For each event in LTM
{
Att = AESR(smarty.LTMEMORY[E][smarty.LtmARActBin]);
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n");
//------ LTMEMORY ActBin Object binon
MemLine = new StringBuilder;
for (int E = GroupSize * Group + 1; E <= EndLIN; E++) //For each event in LTM
{
Att = String.valueOf(LTMEMORY[E][smarty.LtmARActBin]);
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n\r\n");
//------Actions(.., Fired) Type
MemLine = new StringBuilder;
for (int E = GroupSize * Group + 1; E <= EndLIN; E++) //For each event in LTM
{
Att = smarty.BinonTypeName[smarty.LTMEMORY[E][smarty.LtmActionTyp]][smarty.BinAbbreviation];
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n");
//------Actions(.., Fired) Binon
MemLine = new StringBuilder;
for (int E = GroupSize * Group + 1; E <= EndLIN; E++) //For each event in LTM
{
Att = String.valueOf(smarty.LTMEMORY[E][smarty.LtmActionBin]);
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n\r\n");
}
setText(memoryTextArea, str(text));
} //End of dumpLTM
svoid uiZoom(double percent) {
cset(state, fontScale := toFloat(percent/100));
updateFontScale(state.fontScale);
}
svoid updateFontScale(float scale) {
swingFontScale(scale);
spacing = iround(defaultSpacing*scale);
// TODO: restart?
}