/************************************************************* * test.js.php * * Sets up the experiment and contains all the logic for the * progression of the experiment. The main javascript file that * powers this experiment. * * Author: Willy Xiao * Last Modified: _______ * * Adapted from : Yuechen Zhao * * © Copyright 2013 Intelligent and Interactive Systems * Group, Harvard University. * For questions about this file and permission to use * the code, contact us at info@labinthewild.org *************************************************************/ // for php_gettext var basic = { //** EXPERIMENT VARIABLES, CONSTANTS, AND CONFIGURATIONS **// test_name : "basic", index : null, // expment variables and data collected expment : { // phases of the test phases : new Array ( { type : "practice", instructions : "

Instructions for the Practice Trial for Basic Test

Remember, this is only for practice. Your results will be discarded.

You will see a slide of anywhere between 1 - 6 symbols flash on your screen. Memorize the set of symbols (you need not remember their order).

set

Then, you will see a another image like the one shown below.
probeDecide whether or not the symbol was part of the previous set and move your mouse to either the [check] or the [x] to indicate Yes or No.

Remember, your goal is to answer correctly as quickly as possible. You may find it useful to press 1 on your keyboard for Yes and 0 for No to increase your speed.

Note : If you choose to use your mouse instead of your keyboard, you will have to recenter it after each trial on the red target: mouse_centerPress next when you're ready to begin the practice.

", numTrials : 1, }, { type : "trial", instructions : "



Great Job! :)


Now for the real deal. It'll be the same as the practice you just took, but with 20 trials.

When you're ready, press next to begin the test.

", numTrials : 1, } ), // an array to hold all of the trials, will be populated by setup trials : [ [], [] ], // array for the results of the non-practice trials results : [ [], [] ], }, // variables needed to proceed with test vars : { // chain of functions ch : null, // current phase of test 0-indexed phase : 0, // some counts used later in the test total_num_symbols : 0, total_num_phases : 0, }, config : { // the symbols that will be shown or tested symbols : "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(''), // keyboard input codes for one and zero (normal numbers and numpad) true_codes : new Array(49, 97), false_codes : new Array(48, 96), min_stims : 1, max_stims : 6, stimDuration : 1000, itiDuration : 500, waitDuration : 500, feedbackDuration : 1000, }, //** SETUP (including initializations) AND PRELOADING ITEMS CALLED BY INDEX **// setup : function(test_index) { console.log(this.test_name + " is setting up..."); /* INITIALIZATIONS */ // initializing a number of different variables this.vars.total_num_symbols = this.config.symbols.length; this.vars.total_num_phases = this.expment.phases.length; /* SETUP-PROPER */ // alias for phases var phases = this.expment.phases; // populate the different phases of the trials for(n in phases) { // first get the instructions this.expment.trials[n] = [{type : "inst", html : phases[n].instructions}]; var type = phases[n].type; var total_in_set = this.vars.total_num_symbols; // var total_set_str = this.config.symbols.toString(); for(var i = 0; i < phases[n].numTrials; i++) { // some necessary components to record and for starting the set var trial_num = i; var response_required = this.isPosResponse(); var total_in_stim = getRandomInt(this.config.min_stims, this.config.max_stims); var stim_set = this.getRandomSet(total_in_stim); // var stim_set_str = stim_set.toString(); var probe = this.getProbe(response_required, stim_set); // put this on to the end of the experiment this.expment.trials[n].push( { of_test : basic.test_name, type : type, trial_num : trial_num, response_required : response_required, stim_set : stim_set, stim_time : this.config.stimDuration, wait_time : this.config.waitDuration, total_in_stim : total_in_stim, probe : probe, total_in_set : total_in_set }); } } console.log(this.test_name + " is done setting up!"); }, preload_arr :[], preload_helper : function () { console.log(this.test_name + " is preloading..."); // alias var trials = this.expment.trials; // load in the html for the different stims for(phase in trials) { for(n in trials[phase]) { var current_trial = trials[phase][n]; if (current_trial.type != "inst") { var stim_html = "
"; for(i in current_trial.stim_set){stim_html += current_trial.stim_set[i] + " ";} stim_html += "
"; $("#stims").append(stim_html); var probe_html = "
"; probe_html += current_trial.probe; probe_html += "
"; $("#probes").prepend(probe_html); } } } console.log(this.test_name + " is done preloading!"); return; }, //** PRELOADING HELPER FUNCTIONS **// // determines whether a positive or negative response should be required isPosResponse : function () { return (getRandomInt(0,1) == 1); }, // gets a random set from this.config.symbols of length "num" getRandomSet : function(num) { var return_set = new Array(); var index; do { index = getRandomInt(0, (this.vars.total_num_symbols - 1)); if (!arrayContains(return_set, this.config.symbols[index])) { return_set.push(this.config.symbols[index]); } } while(return_set.length < num) return return_set; }, // gets a probe to test the individual. if response_required, then will return something in the set // otherwise will return something outside of the set getProbe : function(pos_response_required, set) { if (pos_response_required) { var randomIndex = getRandomInt(0, (set.length - 1)); return set[randomIndex]; } else { var symbol = ""; do { var randomIndex = getRandomInt(0, (this.vars.total_num_symbols - 1)); symbol = this.config.symbols[randomIndex]; } while (arrayContains(set, symbol)); return symbol; } }, //** CHAIN OF FUNCTIONS TO RUN DURING TRIALS, CALLED BY nextTrial IN pages.js.php **// // must uses test_name.method rather than this.method nextTrialChain : function (trial) { return new Array ( function () { hideNextButton(); showSlide("empty"); $("#stims").children().hide(); $("#probes").children().hide(); $("#response").show(); $("#" + trial.of_test + trial.type + trial.trial_num).show(); $("#" + trial.of_test + trial.type + trial.trial_num + "response").show(); $$$("heading").innerHTML = "

