Skip to content

Commit

Permalink
Merge pull request #1543 from somiaj/achievement-features
Browse files Browse the repository at this point in the history
Achievement features
  • Loading branch information
drgrice1 authored Apr 6, 2022
2 parents 2afedff + d130818 commit b0381a1
Show file tree
Hide file tree
Showing 28 changed files with 195 additions and 33 deletions.
4 changes: 2 additions & 2 deletions conf/defaults.config
Original file line number Diff line number Diff line change
Expand Up @@ -1605,8 +1605,8 @@ $ConfigValues = [
type => 'number'
},
{ var => 'achievementItemsEnabled',
doc => 'Enable Achievement Items',
doc2 => 'Activiating this will enable achievement items. This features rewards students who earn achievements with items that allow them to affect their homework in a limited way.',
doc => 'Enable Achievement Rewards',
doc2 => 'Activating this will enable achievement rewards. This feature allows students to earn rewards by completing achievements that allow them to affect their homework in a limited way.',
type => 'boolean'
},
{ var => 'options{enableConditionalRelease}',
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@
DBchapter and DBsection Note: These values are not super stable and are likely to change
from problem to problem and year to year

- $userAchievements: this hash stores all assigned achievements for
the current user. The keys are the achievement_id and the values
are 0 or 1 for if the achievement has been earned. Changes to this
variable will be accessible by achievements down the line in the
current evaluation loop, but will not be saved across evaluations.
Note: This variable is updated if an achievement is earned,
but only achievements further down the evaluation chain will
see the update. So when depending on other achievements place
make sure they are run first.

- $localData : this is a hash which stores data for this user and
achievement (changes to this variable *will* be saved!)
This hash will persist from evaluation to evaluation. You can
Expand All @@ -62,12 +72,14 @@
This hash will persist from evaluation to evaluation and, like
$localData, you can store whatever you like in here. This data
will be accessable from *every* achievement and is unique to the
user. There are two variables stored in this hash that are
user. There are three variables stored in this hash that are
maintained by the system.
- $globalData->completeSets : This is the number of sets which
the student has earned 100% on
- $globalData->complete Problems : This is the number of problems
which the student has earned 100% on
- $globalData->prev_level_points : This is the number of points
to reach current level which is used with level progress bar.
Warning: The achievements are always evaluated in the order they
are listed the Instructors achievement editor page. To make matters
more complicated, achievements which have already been earned are
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ on_fire,"You're on Fire!",210,one_timer,"default,jitar","Complete 10 problems in
complete_one_set,"One Set Wonder",401,complete_sets,default,"Get 100% on one homework set.",10,,complete_one_set.at,complete_one_set.png
complete_five_sets,"High Five",402,complete_sets,default,"Get 100% on five homework sets.",10,5,complete_five_sets.at,complete_five_sets.png
complete_ten_sets,"One For Each Finger",403,complete_sets,default,"Get 100% on ten homework sets.",10,10,complete_ten_sets.at,complete_ten_sets.png
complete_twenty_sets,"Mathbox Twenty",403,complete_sets,default,"Get 100% on twenty homework sets.",20,20,complete_twenty_sets.at,complete_twenty_sets.png
complete_twenty_sets,"Mathbox Twenty",404,complete_sets,default,"Get 100% on twenty homework sets.",20,20,complete_twenty_sets.at,complete_twenty_sets.png
complete_thirty_sets,"The Long Road",405,complete_sets,default,"Get 100% on thirty homework sets.",20,30,complete_thirty_sets.at,complete_thirty_sets.png
complete_all_sets,Perfection,406,complete_sets,default,"Get 100% on all homework sets.",30,35,complete_all_sets.at,complete_all_sets.png
complete_one_problem,"The First Step",501,complete_problems,"default,jitar","Earn 100% on a homework problem.",10,,complete_one_problem.at,complete_one_problem.png
Expand All @@ -41,6 +41,11 @@ challenge_eight,"Challenge Eight Complete",608,challenge,default,"Finish the eig
challenge_nine,"Challenge Nine Complete",609,challenge,default,"Finish the ninth challenge problem.",10,,challenge_nine.at,challenge_nine.png
challenge_ten,"Challenge Ten Complete",610,challenge,default,"Finish the tenth challenge problem.",10,,challenge_ten.at,challenge_ten.png
challenger,Challenger,611,challenge,default,"Finish all of the challenge problems.",10,20,challenger.at,challenger.png
earn_10_achievements,"Huzzah!!",9501,achievements,"default,gateway,jitar","Earn ten achievements.",10,10,earn_n_achievements.at,earn_10_achievements.png
earn_20_achievements,"Achiever",9502,achievements,"default,gateway,jitar","Earn twenty achievements.",10,20,earn_n_achievements.at,earn_20_achievements.png
earn_30_achievements,"The Collector",9503,achievements,"default,gateway,jitar","Earn thirty achievements.",10,30,earn_n_achievements.at,earn_30_achievements.png
earn_40_achievements,"Over Achiever",9504,achievements,"default,gateway,jitar","Earn forty achievements.",20,40,earn_n_achievements.at,earn_40_achievements.png
earn_50_achievements,"The Completionist",9505,achievements,"default,gateway,jitar","Earn fifty achievements.",20,50,earn_n_achievements.at,earn_50_achievements.png
level_one,"Level 1 Initiate",9901,level,"default,gateway,jitar","You have been awarded a Lesser Rod of Revelation",,,level_one.at,level_one.png
level_two,"Level 2 Novice",9902,level,"default,gateway,jitar","You have been awarded a Potion of Forgetfulness",,,level_two.at,level_two.png
level_three,"Level 3 Apprentice",9903,level,"default,gateway,jitar","You have been awarded a Tunic of Extension",,,level_three.at,level_three.png
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# This is a "earn n achievements. Notice how we update $counter
# (even though the appropriate data is already given to use in
# $userAchievements) so that the achievement progress bar works correctly.

# Update counter from $userAchievements. Ignore level achievements.
$counter = 0;
foreach my $key (keys %{ $userAchievements }) {
if ($userAchievements->{$key} && $key !~ /^level/) {
$counter++;
}
}

if ($counter >= $maxCounter) {
return 1
} else {
return 0;
}


# Variable Descriptions:
# - $problem : the problem data (changes to this variable will not be saved!)
# This variable contains the problem data. It is a hash pointer with the
# following values (not all values shown)
# - $problem->status : the score of the current problem
# - $problem->problem_id : the id of the current problem
# - $problem->set_id : the id of the set containing the problem
# - $problem->num_correct : the number of correct attempts
# - $problem->num_incorrect : the number of incorrect attempts
# - $problem->max_attempts : the maximum number of allowed attempts
#
# - $set : the set data (changes to this variable will not be saved!)
# This variable contains the set data. it is a hash pointer with the
# following values. (not all values shown)
# - $set->open_date : when the set was open
# - $set->due_date : when the set is due
#
# - @setProblems : the problem data for all the problems from this set.
# (changes to this variable will not be saved!)
# This is an array of problem hashes. Each element of the array has the
# save hash keys as the $problem variable above
#
# - $counter : the users counter associated to this achievement
# (changes to this variable *will* be saved!)
# If this achievement has a counter associated to it
# (i.e. solve 20 problems) then this is where you store
# the students counter for this achievement.
# This variable will initally start as ''
#
# - $maxCounter : the goal for the $counter variable for this achievement
# (changes to this variable will not be saved!)
# If this achievement has a counter associated to it then this variable
# contains the goal for the counter. Your achievement should return 1
# when $counter >= $maxCounter. These two variables are used to show a
# progress bar for the achievement.
#
# - $tags : this contains the metadata for the problem stored in a hash. This includes DBsubject
# DBchapter and DBsection Note: These values are not super stable and are likely to change
# from problem to problem and year to year
#
# - $userAchievements: this hash stores all assigned achievements for
# the current user. The keys are the achievement_id and the values
# are 0 or 1 for if the achievement has been earned. Changes to this
# variable will be accessible by achievements down the line in the
# current evaluation loop, but will not be saved across evaluations.
# Note: This variable is updated if an achievement is earned,
# but only achievements further down the evaluation chain will
# see the update. So when depending on other achievements place
# make sure they are run first.
#
# - $localData : this is a hash which stores data for this user and
# achievement (changes to this variable *will* be saved!)
# This hash will persist from evaluation to evaluation. You can
# store whatever you like in here and it can be accessed next time
# this evaluator is run. Two things to keep in mind. First, The data
# in this hash will *not* be accessible by other achievements. Second,
# the first time a variable is accessed it will have the value ''.
#
# - $globalData : this is a hash which stores data for all achievements
# (changes to this variable *will* be saved!)
# This hash will persist from evaluation to evaluation and, like
# $localData, you can store whatever you like in here. This data
# will be accessable from *every* achievement and is unique to the
# user. There are two variables stored in this hash that are
# maintained by the system.
# - $globalData->completeSets : This is the number of sets which
# the student has earned 100% on
# - $globalData->complete Problems : This is the number of problems
# which the student has earned 100% on
# Warning: The achievements are always evaluated in the order they
# are listed the Instructors achievement editor page. To make matters
# more complicated, achievements which have already been earned are
# not evaluated at all. The up-shot of this is that when modifying
# variables in $globalData you need to either write your code so it
# doesnt matter which order the evaluators are run, or you need to
# pay very close attention to which evaluators are run and when.
2 changes: 1 addition & 1 deletion htdocs/themes/math4/achievements.scss
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
}

