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

690
LINES

< > BotCompany Repo | #1031142 // Smarty [reparse test]

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

Download Jar. Uses 1177K of libraries. Click here for Pure Java version (30501L/198K).

!7

set flag Reparse.

import javax.swing.filechooser.*;

!include #1031138 // Smarty AI Include

sbool showHelpOnStart;

static int spacing = 20;
static JFrame mainFrame;
static LL<JCell> gridComponents;
static JComponent mainGrid;
static JCheckBoxMenuItem miShowLocations;
static SingleComponentPanel scpMainGrid, scpVisionConfig, scpWheelsConfig, scpCurrentSmarty;
static JFrame historyFrame, memoryFrame;
static JSpinner worldSizeSpinner;

static new Smarty smarty; // AI instance

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 = basicUnicodeSmiley();
static int smartyFontSize = 40;

sS windowsFontID = #1400468;
sS frameIconID = #1102983;

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";
  new Set<S> cameraDirections;
  S visionMode = VisionMode.nextSquare; // see VisionMode
  new Set<S> wheels;

  // for saving
  S wheelsFlag(S flag) { ret wheels.contains(flag) ? "1" : "0"; }
}

concept State {
  float fontScale = 1.25f;
  S worldName = "empty";
  int gridRows = defaultWorldSize, gridCols = defaultWorldSize; // actually these are always identical, could merge into one
  bool showLocations = true;
  int smartyX, smartyY;
  Rect selection = rect(1, 1, 1, 1);
  Pt cursorDirection = pt(1, 0);
  new BitSet obstacles;

  new Ref<SmartyBody> body;
  
  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);
    cset(this, smartyX := selection.x, smartyY := selection.y);
    moveCursor();
  }
} // 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);
      drawCenteredText(g, smartyUnicode, 0, 0, w, h, Color.black);
    }
  }

  int index() { ret y*state.gridCols+x; }
  bool obstacle() { ret main contains(state.obstacles, index()); }
  void setObstacle(bool b) {
    setBit(state.obstacles, index(), b);
    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();
}

svoid setWorldSize(int size) {
  state.obstacles.clear();
  state.gridCols = state.gridRows = size;
  setSpinnerValue(worldSizeSpinner, size);
  state.selection = rect(1, 1);
  state.smartyX = state.smartyY = 0;
  state.change();
  makeMainGrid();
}

p {
  autoRestart(2.0);
  setProgramDir(print("Using directory: ", mainDir()));
  db();
  uniq(SmartyBody); // make at least one instance
  state = uniq(State);
  if (!state.body.has()) cset(state, body := conceptWhere(SmartyBody)); // default body
  
  jtattoo_mcWin();
  state.fontScale = 1.5f; // XXX
  //set swingFontScale_debug;
  swingFontScale(state.fontScale);

  loadLibrary(windowsFontID);
  defaultFrameIcon(frameIconID);
  mainFrame = showFrame("Smarty");
  addMenu(mainFrame, "Worlds",
    "New... (Ctrl+N)", r newWorld,
    "Retrieve... (Ctrl+R)", r loadWorldDialog,
    "Save... (Ctrl+S)", r saveWorldDialog,
    "---",
    "Exit", rThread killVM);
    
  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, "Bodies",
    "New... (Ctrl+N)", r newBody,
    "Retrieve... (Ctrl+R)", r loadBodyDialog,
    "Save... (Ctrl+S)", r saveBodyDialog,
    "---",
    "Exit", rThread killVM);
    
  addMenu(mainFrame, "View",
    miShowLocations = jCheckBoxMenuItem("Locations (Ctrl+L)", state.showLocations, b -> {
       cset(state, showLocations := b);
       repaint(mainGrid);
     }));

  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)
      setWorldSize(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"),
        jButton("See History", r showHistory),
        jbutton("Reset"),
        jbutton("See Memory", r showMemory),
        jbutton("EXIT", rThread killVM),
        ))
  );

  scpMainGrid = singleComponentPanel();
  makeMainGrid();

  var mainPanel = westAndCenterWithMargins(spacing,
    jvstackWithSpacing(spacing, jFixedSize(500, scpMainGrid),
      jhgridWithSpacing(spacing, jlabel("VisionD:"), jlabel("Wheels:"))
    ),
    controlArea);

  if (showTabs) {
    scpVisionConfig = singleComponentPanel();
    scpWheelsConfig = singleComponentPanel();
    updateTabs();
    setFrameContents(mainFrame, jtabs(
      "Smarty", mainPanel,
      "Vision", scpVisionConfig,
      "Wheels", scpWheelsConfig));
  } else
    setFrameContents(mainFrame, mainPanel);
  
  centerPackFrame(mainFrame);

  if (showHelpOnStart) showHelp();
  //hideConsole();
}

