Fixed bug when calculating the reverse delta.

Added in a case for a todo with checklists
so the gp and exp for those are reversed correctly.
Added a couple test cases for checking then unchecking tasks.
This commit is contained in:
Brandon Reid 2014-10-06 13:33:43 -06:00
parent 65b3561fb0
commit d0cebce605
3 changed files with 57 additions and 23 deletions

View file

@ -14180,10 +14180,10 @@ api.wrap = function(user, main) {
return nextDelta;
};
calculateReverseDelta = function() {
var calc, closeEnough, currVal, diff, testVal;
var calc, closeEnough, currVal, diff, nextDelta, testVal, _ref1;
currVal = task.value < -47.27 ? -47.27 : task.value > 21.27 ? 21.27 : task.value;
testVal = currVal + Math.pow(0.9747, currVal) * (direction === 'down' ? -1 : 1);
closeEnough = 0.0001;
closeEnough = 0.00001;
while (true) {
calc = testVal + Math.pow(0.9747, testVal);
diff = currVal - calc;
@ -14196,12 +14196,20 @@ api.wrap = function(user, main) {
testVal += diff;
}
}
return testVal - currVal;
nextDelta = testVal - currVal;
if (((_ref1 = task.checklist) != null ? _ref1.length : void 0) > 0) {
if (task.type === 'todo') {
nextDelta *= 1 + _.reduce(task.checklist, (function(m, i) {
return m + (i.completed ? 1 : 0);
}), 0);
}
}
return nextDelta;
};
changeTaskValue = function(reverse) {
changeTaskValue = function() {
return _.times(options.times, function() {
var nextDelta, _ref1;
nextDelta = reverse ? calculateReverseDelta() : calculateDelta();
nextDelta = !options.cron && direction === 'down' ? calculateReverseDelta() : calculateDelta();
if (task.type !== 'reward') {
if (user.preferences.automaticAllocation === true && user.preferences.allocationMode === 'taskbased' && !(task.type === 'todo' && direction === 'down')) {
user.stats.training[task.attribute] += nextDelta;
@ -14218,7 +14226,7 @@ api.wrap = function(user, main) {
});
};
addPoints = function() {
var afterStreak, gpMod, intBonus, perBonus, streakBonus, _crit;
var afterStreak, currStreak, gpMod, intBonus, perBonus, streakBonus, _crit;
_crit = (delta > 0 ? user.fns.crit() : 1);
if (_crit > 1) {
user._tmp.crit = _crit;
@ -14227,7 +14235,7 @@ api.wrap = function(user, main) {
stats.exp += Math.round(delta * intBonus * task.priority * _crit * 6);
perBonus = 1 + user._statsComputed.per * .02;
gpMod = delta * task.priority * _crit * perBonus;
return stats.gp += task.streak ? (streakBonus = task.streak / 100 + 1, afterStreak = gpMod * streakBonus, gpMod > 0 ? user._tmp.streakBonus = afterStreak - gpMod : void 0, afterStreak) : gpMod;
return stats.gp += task.streak ? (currStreak = direction === 'down' ? task.streak - 1 : task.streak, streakBonus = currStreak / 100 + 1, afterStreak = gpMod * streakBonus, currStreak > 0 ? gpMod > 0 ? user._tmp.streakBonus = afterStreak - gpMod : void 0 : void 0, afterStreak) : gpMod;
};
subtractPoints = function() {
var conBonus, hpMod;
@ -14269,8 +14277,8 @@ api.wrap = function(user, main) {
task.streak = 0;
}
} else {
changeTaskValue(delta < 0);
if (delta < 0) {
changeTaskValue();
if (direction === 'down') {
delta = calculateDelta();
}
addPoints();
@ -14292,8 +14300,8 @@ api.wrap = function(user, main) {
changeTaskValue();
} else {
task.dateCompleted = direction === 'up' ? new Date : void 0;
changeTaskValue(delta < 0);
if (delta < 0) {
changeTaskValue();
if (direction === 'down') {
delta = calculateDelta();
}
addPoints();

View file

@ -877,7 +877,7 @@ api.wrap = (user, main=true) ->
testVal = currVal + Math.pow(0.9747, currVal) * (if direction is 'down' then -1 else 1)
# Now keep moving closer to the original value until we get "close enough"
closeEnough = 0.0001
closeEnough = 0.00001
while true
# Check how close we are to the original value by computing the delta off our guess
# and looking at the difference between that and our current value.
@ -889,16 +889,25 @@ api.wrap = (user, main=true) ->
testVal -= diff
else
testVal += diff
# When we get close enough, return the difference between our approximated value
# and the current value. This will be the delta calculated from the original value
# before the task was checked.
testVal - currVal
nextDelta = testVal - currVal
changeTaskValue = (reverse) ->
# Checklists
if task.checklist?.length > 0
# If To-Do, point-match the TD per checklist item completed
if task.type is 'todo'
nextDelta *= (1 + _.reduce(task.checklist,((m,i)->m+(if i.completed then 1 else 0)),0))
nextDelta
changeTaskValue = ->
# If multiple days have passed, multiply times days missed
_.times options.times, ->
# Each iteration calculate the nextDelta, which is then accumulated in the total delta.
nextDelta = if reverse then calculateReverseDelta() else calculateDelta()
nextDelta = if not options.cron and direction is 'down' then calculateReverseDelta() else calculateDelta()
unless task.type is 'reward'
if (user.preferences.automaticAllocation is true and user.preferences.allocationMode is 'taskbased' and !(task.type is 'todo' and direction is 'down')) then user.stats.training[task.attribute] += nextDelta
# ===== STRENGTH =====
@ -930,9 +939,11 @@ api.wrap = (user, main=true) ->
gpMod = (delta * task.priority * _crit * perBonus)
stats.gp +=
if task.streak
streakBonus = task.streak / 100 + 1 # eg, 1-day streak is 1.1, 2-day is 1.2, etc
currStreak = if direction is 'down' then task.streak-1 else task.streak
streakBonus = currStreak / 100 + 1 # eg, 1-day streak is 1.01, 2-day is 1.02, etc
afterStreak = gpMod * streakBonus
user._tmp.streakBonus = afterStreak - gpMod if (gpMod > 0) # keep this on-hand for later, so we can notify streak-bonus
if currStreak > 0
user._tmp.streakBonus = afterStreak - gpMod if (gpMod > 0) # keep this on-hand for later, so we can notify streak-bonus
afterStreak
else gpMod
@ -965,9 +976,9 @@ api.wrap = (user, main=true) ->
subtractPoints()
task.streak = 0 unless user.stats.buffs.streaks
else
changeTaskValue(delta < 0)
if delta < 0
delta = calculateDelta()
changeTaskValue()
if direction is 'down'
delta = calculateDelta() # recalculate delta for unchecking so the gp and exp come out correctly
addPoints() # obviously for delta>0, but also a trick to undo accidental checkboxes
if direction is 'up'
task.streak = if task.streak then task.streak + 1 else 1
@ -986,9 +997,9 @@ api.wrap = (user, main=true) ->
#don't touch stats on cron
else
task.dateCompleted = if direction is 'up' then new Date else undefined
changeTaskValue(delta < 0)
if delta < 0
delta = calculateDelta()
changeTaskValue()
if direction is 'down'
delta = calculateDelta() # recalculate delta for unchecking so the gp and exp come out correctly
addPoints() # obviously for delta>0, but also a trick to undo accidental checkboxes
# MP++ per checklist item in ToDo, bonus per CLI
multiplier = _.max([(_.reduce(task.checklist,((m,i)->m+(if i.completed then 1 else 0)),1)),1])

View file

@ -93,6 +93,11 @@ expectNoChange = (before,after) ->
_.each $w('stats items gear dailys todos rewards flags preferences'), (attr)->
expect(after[attr]).to.eql before[attr]
expectClosePoints = (before, after, taskType) ->
expect( Math.abs(after.stats.exp - before.stats.exp) ).to.be.lessThan 0.0001
expect( Math.abs(after.stats.gp - before.stats.gp) ).to.be.lessThan 0.0001
expect( Math.abs(after["#{taskType}s"][0].value - before["#{taskType}s"][0].value) ).to.be.lessThan 0.0001
expectDayResetNoDamage = (b,a) ->
[before,after] = [_.cloneDeep(b), _.cloneDeep(a)]
_.each after.dailys, (task,i) ->
@ -379,10 +384,20 @@ describe 'Simple Scoring', ->
@after.ops.score {params: {id: @after.dailys[0].id, direction: 'up'}}
expectGainedPoints(@before, @after,'daily')
it 'Dailys : Up, Down', ->
@after.ops.score {params: {id: @after.dailys[0].id, direction: 'up'}}
@after.ops.score {params: {id: @after.dailys[0].id, direction: 'down'}}
expectClosePoints(@before, @after, 'daily')
it 'Todos : Up', ->
@after.ops.score {params: {id: @after.todos[0].id, direction: 'up'}}
expectGainedPoints(@before, @after,'todo')
it 'Todos : Up, Down', ->
@after.ops.score {params: {id: @after.todos[0].id, direction: 'up'}}
@after.ops.score {params: {id: @after.todos[0].id, direction: 'down'}}
expectClosePoints(@before, @after, 'todo')
describe 'Cron', ->
it 'computes shouldCron', ->