Blog

CommandBox - Choose your own Adventure

Gavin Pickin March 03, 2015

Spread the word

Gavin Pickin

March 03, 2015

Spread the word


Share your thoughts

CommandBox’s run command is not like a normal function you write. Each piece of the function is run line by line, to give you that interactivity needed for a true command prompt application. To test this side of things, I decided I had 2 choices, build a wizard, or enter the room to the left. Wait a minute, the room to the left, that sounds like one of those Choose your own Adventure stories, where the choices you make, affect the outcome of the story. That’s right… remembering how cool those books were, I decided that would be more fun, so lets see how you can build your own “Choose your own Adventure” command for CommandBox.

First, we create a new CFC with the base requirements of a command.

component extends="commandbox.system.BaseCommand" {
   function run(  ){
     print.line(“WATCH ME RUN”);
  }
 
} 

Lets find a story. I will not expose you to my terrible writing skills, beyond what you are already reading, so I found a Free Article, written by a third grader named Paul Channel, available on this website… we'll use this as our base. 
https://www.teachervision.com/creative-writing/activity/3139.html

So first things first, we need to print out the title of the story, and ask you to start the story.

print.boldGreenLine('The Mystery of the Haunted House, by Paul Channel');
print.line();
print.line("It is summertime again, vacation time. You go to your uncle's house. He takes you on a tour around the city. There are many old buildings, but the oldest of all is on Main Street. The address is 880. He says that it is haunted, but you don't believe him. ");

Now we need to ask, do you go inside? So lets use the ask() method.

var selection1 = ask( 'Do you go inside?' );
if ( selection1 == "Y" || selection1 == "YES"){
     page2();
}
else {
     page3();
} 

We will add those functions to complete the next step of the story. Let’s test our progress. We type R to reload our commandBox console and then run our command

onceUponATime

and we see

Do you go inside?

Where is the rest of the text? We click No and hit enter, and then everything flushes. Strange, not what we wanted. A little research and I have the solution. .toConsole() on the print line will flush it automatically, so lets update it.

function run(  ){
   
    print.boldGreenLine('The Mystery of the Haunted House, by Paul Channel').toConsole();
    print.line().toConsole();
   print.line("It is summertime again, vacation time. You go to your uncle's house. He takes you on a tour around the city. There are many old buildings, but the oldest of all is on Main Street. The address is 880. He says that it is haunted, but you don't believe him. ").toConsole();
   
    var selection1 = ask( 'Do you go inside?' );
    if ( selection1 == "Y" || selection1 == "YES"){
        page2();
    }
    else {
        page3();
    }

}

Much better now.

Ok, so page2()
You say, "I will go inside." He says, "I want to watch you." You start up the stone steps of the old haunted house. You open the door and step inside and suddenly a sharp arrow streaks across in front of you! But it misses you.
Choice: Do you go up the staircase? (turn to page 4)
Or: Do you go through the swinging doors? (go to page 5)

To make it easier for our user, lets try a different interactive method, the waitForKey method, which takes a string, and returns when a key is pressed. It returns an ASCII code, so lets try that out.

var ASCIICode = waitForKey( 'Do you go up the (S)taircase? Or do you go through the Swinging (D)oors?' );

Then we check to see what ascii code is and direct them to page 4 (staircase), page 5 (swinging doors) or repeat the prompt for any other keys.

function page2(){
    
      print.line('You say, "I will go inside." He says, "I want to watch you." You start up the stone steps of the old haunted house. You open the door and step inside and suddenly a sharp arrow streaks across in front of you! But it misses you.').toConsole();
      var ASCIICode = waitForKey( 'Do you go up the (S)taircase? Or do you go through the Swinging (D)oors?');
      if ( ASCIICode == 115 || ASCIICode == 83 ){ // s or S
          print.line().toConsole();
          print.line('You choose the staircase').toConsole();
          page4();
      }
      else if ( ASCIICode == 100 || ASCIICode == 68 ){  // d or D
          print.line().toConsole();
          print.line('You choose the swinging doors').toConsole();
          page5();
      }
      else {
          print.line().toConsole();
          page2();
      }
}

Page3 just simple prints a line, and then returns, to exit the story.

function page3(){
  print.line('You stay there. Then you decide to go home, have an ice cream, and go to bed.');
  return;
  }

Page4 is a sad ending, which prints a line, and does not run any more code, so will return automatically.

function page4(){
  print.line("You go up the stairs. You lean against the railing and it breaks. You fall and that's the end of you.");
}

Page5 is another nail biting decision. Do you choose to enter the closet, or the pathway. This time, we’ll use a Y / N confirm method. The result is evaluated as a boolean, if and else. So we’ll setup the confirm with prompts for Y for Closet, and N for the passageway under the house.

function page5(){
      
    print.line("You go through the swinging doors. You walk through the room.").toConsole();
    if( confirm( 'Do you go into the closet? (Y) Or you go into a passageway under the house (N)' ) ) {
        page6();
    } else {
        page7();
    }
}

The last 2 pages are line outputs, so here they are

function page6(){
    print.line("You go into the closet. You fall through a trapdoor and break your leg. The walls are too smooth to climb. There is no other way up.");
}
 
function page7(){
    print.line("You go into a pasaageway under the house. You make your way along and it leads to a trapdoor that takes you back to where you started from. You meet a policeman at the top and he says to you, ""You were lucky to get out of there. Don't ever go in there again!"" You go home and have some ice cream.");
}

If you put it all together, you get run + 7 page functions, and a fun story written by a 3rd grader.

Check out the code here
https://github.com/gpickin/ChooseYourOwnAdventure/

Try it out for yourself by installing the command:

install onceUponATime

Of course, my use of the interactivity prompts are more for explanation purposes, and could be used much better, but I hope you see some of the power a CommandBox function has, and get you thinking about what your first Command will be.
 

Add Your Comment

Recent Entries

qb 9.0.0 Released

qb 9.0.0 Released

A new major release of qb is now available on ForgeBox! This comes jam-packed with awesome features like new SQLite grammar support and SQLCommenter support to add contextual comments to your queries. Breaking changes include dropping support for older Adobe ColdFusion versions, splitting the uuid SchemaBuilder method, pagination changes when maxRows is 0 or lower, and changes to some default settings.

Eric Peterson
Eric Peterson
February 06, 2023
CBSecurity 3.x Released

CBSecurity 3.x Released

We are incredibly excited to release CBSecurity 3. This is a significant release with over six months of work invested in it. We have completely revamped our security module to make ColdBox applications secure, flexible, and ready for the upcoming ColdBox 7 release. The first major announcement for this release is that we have a brand-new logo!

Luis Majano
Luis Majano
January 30, 2023
CBWIRE 2.2 Released

CBWIRE 2.2 Released

We're excited to announce the release of CBWIRE 2.2. This release includes several added enhancements, such as new lifecycle hooks and simplified Turbo Drive integration. We changed the previous lifecycle hook of mount() to onMount() to be consistent, and several bugs were squashed.

Maria Jose Herrera
Maria Jose Herrera
January 09, 2023