CYOA extensions for TADS 3?

While not an extension per se, I do have such a beast implemented in my WIP. It should be packaged into a global function, so here is an untested version of that. First, define numbered list and function:

// custom numbered tall lister, as for selection list
//
class SimpleTallLister: SimpleLister
    showSimpleList(lst) { showListAll(lst, ListTall, 1); }
;
stringTallNumLister: SimpleTallLister
    order = 1
    showListItem (str, options, pov, infoTab) {
        say(order++);
        say('.  ');
        say(str);
    }
    getArrangedListCardinality(singles, groups, groupTab) {
        order = 1;
        return singles.length();
    } 
;

/* =============================================
 *
 *   promptList utility function, prompts user for a number-based
 *        input selection
 *   Parameters:
 *     prompt - Text string prompting user for choice to follow
 *     list - list of strings that are the choices
 *     allowQuit - default true, when true allows user to Q without
 *          making a choice
 *   Returns:
 *     selection value integer, or nil if no selection made
 *     note caller will have to decode results
 *
 * ==================================================
 */
promptList(prompt, list, allowQuit = true) {

    "\n<<prompt>>
        <<stringTallNumLister.showSimpleList(list)>>
        <<if allowQuit>>\n\tQ.  Not now, will choose later.<<end>>
        \nSelect:  ";

    local strSel;
    local intSel;
    local num = list.length();
    do {
        strSel = inputManager.getKey(nil, nil).toUpper();
        intSel = toInteger(strSel);
	    "<<if allowQuit && (strSel == 'Q')>><<strSel>><<else>>
            <<((intSel > 0) && (intSel <= num)) ?
                '<<strSel>> (<<list[intSel]>>)' : 'X\nSelect:  '>><<end>>";
    } while (((strSel != 'Q') || !allowQuit) && ((intSel == 0) || (intSel > num)));

    return (strSel == 'Q' ? nil : intSel);
}

That allows it to be used like this:

    local choiceList = ['Red','Yellow','Green']
    local choice = promptList('To what color?', choiceList);
    if (choice == nil) "Ok, come back later.  ";
    else {
        "You set the traffic light to <<choiceList[choice]>>.  ";
        // any other choice side effects
    }

Which gives results like:

>set [something]
To what color?
       1.  Red
       2.  Yellow
       3.  Green
   Q.  Not now, will choose later.
Select:X // if anything other than 1-3 or Q selected
Select:  1 (Red)
//or
Select: Q
Ok, come back later.

// &etc

Will end up refactoring my code to function, and update if any typos found above.

3 Likes