예제 #1
0
 @Override
 public FormulaElement clone() {
   FormulaElement leftChildClone = leftChild == null ? null : leftChild.clone();
   FormulaElement rightChildClone = rightChild == null ? null : rightChild.clone();
   return new FormulaElement(
       type, value == null ? "" : value, null, leftChildClone, rightChildClone);
 }
예제 #2
0
 public FormulaElement getRoot() {
   FormulaElement root = this;
   while (root.getParent() != null) {
     root = root.getParent();
   }
   return root;
 }
예제 #3
0
  private Object interpretFunctionListItem(Object left, Sprite sprite) {
    UserList userList = null;
    if (rightChild.getElementType() == ElementType.USER_LIST) {
      DataContainer dataContainer =
          ProjectManager.getInstance().getSceneToPlay().getDataContainer();
      userList = dataContainer.getUserList(rightChild.getValue(), sprite);
    }

    if (userList == null) {
      return "";
    }

    int index = 0;
    if (left instanceof String) {
      try {
        Double doubleValueOfLeftChild = Double.valueOf((String) left);
        index = doubleValueOfLeftChild.intValue();
      } catch (NumberFormatException numberFormatexception) {
        Log.d(getClass().getSimpleName(), "Couldn't parse String", numberFormatexception);
      }
    } else {
      index = ((Double) left).intValue();
    }

    index--;

    if (index < 0) {
      return "";
    } else if (index >= userList.getList().size()) {
      return "";
    }

    return userList.getList().get(index);
  }
예제 #4
0
 public boolean containsElement(ElementType elementType) {
   if (type.equals(elementType)
       || (leftChild != null && leftChild.containsElement(elementType))
       || (rightChild != null && rightChild.containsElement(elementType))) {
     return true;
   }
   return false;
 }
예제 #5
0
  public List<InternToken> getInternTokenList() {
    List<InternToken> internTokenList = new LinkedList<InternToken>();

    switch (type) {
      case BRACKET:
        internTokenList.add(new InternToken(InternTokenType.BRACKET_OPEN));
        if (rightChild != null) {
          internTokenList.addAll(rightChild.getInternTokenList());
        }
        internTokenList.add(new InternToken(InternTokenType.BRACKET_CLOSE));
        break;
      case OPERATOR:
        if (leftChild != null) {
          internTokenList.addAll(leftChild.getInternTokenList());
        }
        internTokenList.add(new InternToken(InternTokenType.OPERATOR, this.value));
        if (rightChild != null) {
          internTokenList.addAll(rightChild.getInternTokenList());
        }
        break;
      case FUNCTION:
        internTokenList.add(new InternToken(InternTokenType.FUNCTION_NAME, value));
        boolean functionHasParameters = false;
        if (leftChild != null) {
          internTokenList.add(new InternToken(InternTokenType.FUNCTION_PARAMETERS_BRACKET_OPEN));
          functionHasParameters = true;
          internTokenList.addAll(leftChild.getInternTokenList());
        }
        if (rightChild != null) {
          internTokenList.add(new InternToken(InternTokenType.FUNCTION_PARAMETER_DELIMITER));
          internTokenList.addAll(rightChild.getInternTokenList());
        }
        if (functionHasParameters) {
          internTokenList.add(new InternToken(InternTokenType.FUNCTION_PARAMETERS_BRACKET_CLOSE));
        }
        break;
      case USER_VARIABLE:
        internTokenList.add(new InternToken(InternTokenType.USER_VARIABLE, this.value));
        break;
      case USER_LIST:
        internTokenList.add(new InternToken(InternTokenType.USER_LIST, this.value));
        break;
      case NUMBER:
        internTokenList.add(new InternToken(InternTokenType.NUMBER, this.value));
        break;
      case SENSOR:
        internTokenList.add(new InternToken(InternTokenType.SENSOR, this.value));
        break;
      case STRING:
        internTokenList.add(new InternToken(InternTokenType.STRING, value));
        break;
      case COLLISION_FORMULA:
        internTokenList.add(new InternToken(InternTokenType.COLLISION_FORMULA, this.value));
        break;
    }
    return internTokenList;
  }