" + (basic.vars.phase == 0 ? "Practice" : "Part " + basic.vars.phase + "/" + globals.tests.length) + "

"; $$$("progress").innerHTML = "" + "Progress: " + (trial.trial_num + 1) + " / " + basic.expment.phases[basic.vars.phase].numTrials; }, this.config.itiDuration, function () { showSlide("stims"); }, this.config.stimDuration, function() { showSlide("empty"); }, this.config.waitDuration, function () { // function used to record responses - called by handlers var record_response = function(pos_response, type_of_response) { input.rt = (new Date()) - rt_start; input.response = pos_response; input.type = type_of_response; remove_my_listeners(); basic.processResponse(input, trial); } // handlers for input from user var yes_handler = function(e) {record_response(true, "mouse")}; var no_handler = function(e) {record_response(false, "mouse")}; var keyboard_handler = function(e) { var in_pos = arrayContains(basic.config.true_codes, e.keyCode); var in_neg = arrayContains(basic.config.false_codes, e.keyCode); if (in_pos || in_neg) record_response(in_pos, "keyboard"); } // bind the handlers $("#yes_response").bind("mouseover", yes_handler); $("#no_response").bind("mouseover", no_handler); $(document).bind("keydown", keyboard_handler); // a function used to remove handlers after events are triggered var remove_my_listeners = function() { $(document).unbind("keydown", keyboard_handler); $("#yes_response").unbind('mouseover', yes_handler); $("#no_response").unbind('mouseover', no_handler); } showSlide("probes"); var rt_start = new Date(); var input = {}; } ); }, // processes response processResponse : function(input, trial) { // if there's a chain of timeouts, clear them all if(this.vars.ch) clearChain(this.vars.ch); $("#response").hide(); var feedback_html = (trial.response_required == input.response ? "

" + 'Correct!' + "

" + (input.rt / 1000.0) + " seconds

" : "

" + 'Incorrect!' + "

") $("#feedback").html(feedback_html); $("#feedback").show(); var result = trial; result.rt = input.rt; result.input_response = input.response; result.input_type = input.type; this.expment.results[this.vars.phase].push(result); var mouse_handler = function(e) { $("#mouse_center").hide(); $("#mouse_center").children("img").unbind('mouseover', mouse_handler); nextTrial(basic); }; setTimeout(function() { $("#feedback").hide(); $("#feedback").empty(); if (input.type == 'mouse') { $("#mouse_center").show(); $("#mouse_center").children("img").bind('mouseover', mouse_handler); } else { nextTrial(basic); } }, basic.config.feedbackDuration); }, //** FINISHING ITEMS FOR WHEN EXPERIMENT IS DONE **// submit : function() { /*$.ajax({ type: 'POST', url: 'includes/data.php', data: { participant_id: vars.participant_id, participant_country: vars.participant_country, results: JSON.stringify(expment.results) } }).done( function (data) { filter_high(); calculate(); results(); });*/ console.log(this.expment.results); this.results_html = "
" + this.expment.results + "
"; }, // will hold the html for the results later results_html : "
little bobby!
", }