.cheevoinnerbar {
height: 10px;
height: 6px;
background-color: var(--ww-achievement-level-color, #88D);
}

Expand Down
17 changes: 15 additions & 2 deletions lib/WeBWorK/AchievementEvaluator.pm
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ sub checkForAchievements {
our $nextLevelPoints = $globalUserAchievement->next_level_points;
our $localData = {};
our $globalData = {};
our $userAchievements = {};
our $tags;
our @setProblems;
our @courseDateTime = (
Expand All @@ -120,10 +121,16 @@ sub checkForAchievements {

#Thaw_Base64 globalData hash
if ($globalUserAchievement->frozen_hash) {

$globalData = thaw_base64($globalUserAchievement->frozen_hash);
}

#Generate hash of user achievements:
foreach my $achievement (@achievements) {
next unless $achievement->enabled;
my $userAchievement = $db->getUserAchievement($user_id, $achievement->achievement_id);
$userAchievements->{$achievement->achievement_id} = $userAchievement->earned if $userAchievement;
}

#Update a couple of "standard" variables in globalData hash.
my $allcorrect = 0;

Expand Down Expand Up @@ -188,10 +195,11 @@ sub checkForAchievements {
# $nextLevelPoints - only should be used by 'level' achievements
# $set - the set data
# $achievementPoints - the number of achievmeent points
# $userAchievements - hash of enabled achievement_id => earned
# $tags -this is the tag data associated to the problem from the problem library
# @courseDateTime - array of time information in course timezone (sec,min,hour,day,month,year,day_of_week)

$compartment->share(qw( $problem @setProblems $localData $maxCounter
$compartment->share(qw( $problem @setProblems $localData $maxCounter $userAchievements
$globalData $counter $nextLevelPoints $set $achievementPoints $tags @courseDateTime));

#load any preamble code
Expand Down Expand Up @@ -242,7 +250,12 @@ sub checkForAchievements {
if ($earned) {
$userAchievement->earned(1);

# update userAchievements hash with earned status.
$userAchievements->{$achievement_id} = $earned;

if ($achievement->category eq 'level') {
# Store prev_level_points in globalData, used for level progress bar.
$globalData->{'prev_level_points'} = $globalUserAchievement->next_level_points;
$globalUserAchievement->level_achievement_id($achievement_id);
$globalUserAchievement->next_level_points($nextLevelPoints);
}
Expand Down
Loading

0 comments on commit b0381a1

Please sign in to comment.