예제 #6
0
 public void updateVariableReferences(String oldName, String newName) {
   if (leftChild != null) {
     leftChild.updateVariableReferences(oldName, newName);
   }
   if (rightChild != null) {
     rightChild.updateVariableReferences(oldName, newName);
   }
   if (type == ElementType.USER_VARIABLE && value.equals(oldName)) {
     value = newName;
   }
 }
예제 #7
0
 public void getVariableAndListNames(List<String> variables, List<String> lists) {
   if (leftChild != null) {
     leftChild.getVariableAndListNames(variables, lists);
   }
   if (rightChild != null) {
     rightChild.getVariableAndListNames(variables, lists);
   }
   if (type == ElementType.USER_VARIABLE && !variables.contains(value)) {
     variables.add(value);
   }
   if (type == ElementType.USER_LIST && !lists.contains(value)) {
     lists.add(value);
   }
 }
예제 #8
0
  public void replaceElement(FormulaElement current) {
    parent = current.parent;
    leftChild = current.leftChild;
    rightChild = current.rightChild;
    value = current.value;
    type = current.type;

    if (leftChild != null) {
      leftChild.parent = this;
    }
    if (rightChild != null) {
      rightChild.parent = this;
    }
  }
예제 #9
0
  public void replaceWithSubElement(String operator, FormulaElement rightChild) {

    FormulaElement cloneThis =
        new FormulaElement(ElementType.OPERATOR, operator, this.getParent(), this, rightChild);

    cloneThis.parent.rightChild = cloneThis;
  }
예제 #10
0
  private Object interpretFunctionContains(Object right, Sprite sprite) {
    if (leftChild.getElementType() == ElementType.USER_LIST) {
      DataContainer dataContainer =
          ProjectManager.getInstance().getSceneToPlay().getDataContainer();
      UserList userList = dataContainer.getUserList(leftChild.getValue(), sprite);

      if (userList == null) {
        return 0d;
      }

      for (Object userListElement : userList.getList()) {
        if (interpretOperatorEqual(userListElement, right) == 1d) {
          return 1d;
        }
      }
    }

    return 0d;
  }
예제 #11
0
  private Object interpretFunctionLength(Object left, Sprite sprite) {
    if (leftChild == null) {
      return 0d;
    }
    if (leftChild.type == ElementType.NUMBER) {
      return (double) leftChild.value.length();
    }
    if (leftChild.type == ElementType.STRING) {
      return (double) leftChild.value.length();
    }
    if (leftChild.type == ElementType.USER_VARIABLE) {
      return (double) handleLengthUserVariableParameter(sprite);
    }
    if (leftChild.type == ElementType.USER_LIST) {
      DataContainer dataContainer =
          ProjectManager.getInstance().getSceneToPlay().getDataContainer();
      UserList userList = dataContainer.getUserList(leftChild.getValue(), sprite);
      if (userList == null) {
        return 0d;
      }
      if (userList.getList().size() == 0) {
        return 0d;
      }

      Object interpretedList = leftChild.interpretRecursive(sprite);
      if (interpretedList instanceof Double) {
        Double interpretedListDoubleValue = (Double) interpretedList;
        if (interpretedListDoubleValue.isNaN() || interpretedListDoubleValue.isInfinite()) {
          return 0d;
        }
        return (double) (String.valueOf(interpretedListDoubleValue.intValue())).length();
      }
      if (interpretedList instanceof String) {
        String interpretedListStringValue = (String) interpretedList;
        return (double) interpretedListStringValue.length();
      }
    }
    if (left instanceof Double && ((Double) left).isNaN()) {
      return 0d;
    }
    return (double) (String.valueOf(left)).length();
  }
