Mhdeusi commited on
Commit
0fef813
·
verified ·
1 Parent(s): b510677

Create reward.js

Browse files
Files changed (1) hide show
  1. js/logic/reward.js +201 -0
js/logic/reward.js ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class RewardSystem {
2
+ constructor() {
3
+ this.quizBaseReward = 10;
4
+ this.exerciseBaseReward = 20;
5
+ this.lessonCompletionReward = 15;
6
+ this.perfectBonus = 5;
7
+ this.streakBonus = 2;
8
+ this.dailyBonus = 10;
9
+ }
10
+
11
+ calculateQuizReward(correctAnswers, totalQuestions, timeSpent = 0, streak = 0) {
12
+ if (totalQuestions === 0) return 0;
13
+
14
+ const accuracy = correctAnswers / totalQuestions;
15
+ let baseScore = accuracy * this.quizBaseReward;
16
+
17
+ // پاداش کامل
18
+ if (correctAnswers === totalQuestions) {
19
+ baseScore += this.perfectBonus;
20
+ }
21
+
22
+ // پاداش سرعت (اگر زمان کمتر از حد انتظار باشد)
23
+ const expectedTime = totalQuestions * 30; // 30 ثانیه برای هر سوال
24
+ if (timeSpent > 0 && timeSpent < expectedTime) {
25
+ const timeBonus = ((expectedTime - timeSpent) / expectedTime) * 5;
26
+ baseScore += timeBonus;
27
+ }
28
+
29
+ // پاداش استریک
30
+ if (streak > 0) {
31
+ baseScore += Math.min(streak * this.streakBonus, 10); // حداکثر 10 امتیاز برای استریک
32
+ }
33
+
34
+ return Math.round(baseScore);
35
+ }
36
+
37
+ calculateExerciseReward(isCorrect, keywordMatches, totalKeywords, complexity = 1) {
38
+ if (!isCorrect) return 0;
39
+
40
+ let baseReward = this.exerciseBaseReward * complexity;
41
+
42
+ // پاداش تطابق کلمات کلیدی
43
+ if (totalKeywords > 0) {
44
+ const matchRatio = keywordMatches / totalKeywords;
45
+ const matchBonus = matchRatio * 10; // حداکثر 10 امتیاز برای تطابق کامل
46
+ baseReward += matchBonus;
47
+ }
48
+
49
+ // پاداش کامل برای تمرین‌های پیچیده
50
+ if (complexity >= 2 && keywordMatches === totalKeywords) {
51
+ baseReward += this.perfectBonus;
52
+ }
53
+
54
+ return Math.round(baseReward);
55
+ }
56
+
57
+ calculateLessonReward(lessonDuration, interactions = 0) {
58
+ const baseReward = this.lessonCompletionReward;
59
+
60
+ // پاداش بر اساس مدت زمان مطالعه
61
+ const timeBonus = Math.min(lessonDuration / 60, 5); // حداکثر 5 امتیاز برای زمان
62
+
63
+ // پاداش تعامل
64
+ const interactionBonus = Math.min(interactions * 0.5, 3); // حداکثر 3 امتیاز برای تعامل
65
+
66
+ return Math.round(baseReward + timeBonus + interactionBonus);
67
+ }
68
+
69
+ calculateDailyBonus(consecutiveDays) {
70
+ let bonus = this.dailyBonus;
71
+
72
+ // پاداش برای روزهای متوالی
73
+ if (consecutiveDays >= 7) {
74
+ bonus += 10; // پاداش هفتگی
75
+ }
76
+ if (consecutiveDays >= 30) {
77
+ bonus += 25; // پاداش ماهانه
78
+ }
79
+
80
+ return bonus;
81
+ }
82
+
83
+ getAchievementReward(achievementType) {
84
+ const rewards = {
85
+ 'first_lesson': 50,
86
+ 'quiz_master': 100,
87
+ 'exercise_pro': 75,
88
+ 'week_streak': 150,
89
+ 'month_streak': 300,
90
+ 'perfect_score': 50,
91
+ 'fast_learner': 60,
92
+ 'consistent_learner': 80
93
+ };
94
+
95
+ return rewards[achievementType] || 25;
96
+ }
97
+
98
+ getLevelThreshold(level) {
99
+ // فرمول نمایی برای سطوح
100
+ return Math.floor(100 * Math.pow(1.5, level - 1));
101
+ }
102
+
103
+ calculateLevel(totalScore) {
104
+ let level = 1;
105
+ let threshold = this.getLevelThreshold(level);
106
+
107
+ while (totalScore >= threshold) {
108
+ level++;
109
+ threshold = this.getLevelThreshold(level);
110
+ }
111
+
112
+ return {
113
+ level: level - 1,
114
+ currentScore: totalScore,
115
+ nextLevelThreshold: threshold,
116
+ progress: this.getLevelThreshold(level - 1) > 0 ?
117
+ ((totalScore - this.getLevelThreshold(level - 2)) /
118
+ (threshold - this.getLevelThreshold(level - 2))) * 100 : 0
119
+ };
120
+ }
121
+
122
+ getRewardFeedback(reward, maxPossibleReward, performanceType) {
123
+ const percentage = (reward / maxPossibleReward) * 100;
124
+
125
+ const feedbackTemplates = {
126
+ quiz: {
127
+ excellent: "عالی! شما بر این مبحث مسلط هستید! 🎉",
128
+ good: "خوب! در مسیر درستی قرار دارید! 👍",
129
+ average: "قابل قبول. می‌توانید بهتر عمل کنید! 💪",
130
+ needs_improvement: "نیاز به مطالعه بیشتر دارید. ادامه دهید! 📚"
131
+ },
132
+ exercise: {
133
+ excellent: "تمرین فوق‌العاده‌ای بود! مهارت شما قابل تحسین است! 🌟",
134
+ good: "تمرین خوبی بود. نکات اصلی را رعایت کردید! ✅",
135
+ average: "تمرین قابل ق��ولی بود. می‌توانید جزئیات بیشتری اضافه کنید! 📝",
136
+ needs_improvement: "نیاز به تمرین بیشتر دارید. دوباره تلاش کنید! 🔄"
137
+ },
138
+ lesson: {
139
+ excellent: "مطالعه بسیار موثری داشتید! ادامه دهید! 🚀",
140
+ good: "مطالعه خوبی بود. مفاهیم اصلی را فرا گرفتید! 📖",
141
+ average: "مطالعه قابل قبولی بود. پیشنهاد می‌کنیم دوباره مرور کنید! 🔍",
142
+ needs_improvement: "نیاز به مطالعه عمیق‌تر دارید. 💡"
143
+ }
144
+ };
145
+
146
+ const templates = feedbackTemplates[performanceType] || feedbackTemplates.quiz;
147
+
148
+ if (percentage >= 90) {
149
+ return {
150
+ message: templates.excellent,
151
+ emoji: "🎉",
152
+ color: "#38a169"
153
+ };
154
+ } else if (percentage >= 70) {
155
+ return {
156
+ message: templates.good,
157
+ emoji: "👍",
158
+ color: "#319795"
159
+ };
160
+ } else if (percentage >= 50) {
161
+ return {
162
+ message: templates.average,
163
+ emoji: "💪",
164
+ color: "#dd6b20"
165
+ };
166
+ } else {
167
+ return {
168
+ message: templates.needs_improvement,
169
+ emoji: "📚",
170
+ color: "#e53e3e"
171
+ };
172
+ }
173
+ }
174
+
175
+ getRankTitle(level) {
176
+ const ranks = {
177
+ 1: "تازه کار",
178
+ 5: "یادگیرنده",
179
+ 10: "متخصص",
180
+ 15: "استاد",
181
+ 20: "ارشد",
182
+ 25: "لجن",
183
+ 30: "اسطوره"
184
+ };
185
+
186
+ for (const [threshold, title] of Object.entries(ranks).reverse()) {
187
+ if (level >= parseInt(threshold)) {
188
+ return title;
189
+ }
190
+ }
191
+
192
+ return "تازه کار";
193
+ }
194
+
195
+ calculateStreakBonus(currentStreak, previousStreak) {
196
+ if (currentStreak <= previousStreak) return 0;
197
+
198
+ const streakIncrease = currentStreak - previousStreak;
199
+ return streakIncrease * this.streakBonus;
200
+ }
201
+ }