svoid updateTabs {
  scpVisionConfig.setComponent(visionConfigPanel(state.body!));
  scpWheelsConfig.setComponent(wheelsConfigPanel(state.body!));
  scpCurrentSmarty.setComponent(disableTextField(jLiveValueTextField(conceptFieldLiveValue name(state.body!))));
}

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,
        jvsplit(0.5, 100,
          jTextArea(),
          westAndCenterWithMargin(spacing, setFont(ttFont, topAlignLabel(jMultiLineLabel(
            linesLL("Step #", "Percept", "Binon #", "", "Expect", "Binon #",
              "", "Action", "Binon #", "", "Action", "Binon #", "")))),
            setFont(ttFont, jTextArea()))
        ),
        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, jTextArea())),
            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); });
  ret rb;
}

static JComponent bodyNamePanel(SmartyBody body) {
  ret westAndCenter(
    jMinWidth(swingScale(250), withLabel("Body name:", jLiveValueTextField_bothWays(conceptFieldLiveValue name(body)))),
    jpanel());
}

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.change(); });
              ret cb;
            }))))),
            
      jCenteredSection("Vision mode",
        jvstackWithSpacing(spacing,
          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
          ]])))),
  
          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.
          ]]))),
          
          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.change(); });
  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));
}

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"))
          cset(state, smartyX := x, smartyY := y);
      }
    rearrangeLetters();
    repaint(mainGrid);
    cset(state, worldName := fileNameWithoutExtension(f));
    infoBox("World loaded: " + fileName(f));
  }
}

svoid saveWorldDialog 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());
  }
}

svoid loadWorldDialog 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 {
  setWorldSize(defaultWorldSize);
  cset(state, worldName := "empty");
}

static File mainDir() {
  ret mkdirs(userDir("Adaptron/Smarty"));
}

svoid saveBody(File f) {
  S[] Body = new[22];
  SmartyBody b = state.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)

  saveTextFile(f, lines(dropFirst(Body)));
}

svoid newBody {
  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(state.body, 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;
    b.change();
    updateTabs();
    infoBox("Body loaded: " + fileName(f));
  }
}

svoid saveBodyDialog 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());
  }
}

svoid loadBodyDialog swing {
  JFileChooser fileChooser = new(mainDir());
  fileChooser.setFileFilter(new FileNameExtensionFilter("Smarty Body files (*.\*bodyFileExtension*/)", bodyFileExtension));
        
  if (fileChooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION)
    loadBody(fileChooser.getSelectedFile());
}

Author comment

Began life as a copy of #1031104

download  show line numbers  debug dex  old transpilations   

Travelled to 6 computer(s): bhatertpkbcr, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, vouqrxazstgt, ymdyxumozjwr

No comments. add comment

Snippet ID: #1031142
Snippet name: Smarty [reparse test]
Eternal ID of this version: #1031142/5
Text MD5: 24c0bb9a684132061cb5c34160c4fa5c
Transpilation MD5: 76308ca1c7974c4c0c1826bc377d1c44
Author: stefan
Category:
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-05-12 18:55:21
Source code size: 25183 bytes / 690 lines
Pitched / IR pitched: No / No
Views / Downloads: 137 / 562
Version history: 4 change(s)
Referenced in: [show references]