예제 #12
0
 public boolean containsSpriteInCollision(String name) {
   boolean contained = false;
   if (leftChild != null) {
     contained |= leftChild.containsSpriteInCollision(name);
   }
   if (rightChild != null) {
     contained |= rightChild.containsSpriteInCollision(name);
   }
   if (type == ElementType.COLLISION_FORMULA) {
     String collisionTag =
         CatroidApplication.getAppContext().getString(R.string.formula_editor_function_collision);
     String firstSprite = value.substring(0, value.indexOf(collisionTag) - 1);
     String secondSprite =
         value.substring(value.indexOf(collisionTag) + collisionTag.length() + 1, value.length());
     if (firstSprite.equals(name) || secondSprite.equals(name)) {
       contained = true;
     }
   }
   return contained;
 }
예제 #13
0
 public boolean isSingleNumberFormula() {
   if (type == ElementType.OPERATOR) {
     Operators operator = Operators.getOperatorByValue(value);
     return (operator == Operators.MINUS)
         && (leftChild == null)
         && rightChild.isSingleNumberFormula();
   } else if (type == ElementType.NUMBER) {
     return true;
   }
   return false;
 }
예제 #14
0
  public void updateCollisionFormula(String oldName, String newName) {

    if (leftChild != null) {
      leftChild.updateCollisionFormula(oldName, newName);
    }
    if (rightChild != null) {
      rightChild.updateCollisionFormula(oldName, newName);
    }
    if (type == ElementType.COLLISION_FORMULA && value.contains(oldName)) {
      String collisionTag =
          CatroidApplication.getAppContext().getString(R.string.formula_editor_function_collision);
      String firstSprite = value.substring(0, value.indexOf(collisionTag) - 1);
      String secondSprite =
          value.substring(value.indexOf(collisionTag) + collisionTag.length() + 1, value.length());
      if (firstSprite.equals(oldName)) {
        value = newName + " " + collisionTag + " " + secondSprite;
      } else if (secondSprite.equals(oldName)) {
        value = firstSprite + " " + collisionTag + " " + newName;
      }
    }
  }
예제 #15
0
 private String interpretInterpretFunctionJoinParameter(FormulaElement child, Sprite sprite) {
   String parameterInterpretation = "";
   if (child != null) {
     if (child.getElementType() == ElementType.NUMBER) {
       Double number = Double.valueOf((String) child.interpretRecursive(sprite));
       if (number.isNaN()) {
         parameterInterpretation = "";
       } else {
         if (isInteger(number)) {
           parameterInterpretation += number.intValue();
         } else {
           parameterInterpretation += number;
         }
       }
     } else if (child.getElementType() == ElementType.STRING) {
       parameterInterpretation = child.value;
     } else {
       parameterInterpretation += child.interpretRecursive(sprite);
     }
   }
   return parameterInterpretation;
 }
예제 #16
0
  public Object interpretRecursive(Sprite sprite) {

    Object returnValue = 0d;

    switch (type) {
      case BRACKET:
        returnValue = rightChild.interpretRecursive(sprite);
        break;
      case NUMBER:
        returnValue = value;
        break;
      case OPERATOR:
        Operators operator = Operators.getOperatorByValue(value);
        returnValue = interpretOperator(operator, sprite);
        break;
      case FUNCTION:
        Functions function = Functions.getFunctionByValue(value);
        returnValue = interpretFunction(function, sprite);
        break;
      case SENSOR:
        returnValue = interpretSensor(sprite);
        break;
      case USER_VARIABLE:
        returnValue = interpretUserVariable(sprite);
        break;
      case USER_LIST:
        returnValue = interpretUserList(sprite);
        break;
      case STRING:
        returnValue = value;
        break;
      case COLLISION_FORMULA:
        try {
          returnValue = interpretCollision(value);
        } catch (Exception exception) {
          returnValue = 0d;
          Log.e(getClass().getSimpleName(), Log.getStackTraceString(exception));
        }
    }
    return normalizeDegeneratedDoubleValues(returnValue);
  }
