3

This function works, but how It would be possible avoid typing the same for loop for a second variable and somehow use only one. Trying to Don't repeat yuorself method here. Do I need to use an array?

JS:

var app=angular.module('xpCalc', []);
app.controller('xpCalculatorController', function($scope){
$scope.currentLevel=1;
$scope.currentXp=function(){
    var output=0;
    for (var thisLVL=1; thisLVL < $scope.currentLevel; thisLVL++) {
        output += ( Math.floor ( thisLVL + 300 * Math.pow( 2, thisLVL / 7 ) ) / 4 );
    }
    return output;
  };
  $scope.desiredLevel=1;
  $scope.desiredXp=function(){
    var output=0;
    for (var thisLVL=1; thisLVL < $scope.desiredLevel; thisLVL++) {
        output += ( Math.floor ( thisLVL + 300 * Math.pow( 2, thisLVL / 7 ) ) / 4 );
    }
    return output;
  };
});

HTML:

<h2>{{desiredXp()-currentXp()}}</h2> 
2
  • First off, calculate desiredXp()-currentXp() in controller or service. After post result in HTML. Further, use :: bindOnce, for example <h2>{{::result}}</h2>. Anyways its not good practice to use function in HTML, you call it every digest cycle Commented Aug 26, 2016 at 7:57
  • Just implement getXP(level) function. Commented Aug 26, 2016 at 7:57

4 Answers 4

1

Try this.

var app=angular.module('xpCalc', []);
app.controller('xpCalculatorController', function($scope){
$scope.currentLevel=1;
$scope.currentXp=InternalLoop($scope.currentLevel);
$scope.desiredLevel=1;
$scope.desiredXp=InternalLoop($scope.desiredLevel);

function InternalLoop(level){
    var output=0;
    for (var thisLVL=1; thisLVL < level; thisLVL++) {
        output += ( Math.floor ( thisLVL + 300 * Math.pow( 2, thisLVL / 7 ) ) / 4 );
    }
    return output;
  };

});
Sign up to request clarification or add additional context in comments.

1 Comment

You also should add $watch for input variables.
0

You can try this:

var app=angular.module('xpCalc', []);
app.controller('xpCalculatorController', function($scope){
$scope.currentLevel=1;
var getResult = function(level)
{
   var output=0;
   for (var thisLVL=1; thisLVL < level; thisLVL++) {
     output += (Math.floor(thisLVL+300*Math.pow(2,thisLVL/7))/4);
   }
   return output;
}
$scope.currentXp=getResult($scope.currentLevel);
$scope.desiredLevel=1;
$scope.desiredXp=getResult($scope.desiredLevel);
});

Comments

0

Task:

  • xp = sum[floor(i + 300*2^(i/7)) / 4], i = 1..level
  • 4*xp = sum[i] + sum[floor(300*2^(i/7))], i = 1..level
  • 4*xp = level*(level+1)/2 + sum[floor(300*2^(i/7))], i = [1..level)

We come to next function:

function getXP(level) {
  var xp = level*(level+1)/2, i;
  var sum = 0;
  for (i = 1; i < level; i++)
    sum+=Math.floor(300 * Math.pow(2, i/7));
  return (xp + sum) / 4;
}

However, getXP(5) - getXP(3) will equal like we skip first 3 steps

function getXP(to, from) {
  from = from || 1;
  var xp = 0, i;
  for (i = from; i < level; i++)
    sum += i + Math.floor(300 * Math.pow(2, i/7));
  return xp / 4;
}

So, you can now use it like {{getXP(desiredLevel, currentLevel)}}


This function will be called each digest iteration. It's bad.

You have at least two options to deal with it:

  • Calculate result in your controller and watch about arguments to recalc it.
  • Memoize your function

Something like this:

var hash = {};
function mgetXP(to, from) {
  if (typeof hash[key(to, from)] != 'undefined') return hash[key(to, from)];
  return hash[key(to, from)] = getXP(to, from);
  function key(to, from) {return [to, from].join('_'); }
}

Comments

0

You may also try this approach:

$scope.currentLevel=1;
$scope.currentXp = xp($scope.currentLevel);
$scope.desiredLevel=1;
$scope.desiredXp = xp($scope.desiredLevel);

function xp(level) {    
   function calc(index, result){
      if (index >= level) return result;
      result += (Math.floor( index + 300 * Math.pow( 2, index / 7 ) ) / 4);
      return calc(index + 1, result);
   }
   return calc(1, 0);    
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.