little_professor_main.lsl
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2012 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
// Notecard reader
key nQuery = NULL_KEY;
integer nLine = 0;
list questions = [];
list answers = [];
list notecards = [];
string nc = "";
string ua = "";
 
default
{
    state_entry() {
        integer itra = llGetInventoryNumber(INVENTORY_NOTECARD)-1;
        if(itra == -1) {
            llOwnerSay("Failed to read questions notecard.");
            return;
        }
        do {
            notecards += llGetInventoryName(INVENTORY_NOTECARD, itra);
        } while(--itra>-1);
        nc = llList2String(notecards, 0);
        notecards = llDeleteSubList(notecards, 0, 0);
        nLine = 0;
        nQuery = llGetNotecardLine(nc, nLine);
    }
    dataserver(key id, string data) {
        if(id != nQuery) return;
        if(data == EOF) {
            if(llGetListLength(notecards) == 0) jump all_read;
            nc = llList2String(notecards, 0);
            notecards = llDeleteSubList(notecards, 0, 0);
            nLine = 0;
            nQuery = llGetNotecardLine(nc, nLine);
            return;
@all_read;
            state permute;
        }
        if(data == "") jump next_line;
        list qa = llParseString2List(data, ["="], []);
        questions += llList2String(qa, 0);
        answers += llList2String(qa,1);
@next_line;
        nQuery = llGetNotecardLine(nc, ++nLine);
    }
    changed(integer change) {
        if(change & CHANGED_INVENTORY) llResetScript();
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state quiz {
    state_entry() {
        llMessageLinked(LINK_ROOT, 204000,"                                       ","0");
        llMessageLinked(LINK_ROOT, 204000, llList2String(questions, 0) + "=", "0");
    }
    link_message(integer sender_num, integer num, string str, key id) {
        if(sender_num == 1) return;
        llMessageLinked(LINK_ROOT, 204000,"                                       ","0");
        if(str == "C") {
            ua = "";
            jump reset;
        }
        ua+=str;
@reset;
        llMessageLinked(LINK_ROOT, 204000, llList2String(questions, 0) + "=" + ua, "0");
        if(ua != llList2String(answers, 0)) return;
        state permute;
    }
    changed(integer change) {
        if(change & CHANGED_INVENTORY) llResetScript();
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state permute {
    state_entry() {
        ua = "";
        integer r = (integer)llFrand(llGetListLength(questions));
        do { 
            // Permute questions
            string q = llList2String(questions, 0);
            questions = llDeleteSubList(questions, 0, 0);
            questions += q;
            // Permute answers
            string a = llList2String(answers, 0);
            answers = llDeleteSubList(answers, 0, 0);
            answers += a;
        } while(--r>-1);
        state quiz;
    }
    changed(integer change) {
        if(change & CHANGED_INVENTORY) llResetScript();
    }
    on_rez(integer num) {
        llResetScript();
    }
}