예제 #17
0
  private Object interpretOperator(Operators operator, Sprite sprite) {

    if (leftChild != null) { // binary operator
      Object leftObject;
      Object rightObject;
      try {
        leftObject = leftChild.interpretRecursive(sprite);
      } catch (NumberFormatException numberFormatException) {
        leftObject = Double.NaN;
      }

      try {
        rightObject = rightChild.interpretRecursive(sprite);
      } catch (NumberFormatException numberFormatException) {
        rightObject = Double.NaN;
      }

      Double left;
      Double right;

      switch (operator) {
        case PLUS:
          left = interpretOperator(leftObject);
          right = interpretOperator(rightObject);
          return left + right;
        case MINUS:
          left = interpretOperator(leftObject);
          right = interpretOperator(rightObject);
          return left - right;
        case MULT:
          left = interpretOperator(leftObject);
          right = interpretOperator(rightObject);
          return left * right;
        case DIVIDE:
          left = interpretOperator(leftObject);
          right = interpretOperator(rightObject);
          return left / right;
        case POW:
          left = interpretOperator(leftObject);
          right = interpretOperator(rightObject);
          return java.lang.Math.pow(left, right);
        case EQUAL:
          return interpretOperatorEqual(leftObject, rightObject);
        case NOT_EQUAL:
          return interpretOperatorEqual(leftObject, rightObject) == 1d ? 0d : 1d;
        case GREATER_THAN:
          left = interpretOperator(leftObject);
          right = interpretOperator(rightObject);
          return left.compareTo(right) > 0 ? 1d : 0d;
        case GREATER_OR_EQUAL:
          left = interpretOperator(leftObject);
          right = interpretOperator(rightObject);
          return left.compareTo(right) >= 0 ? 1d : 0d;
        case SMALLER_THAN:
          left = interpretOperator(leftObject);
          right = interpretOperator(rightObject);
          return left.compareTo(right) < 0 ? 1d : 0d;
        case SMALLER_OR_EQUAL:
          left = interpretOperator(leftObject);
          right = interpretOperator(rightObject);
          return left.compareTo(right) <= 0 ? 1d : 0d;
        case LOGICAL_AND:
          left = interpretOperator(leftObject);
          right = interpretOperator(rightObject);
          return (left * right) != 0d ? 1d : 0d;
        case LOGICAL_OR:
          left = interpretOperator(leftObject);
          right = interpretOperator(rightObject);
          return left != 0d || right != 0d ? 1d : 0d;
      }
    } else { // unary operators
      Object rightObject;
      try {
        rightObject = rightChild.interpretRecursive(sprite);
      } catch (NumberFormatException numberFormatException) {
        rightObject = Double.NaN;
      }

      switch (operator) {
        case MINUS:
          Double result = interpretOperator(rightObject);
          return -result;
        case LOGICAL_NOT:
          return interpretOperator(rightObject) == 0d ? 1d : 0d;
      }
    }
    return 0d;
  }
