Skip to content

Commit

Permalink
Sequencing enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
agordillo committed Apr 17, 2021
1 parent e40f0f1 commit 331d0a6
Show file tree
Hide file tree
Showing 7 changed files with 429 additions and 281 deletions.
2 changes: 1 addition & 1 deletion app/models/game.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Game < ActiveRecord::Base
belongs_to :template, class_name: :GameTemplate, foreign_key: "game_template_id"
has_many :mappings, class_name: :GameEventMapping, :dependent => :destroy
has_many :events, class_name: :GameTemplateEvent, :through => :template
has_many :los, :through => :mappings
has_many :los, -> { uniq }, :through => :mappings

has_attached_file :thumbnail,
:styles => SgamePlatform::Application.config.thumbnail_styles
Expand Down
39 changes: 33 additions & 6 deletions lib/plugins/sgame/app/assets/javascripts/sgame_api/SGAME.CORE.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ SGAME.CORE = (function(){
var _options = {};
//Internal vars
var _togglePauseFunction = undefined;
var _sequence_finished = false;
var _final_screen_text = "Congratulations. You have achieved the objectives of this educational game. You may close this window or continue playing.";

//SGAME settings (provided by the SGAME platform)
Expand Down Expand Up @@ -170,8 +171,6 @@ SGAME.CORE = (function(){
_settings["los"][lo_ids[i]]["nshown"] = 0; //number of times shown
_settings["los"][lo_ids[i]]["succesfully_consumed"] = false;
_settings["los"][lo_ids[i]]["nsuccess"] = 0; //number of times succesfully consumed
_settings["los"][lo_ids[i]].groups = []; //Groups, for applying sequencing rules.

_settings["los"][lo_ids[i]]["acts_as_asset"] = ((_settings["los"][lo_ids[i]]["scorm_type"]==="asset")||((_settings["los"][lo_ids[i]]["scorm_type"]==="sco")&&(_settings["los"][lo_ids[i]]["report_data"]===false)));

_los_can_be_shown = true;
Expand All @@ -189,9 +188,19 @@ SGAME.CORE = (function(){
}

if(typeof _settings["sequencing"]["sequence"] === "object"){
//Reset LOs
var lo_ids = Object.keys(_settings["los"]);
_nLOs = lo_ids.length;
for(var x=0; x<_nLOs; x++){
_settings["los"][lo_ids[x]]["can_be_shown"] = false;
_settings["los"][lo_ids[x]].groups = []; //Groups for applying sequencing rules.
}

_los_can_be_shown = false;

var group_ids = Object.keys(_settings["sequencing"]["sequence"]);
_nGroups = group_ids.length;
for(var j=0; j<_nGroups;j++){
for(var j=0; j<_nGroups; j++){
//Add additional vars for SGAME
var group = _settings["sequencing"]["sequence"][group_ids[j]];
group["can_be_shown"] = ((typeof group.conditions === "undefined")||(group.conditions.length === 0));
Expand All @@ -205,9 +214,15 @@ SGAME.CORE = (function(){
_settings["sequencing"]["sequence"][group_ids[j]] = group;
for(var l=0; l<group.los.length; l++){
_settings["los"][group.los[l]].groups.push(group.id);
_settings["los"][group.los[l]]["can_be_shown"] = (group["can_be_shown"] === true);
if(_settings["los"][group.los[l]]["can_be_shown"] === true){
_los_can_be_shown = true;
}
}
}
}

SGAME.Sequencing.init(_settings["sequencing"]);
};

var triggerLO = function(event_id,callback){
Expand Down Expand Up @@ -333,9 +348,15 @@ SGAME.CORE = (function(){
_settings["los"][lo["id"]]["nsuccess"] += 1;
}

if(_settings["sequencing"]["approach"] !== "random"){
if((_settings["sequencing"]["approach"] !== "random")&&(_sequence_finished === false)){
//Check if the groups to which the LO belongs have been "shown" or "succesfully consumed" and if other groups should be unlocked or locked
_settings["sequencing"]["sequence"] = SGAME.Sequencing.updateGroupsTracking(_settings["los"][lo["id"]],_settings["sequencing"]["sequence"],_settings["los"]);
var output = SGAME.Sequencing.updateGroupsTracking(_settings["los"][lo["id"]],_settings["sequencing"]["sequence"],_settings["los"]);
_settings["sequencing"]["sequence"] = output.groups;
_settings["los"] = output.los;
if(output.finished){
//All groups have been locked. Sequencing is finished.
_sequence_finished = true;
}
}

//Check if the learning object can be shown again
Expand Down Expand Up @@ -691,7 +712,13 @@ SGAME.CORE = (function(){
* This strategy chooses one learning object among the valid candidates following sequencing rules defined by the game author.
*/
var _selectLoFromCandidatesSequence = function(loCandidatesFromMapping){
return _selectLoFromCandidatesRandom(_getLoCandidatesFromSequecingRules(loCandidatesFromMapping));
var candidates;
if(_sequence_finished === false){
candidates = _getLoCandidatesFromSequecingRules(loCandidatesFromMapping);
} else {
candidates = loCandidatesFromMapping;
}
return _selectLoFromCandidatesRandom(candidates);
};

var _getLoCandidatesFromSequecingRules = function(loCandidatesFromMapping){
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
SGAME.Sequencing = (function(){

//SGAME settings (provided by the SGAME platform)
var _sequencingApproach;
//Validations
var supportedGroupRequirements = ["completion","success"];

var init = function(){
var init = function(seq_settings){
_sequencingApproach = seq_settings["approach"];
};

var validateSequence = function(sequence,los){
Expand Down Expand Up @@ -120,23 +122,43 @@ SGAME.Sequencing = (function(){
}

//Check if some group must be unlocked/locked
var nLockedGroups = 0;
var group_ids = Object.keys(groups);
for(var j=0; j<group_ids.length; j++){
var ogroup = groups[group_ids[j]];
if((ogroup.can_be_shown === false)&&(ogroup.shown === false)&&(ogroup.succesfully_consumed === false)){
groups[group_ids[j]] = _updateGroupUnlock(ogroup,groups);
if(ogroup.can_be_shown === false){
nLockedGroups = nLockedGroups + 1;
if((ogroup.shown === false)&&(ogroup.succesfully_consumed === false)){
groups[group_ids[j]] = _updateGroupUnlock(ogroup,groups);
if(groups[group_ids[j]].can_be_shown === true){
//Group unlocked: Unlock group LOs
los = _changeCanBeShownForLOsInGroup(groups[group_ids[j]],los,true);
nLockedGroups = nLockedGroups - 1;
}
}
}
}

for(var k=0; k<lo.groups.length; k++){
var ogroup = groups[lo.groups[k]+""];
if(ogroup.can_be_shown === true){
groups[lo.groups[k]+""] = _updateGroupLock(ogroup,groups);
if(groups[lo.groups[k]+""].can_be_shown === false){
//Group locked: Lock group LOs
los = _changeCanBeShownForLOsInGroup(groups[lo.groups[k]+""],los,false);
nLockedGroups = nLockedGroups + 1;
}
}
}

return groups;
};
var finished = (nLockedGroups === group_ids.length);
if(finished){
//All groups have been locked
los = _unlockLOsWithoutGroup(los);
}

return {"groups": groups, "los": los, "finished": finished};
};

/*
* Update the tracking data of a specific group
Expand All @@ -158,10 +180,6 @@ SGAME.Sequencing = (function(){
group.shown = gShown;
group.succesfully_consumed = gSuccess;

if(group.succesfully_consumed){
group.can_be_shown = false;
}

return group;
};

Expand Down Expand Up @@ -202,22 +220,56 @@ SGAME.Sequencing = (function(){

var _getLockForGroup = function(group,groups){
var group_ids = Object.keys(groups);
var nConditions = 0;
var nConditionsMet = 0;
for(var j=0; j<group_ids.length; j++){
var ogroup = groups[group_ids[j]];
if((ogroup.id != group.id)&&(typeof ogroup.conditions !== "undefined")){
if((ogroup.can_be_shown === false)&&(ogroup.id != group.id)&&(typeof ogroup.conditions !== "undefined")){
for(var k=0; k<ogroup.conditions.length; k++){
if(ogroup.conditions[k].group == group.id){
nConditions = nConditions + 1;
if(ogroup.conditions[k].met === false){
return false;
}

nConditionsMet = nConditionsMet + 1;
}
}
}
}
return (nConditions > 0);
//Currently, no locked group depends on the status of this group to be unlocked.

if (nConditionsMet > 0){
//A condition related to this group unlocking another group has been met. This group can be locked.
return true;
} else {
//This group does not unlock any other group.
//Lock when completed or successed depending on the sequencing approach.
switch(_sequencingApproach){
case "linear_completion":
return group.shown;
case "linear_success":
return group.succesfully_consumed;
case "custom":
default:
return ((group.shown)&&(group.succesfully_consumed));
break;
}
}
};

var _changeCanBeShownForLOsInGroup = function(group,los,canBeShown){
for(var i=0; i<group.los.length; i++){
los[group.los[i]]["can_be_shown"] = canBeShown;
}
return los;
};

var _unlockLOsWithoutGroup = function(los){
var lo_ids = Object.keys(los);
for(var i=0; i<lo_ids.length; i++){
if((typeof los[lo_ids[i]].groups === "undefined")||(los[lo_ids[i]].groups.length === 0)){
los[lo_ids[i]]["can_be_shown"] = true;
}
}
return los;
};

return {
Expand Down
4 changes: 2 additions & 2 deletions lib/plugins/sgame/app/assets/javascripts/sgame_api/SGAME.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@ SGAME = (function(){
};
})();

SGAME.VERSION = '0.7';
SGAME.AUTHORS = 'Aldo Gordillo, Enrique Barra';
SGAME.VERSION = '1.0.0';
SGAME.AUTHORS = 'Aldo Gordillo';
SGAME.URL = "https://github.com/ging/sgame_platform";
2 changes: 1 addition & 1 deletion lib/plugins/sgame/lib/tasks/sgame.rake
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ SGAME_COMPILER_JAR_PATH = "extras/compile"
SGAME_JSCOMPILER_JAR_FILE = SGAME_COMPILER_JAR_PATH + "/compiler.jar"

# SGAME API files and dirs :
SGAME_API_JS_FILES_AND_DIRS = ['app/assets/js_to_compile_api/iso8601Parser.js','app/assets/js_to_compile_api/Local_API_1484_11.js','app/assets/js_to_compile_api/Local_API_SCORM_12.js','app/assets/js_to_compile_api/SGAME.js','app/assets/js_to_compile_api/SGAME.Debugger.js','app/assets/js_to_compile_api/SGAME.Messenger.js','app/assets/js_to_compile_api']
SGAME_API_JS_FILES_AND_DIRS = ['app/assets/js_to_compile_api/iso8601Parser.js','app/assets/js_to_compile_api/Local_API_1484_11.js','app/assets/js_to_compile_api/Local_API_SCORM_12.js','app/assets/js_to_compile_api/SGAME.js','app/assets/js_to_compile_api/SGAME.Debugger.js','app/assets/js_to_compile_api/SGAME.Messenger.js','app/assets/js_to_compile_api/SGAME.Sequencing.js','app/assets/js_to_compile_api']
SGAME_Gateway_JS_FILES_AND_DIRS = ['app/assets/js_to_compile_gateway/jquery-3.4.1.min.js','app/assets/js_to_compile_gateway/platform.js','app/assets/js_to_compile_gateway/SCORM_API_Wrapper.js','app/assets/js_to_compile_gateway/SGAME_GATEWAY.js','app/assets/js_to_compile_gateway']


Expand Down
Loading

0 comments on commit 331d0a6

Please sign in to comment.