Skip to content

Commit 7ea39f5

Browse files
authored
Add rating system with XP and score multiplier
1 parent b354235 commit 7ea39f5

File tree

1 file changed

+96
-5
lines changed

1 file changed

+96
-5
lines changed

src/store/index.ts

Lines changed: 96 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export default createStore({
2929
xp: 0 as number, //set xp to 0 when state is created
3030
progress: 0 as number, //set level progress to 0 percent when state is created
3131
score: 0 as number, //set score to 0 when state is created
32+
rating: 0 as number, //set rating to 0 when state is created
3233
bestScoreEarned: 0 as number, //the highest number of points earned achieved when the task is completed
3334
dailyStreak: 0 as number, //set daily streak to 0 and last completion date to undefined when state is created
3435
tasksCompletedToday: 0 as number, //set the number of tasks completed in a day (today) to 0
@@ -45,6 +46,7 @@ export default createStore({
4546
getLevel: (state) => state.user.level, //get user level
4647
getProgress: (state) => state.user.progress, //get user level progress
4748
getScore: (state) => state.user.score, //get user score
49+
getRating: (state) => state.user.rating, //get user rating
4850
getDailyStreak: (state) => state.user.dailyStreak, //get user daily streak
4951
getTasksCompletedToday: (state) => state.user.tasksCompletedToday, //get user tasks completed in a day
5052
getTotalTasksCompleted: (state) => state.user.totalTasksCompleted, //get user total tasks completed
@@ -85,6 +87,7 @@ export default createStore({
8587
let levelMultiplier: number; //calculate level score multiplier based on user level
8688
let dayTasksMultiplier: number; //calculate XP and score multiplier for tasks completed in a day (today)
8789
let tasksMultiplier: number; //calculate score multiplier for total number of tasks completed
90+
let rankMultiplier: number; //calculate rank multiplier based on current user rating score
8891
const activeTasks: number = state.todos.filter(
8992
(taskList) => !taskList.isCompleted,
9093
).length; //calculate the number of active tasks (tasks that are not completed) using array.filter
@@ -203,7 +206,8 @@ export default createStore({
203206
} else {
204207
dailyStreakMultiplier = 9.783; //9.783x daily streak XP multiplier from 3,652 daily streaks (approximately 10 years)
205208
}
206-
209+
const previousCompletionDate: string | undefined =
210+
state.user.lastCompletionDate; //set previous completion date to last completion date
207211
//set the last completion date to today
208212
state.user.lastCompletionDate = new Date(
209213
new Date().setMinutes(
@@ -212,6 +216,23 @@ export default createStore({
212216
)
213217
.toISOString()
214218
.split("T")[0];
219+
const daysSinceLastCompletion: number = Math.round(
220+
(Number(new Date(state.user.lastCompletionDate + "23:59:59.999")) -
221+
Number(new Date(previousCompletionDate + "23:59:59.999"))) /
222+
(1000 * 60 * 60 * 24),
223+
); //calculate days since task last completion (inactivity)
224+
//check if at least 1 day of inactivity
225+
if (daysSinceLastCompletion >= 1) {
226+
//repeat for each day of inactivity
227+
for (let i = 0; i < daysSinceLastCompletion; i++) {
228+
state.user.rating = Math.max(
229+
state.user.rating -
230+
Math.sqrt(Math.max(state.user.rating, 0)) *
231+
Math.log(Math.max(i + 1, 1)),
232+
0,
233+
); //decrease user rating for each day of inactivity
234+
}
235+
}
215236
//calculate task streak XP multiplier
216237
if (task.streak === 0 || task.streak === 1 || task.repeatInterval === 5) {
217238
//if task streak is 0 or 1 or task repeat interval is one-time
@@ -394,14 +415,79 @@ export default createStore({
394415
} else {
395416
activeTasksMultiplier = 27; //27x active task score multiplier from 10,000 active tasks
396417
}
418+
//calculate rank multiplier bonus based on user rating score
419+
if (state.user.rating < 10) {
420+
rankMultiplier = 0; //0 rank multiplier for rating under 10
421+
} else if (state.user.rating < 50) {
422+
rankMultiplier = 1; //1 rank multiplier for rating from 10 to under 50
423+
} else if (state.user.rating < 100) {
424+
rankMultiplier = 2; //2 rank multiplier for rating from 50 to under 100
425+
} else if (state.user.rating < 250) {
426+
rankMultiplier = 3; //3 rank multiplier for rating from 100 to under 250
427+
} else if (state.user.rating < 500) {
428+
rankMultiplier = 4; //4 rank multiplier for rating from 250 to under 500
429+
} else if (state.user.rating < 1000) {
430+
rankMultiplier = 5; //5 rank multiplier for rating from 500 to under 1,000
431+
} else if (state.user.rating < 2000) {
432+
rankMultiplier = 6; //6 rank multiplier for rating from 1,000 to under 2,000
433+
} else if (state.user.rating < 3000) {
434+
rankMultiplier = 7; //7 rank multiplier for rating from 2,000 to under 3,000
435+
} else if (state.user.rating < 5000) {
436+
rankMultiplier = 8; //8 rank multiplier for rating from 3,000 to under 5,000
437+
} else if (state.user.rating < 7500) {
438+
rankMultiplier = 9; //9 rank multiplier for rating from 5,000 to under 7,500
439+
} else if (state.user.rating < 10000) {
440+
rankMultiplier = 10; //10 rank multiplier for rating from 7,500 to under 10,000
441+
} else if (state.user.rating < 15000) {
442+
rankMultiplier = 11; //11 rank multiplier for rating from 10,000 to under 15,000
443+
} else if (state.user.rating < 20000) {
444+
rankMultiplier = 12; //12 rank multiplier for rating from 15,000 to under 20,000
445+
} else if (state.user.rating < 25000) {
446+
rankMultiplier = 13; //13 rank multiplier for rating from 20,000 to under 25,000
447+
} else if (state.user.rating < 30000) {
448+
rankMultiplier = 14; //14 rank multiplier for rating from 25,000 to under 30,000
449+
} else if (state.user.rating < 40000) {
450+
rankMultiplier = 15; //15 rank multiplier for rating from 30,000 to under 40,000
451+
} else if (state.user.rating < 50000) {
452+
rankMultiplier = 16; //16 rank multiplier for rating from 40,000 to under 50,000
453+
} else if (state.user.rating < 60000) {
454+
rankMultiplier = 17; //17 rank multiplier for rating from 50,000 to under 60,000
455+
} else if (state.user.rating < 75000) {
456+
rankMultiplier = 18; //18 rank multiplier for rating from 60,000 to under 75,000
457+
} else if (state.user.rating < 100000) {
458+
rankMultiplier = 19; //19 rank multiplier for rating from 75,000 to under 100,000
459+
} else if (state.user.rating < 125000) {
460+
rankMultiplier = 20; //20 rank multiplier for rating from 100,000 to under 125,000
461+
} else if (state.user.rating < 150000) {
462+
rankMultiplier = 21; //21 rank multiplier for rating from 125,000 to under 150,000
463+
} else if (state.user.rating < 200000) {
464+
rankMultiplier = 22; //22 rank multiplier for rating from 150,000 to under 200,000
465+
} else if (state.user.rating < 250000) {
466+
rankMultiplier = 23; //23 rank multiplier for rating from 200,000 to under 250,000
467+
} else if (state.user.rating < 300000) {
468+
rankMultiplier = 24; //24 rank multiplier for rating from 250,000 to under 300,000
469+
} else if (state.user.rating < 400000) {
470+
rankMultiplier = 25; //25 rank multiplier for rating from 300,000 to under 400,000
471+
} else if (state.user.rating < 500000) {
472+
rankMultiplier = 26; //26 rank multiplier for rating from 400,000 to under 500,000
473+
} else if (state.user.rating < 600000) {
474+
rankMultiplier = 27; //27 rank multiplier for rating from 500,000 to under 600,000
475+
} else if (state.user.rating < 750000) {
476+
rankMultiplier = 28; //28 rank multiplier for rating from 600,000 to under 750,000
477+
} else if (state.user.rating < 1000000) {
478+
rankMultiplier = 29; //29 rank multiplier for rating from 750,000 to under 1,000,000
479+
} else {
480+
rankMultiplier = 30; //30 rank multiplier for rating from 1,000,000
481+
}
397482
//calculate the amount of XP earned and points earned when the task is completed
398483
const rankXpEarned: number = Math.max(
399484
Math.floor(
400485
(dateMultiplier - 1) ** 2 *
401486
100 *
402487
Math.max(task.rank, 1) *
403488
Math.max(task.streak, 1) *
404-
repeatMultiplier,
489+
repeatMultiplier *
490+
(1 + rankMultiplier / 10),
405491
),
406492
1,
407493
); //get at least 1 rank XP when the task is completed
@@ -425,11 +511,15 @@ export default createStore({
425511
streakMultiplier *
426512
dailyStreakMultiplier *
427513
dayTasksMultiplier *
428-
(1 + task.rank / 10),
514+
(1 + task.rank / 10) *
515+
(1 + rankMultiplier / 10),
429516
),
430517
1,
431518
); //get at least 1 XP when the task is completed
432519
state.user.xp += xpEarned; //get the amount of XP earned based on task difficulty, task priority, task due date, task repetition, task streak, daily streak and task rank multipliers
520+
state.user.rating +=
521+
((10 + Math.log(state.user.rating + 1) ** 2) * repeatMultiplier) /
522+
Math.max(state.user.tasksCompletedToday, 1); //get the amount of rating poings earned based on user rating, task repeat multiplier and number of tasks completed today
433523
const pointsEarned: number = Math.max(
434524
Math.floor(
435525
task.difficulty *
@@ -442,11 +532,12 @@ export default createStore({
442532
levelMultiplier *
443533
tasksMultiplier *
444534
activeTasksMultiplier *
445-
(1 + task.rank / 10),
535+
(1 + task.rank / 10) *
536+
(1 + rankMultiplier / 10),
446537
),
447538
1,
448539
); //get at least 1 point when the task is completed
449-
state.user.score += pointsEarned; //get amount of points earned based on task difficulty, task priority, task due date, task repetition, task streak, daily streak and user level multipliers
540+
state.user.score += pointsEarned; //get amount of points earned based on task difficulty, task priority, task due date, task repetition, task streak, daily streak, user level and rank multipliers
450541
if (pointsEarned > state.user.bestScoreEarned) {
451542
//if points earned are greater than the best score earned
452543
state.user.bestScoreEarned = pointsEarned; //set the best score earned to points earned when the task is completed

0 commit comments

Comments
 (0)