예제 #18
0
  private Object interpretFunction(Functions function, Sprite sprite) {
    Object left = null;
    Object right = null;

    Double doubleValueOfLeftChild = null;
    Double doubleValueOfRightChild = null;

    if (leftChild != null) {
      left = leftChild.interpretRecursive(sprite);
      if (left instanceof String) {
        try {
          doubleValueOfLeftChild = Double.valueOf((String) left);
        } catch (NumberFormatException numberFormatException) {
          Log.d(getClass().getSimpleName(), "Couldn't parse String", numberFormatException);
        }
      } else {
        doubleValueOfLeftChild = (Double) left;
      }
    }

    if (rightChild != null) {
      right = rightChild.interpretRecursive(sprite);
      if (right instanceof String) {
        try {
          doubleValueOfRightChild = Double.valueOf((String) right);
        } catch (NumberFormatException numberFormatException) {
          Log.d(getClass().getSimpleName(), "Couldn't parse String", numberFormatException);
        }
      } else {
        doubleValueOfRightChild = (Double) right;
      }
    }

    switch (function) {
      case SIN:
        return doubleValueOfLeftChild == null
            ? 0d
            : java.lang.Math.sin(Math.toRadians(doubleValueOfLeftChild));
      case COS:
        return doubleValueOfLeftChild == null
            ? 0d
            : java.lang.Math.cos(Math.toRadians(doubleValueOfLeftChild));
      case TAN:
        return doubleValueOfLeftChild == null
            ? 0d
            : java.lang.Math.tan(Math.toRadians(doubleValueOfLeftChild));
      case LN:
        return doubleValueOfLeftChild == null ? 0d : java.lang.Math.log(doubleValueOfLeftChild);
      case LOG:
        return doubleValueOfLeftChild == null ? 0d : java.lang.Math.log10(doubleValueOfLeftChild);
      case SQRT:
        return doubleValueOfLeftChild == null ? 0d : java.lang.Math.sqrt(doubleValueOfLeftChild);
      case RAND:
        return (doubleValueOfLeftChild == null || doubleValueOfRightChild == null)
            ? 0d
            : interpretFunctionRand(doubleValueOfLeftChild, doubleValueOfRightChild);
      case ABS:
        return doubleValueOfLeftChild == null ? 0d : java.lang.Math.abs(doubleValueOfLeftChild);
      case ROUND:
        return doubleValueOfLeftChild == null
            ? 0d
            : (double) java.lang.Math.round(doubleValueOfLeftChild);
      case PI:
        return java.lang.Math.PI;
      case MOD:
        return (doubleValueOfLeftChild == null || doubleValueOfRightChild == null)
            ? 0d
            : interpretFunctionMod(doubleValueOfLeftChild, doubleValueOfRightChild);
      case ARCSIN:
        return doubleValueOfLeftChild == null
            ? 0d
            : java.lang.Math.toDegrees(Math.asin(doubleValueOfLeftChild));
      case ARCCOS:
        return doubleValueOfLeftChild == null
            ? 0d
            : java.lang.Math.toDegrees(Math.acos(doubleValueOfLeftChild));
      case ARCTAN:
        return doubleValueOfLeftChild == null
            ? 0d
            : java.lang.Math.toDegrees(Math.atan(doubleValueOfLeftChild));
      case EXP:
        return doubleValueOfLeftChild == null ? 0d : java.lang.Math.exp(doubleValueOfLeftChild);
      case POWER:
        return (doubleValueOfLeftChild == null || doubleValueOfRightChild == null)
            ? 0d
            : java.lang.Math.pow(doubleValueOfLeftChild, doubleValueOfRightChild);
      case FLOOR:
        return doubleValueOfLeftChild == null ? 0d : java.lang.Math.floor(doubleValueOfLeftChild);
      case CEIL:
        return doubleValueOfLeftChild == null ? 0d : java.lang.Math.ceil(doubleValueOfLeftChild);
      case MAX:
        return (doubleValueOfLeftChild == null || doubleValueOfRightChild == null)
            ? 0d
            : java.lang.Math.max(doubleValueOfLeftChild, doubleValueOfRightChild);
      case MIN:
        return (doubleValueOfLeftChild == null || doubleValueOfRightChild == null)
            ? 0d
            : java.lang.Math.min(doubleValueOfLeftChild, doubleValueOfRightChild);
      case TRUE:
        return 1d;
      case FALSE:
        return 0d;
      case LETTER:
        return interpretFunctionLetter(right, left);
      case LENGTH:
        return interpretFunctionLength(left, sprite);
      case JOIN:
        return interpretFunctionJoin(sprite);
      case ARDUINODIGITAL:
        Arduino arduinoDigital =
            ServiceProvider.getService(CatroidService.BLUETOOTH_DEVICE_SERVICE)
                .getDevice(BluetoothDevice.ARDUINO);
        if (arduinoDigital != null && left != null) {
          if (doubleValueOfLeftChild < 0 || doubleValueOfLeftChild > 13) {
            return 0d;
          }
          return arduinoDigital.getDigitalArduinoPin(doubleValueOfLeftChild.intValue());
        }
        break;
      case ARDUINOANALOG:
        Arduino arduinoAnalog =
            ServiceProvider.getService(CatroidService.BLUETOOTH_DEVICE_SERVICE)
                .getDevice(BluetoothDevice.ARDUINO);
        if (arduinoAnalog != null && left != null) {
          if (doubleValueOfLeftChild < 0 || doubleValueOfLeftChild > 5) {
            return 0d;
          }
          return arduinoAnalog.getAnalogArduinoPin(doubleValueOfLeftChild.intValue());
        }
        break;
      case RASPIDIGITAL:
        RPiSocketConnection connection = RaspberryPiService.getInstance().connection;
        int pin = doubleValueOfLeftChild.intValue();
        try {
          return connection.getPin(pin) ? 1d : 0d;
        } catch (Exception e) {
          Log.e(getClass().getSimpleName(), "RPi: exception during getPin: " + e);
        }
        break;
      case MULTI_FINGER_TOUCHED:
        return TouchUtil.isFingerTouching(doubleValueOfLeftChild.intValue()) ? 1d : 0d;
      case MULTI_FINGER_X:
        return Double.valueOf(TouchUtil.getX(doubleValueOfLeftChild.intValue()));
      case MULTI_FINGER_Y:
        return Double.valueOf(TouchUtil.getY(doubleValueOfLeftChild.intValue()));
      case LIST_ITEM:
        return interpretFunctionListItem(left, sprite);
      case CONTAINS:
        return interpretFunctionContains(right, sprite);
      case NUMBER_OF_ITEMS:
        return interpretFunctionNumberOfItems(left, sprite);
    }
    return 0d;
  }
예제 #19
0
  public int getRequiredResources() {
    int resources = Brick.NO_RESOURCES;
    if (leftChild != null) {
      resources |= leftChild.getRequiredResources();
    }
    if (rightChild != null) {
      resources |= rightChild.getRequiredResources();
    }
    if (type == ElementType.FUNCTION) {
      Functions functions = Functions.getFunctionByValue(value);
      switch (functions) {
        case ARDUINOANALOG:
        case ARDUINODIGITAL:
          resources |= Brick.BLUETOOTH_SENSORS_ARDUINO;
          break;
        case RASPIDIGITAL:
          resources |= Brick.SOCKET_RASPI;
          break;
      }
    }
    if (type == ElementType.SENSOR) {
      Sensors sensor = Sensors.getSensorByValue(value);
      switch (sensor) {
        case X_ACCELERATION:
        case Y_ACCELERATION:
        case Z_ACCELERATION:
          resources |= Brick.SENSOR_ACCELERATION;
          break;

        case X_INCLINATION:
        case Y_INCLINATION:
          resources |= Brick.SENSOR_INCLINATION;
          break;

        case COMPASS_DIRECTION:
          resources |= Brick.SENSOR_COMPASS;
          break;

        case LATITUDE:
        case LONGITUDE:
        case LOCATION_ACCURACY:
        case ALTITUDE:
          resources |= Brick.SENSOR_GPS;
          break;

        case FACE_DETECTED:
        case FACE_SIZE:
        case FACE_X_POSITION:
        case FACE_Y_POSITION:
          resources |= Brick.FACE_DETECTION;
          break;

        case NXT_SENSOR_1:
        case NXT_SENSOR_2:
        case NXT_SENSOR_3:
        case NXT_SENSOR_4:
          resources |= Brick.BLUETOOTH_LEGO_NXT;
          break;

        case PHIRO_FRONT_LEFT:
        case PHIRO_FRONT_RIGHT:
        case PHIRO_SIDE_LEFT:
        case PHIRO_SIDE_RIGHT:
        case PHIRO_BOTTOM_LEFT:
        case PHIRO_BOTTOM_RIGHT:
          resources |= Brick.BLUETOOTH_PHIRO;
          break;

        case DRONE_BATTERY_STATUS:
        case DRONE_CAMERA_READY:
        case DRONE_EMERGENCY_STATE:
        case DRONE_FLYING:
        case DRONE_INITIALIZED:
        case DRONE_NUM_FRAMES:
        case DRONE_RECORD_READY:
        case DRONE_RECORDING:
        case DRONE_USB_ACTIVE:
        case DRONE_USB_REMAINING_TIME:
          resources |= Brick.ARDRONE_SUPPORT;
          break;

        case NFC_TAG_ID:
          resources |= Brick.NFC_ADAPTER;
          break;

        default:
      }
    }
    if (type == ElementType.COLLISION_FORMULA) {
      resources |= Brick.COLLISION;
    }
    return resources;
  }