House 4 Inform Tutorial

From IFWiki

In 1998, David Cornelson put together a set of Inform 6 source files that would help beginners with their interactive fiction education. They are recreated here.

Jump to any of the source code examples: Tutorial 1 | Tutorial 2 | Tutorial 3 | Tutorial 4 | Tutorial 5 | Tutorial 6 | Tutorial 7 | Tutorial 8

Return to main article: House Tutorial (Inform)

   ! ------------------------------------------------------------------------------
   ! Inform for New Writers
   !
   ! The House - Version 4
   !
   ! Last Modified: David Cornelson - 22-Jan-1998
   !
   ! This work is freely offered to the Public Domain. - DAC 12-12-2015
   !
   ! ------------------------------------------------------------------------------
   
   Constant DEBUG;
   
   Constant Story "The House";
   
   Constant Headline
              "^Inform for New Writers^
                The House - Version 4^
                By New Writer (1998) - Last Compiled: 22-Jan-1998^";
   
   Constant MAX_SCORE 100;
   Serial "980122";
   
   Release 2;
   
   Include "Parser";
   Include "VerbLib";
   
   !-------------------------------------------------------------------------------
   ! Initialise
   !
   !-------------------------------------------------------------------------------
   
   [ Initialise;
   
     location = Sidewalk;
   
   ];
   
   [ PrintRank;
     print ", earning you the rank of ";
     if (score >= 100) "the greatest.";
     if (score >= 80) "above average.";
     if (score >= 60) "average.";
     if (score >= 40) "below average.";
     if (score >= 20) "the barely living.";
     "the living dead.";
   ];
   
   ! ----------------------------------------------------------------------------
   ! Locations
   !
   ! In this section we will define our locations. These are "Objects" to Inform.
   !
   ! ----------------------------------------------------------------------------
   
   Object Sidewalk "Sidewalk"
       with  description
             "You are standing on the sidewalk in front of a house to the west.",
       w_to  Front_Porch,
       has   light;
   
   Object Front_Porch "Front Porch"
       with  description
             "This is the front porch of the house. There are two doors
              leading inside. The door on the left leads west and the
              door on the right leads northwest.",
       e_to  Sidewalk,
       w_to  Left_Front_Door,
       in_to Left_Front_Door,
       nw_to Right_Front_Door,
       has   light;
   
   Object -> Left_Front_Door "left front door"
       with    name "left" "front" "door",
               description
               "The left front door is made of brass.",
       when_open    "The left front door is open.",
       when_closed    "The left front door is closed.",
       door_to        Foyer,
       door_dir    w_to,
       has            static door openable;
   
   Object Right_Front_Door "right front door"
       with    name "right" "front" "door",
               description
               "The right front door is made of wood.",
       when_open    "The right front door is open.",
       when_closed    "The right front door is closed.",
       door_to        [; if (location==Front_Porch) return Den; return Front_Porch; ],
       door_dir    [; if (location==Front_Porch) return nw_to; return se_to; ],
       found_in    Front_Porch Den,
       with_key    right_key,
       has            static door openable lockable locked;
   
   !
   ! VERSION 4 - Cause and Effect. Things happen based on what a player does.
   !
   ! In this version of The House, we're going to add an object, the rock, and
   ! a place where the rock is useful. Unlike version 3 where Inform provides
   ! a special 'door' object, we must provide our own logic to 'handle' the rock.
   ! 
   ! To do this, we're going to use what are called 'code blocks'. A code block is a
   ! group of statements that combine to handle one particular piece of logic
   !
   ! Code blocks contain a decision and/or a loop. A decision is handled by one of two
   ! Inform statements, the 'if' statement and the 'switch' statement. We'll talk about
   ! the 'switch' statement and 'loops' in later versions of The House.
   !
   ! DECISION STATEMENTS
   !
   ! THE 'if' STATEMENT
   !
   !    The 'if' statement contains a comparison of variables, numbers, and/or text that
   !    provides a true or false result. Based on either result (true or false) another
   !    code block is written to handle the decision.
   !
   !        For example:
   !
   !            if (1==1) {
   !                print "True";
   !            } else {
   !                print "False";
   !            }
   !
   !        In the above example, the word "True" will be printed because the comparison of
   !        1 to 1 is a true statement, 1 certainly does equal 1. If we changed the comparison
   !        to:
   !
   !            if (1==2) {
   !                print "True";
   !            } else {
   !                print "False";
   !            }
   !
   !        ...then "False" would be printed because 1 does not equal 2.
   !
   !        Here are some more examples of valid 'if' statements...
   !
   !            eggs=2;
   !            if (eggs<2) {
   !                print "You don't have enough eggs!";
   !            } else {
   !                print "You have enough eggs!";
   !            }
   !
   !        The above 'if' statement asks if the variable 'eggs' is less than two. If the value
   !        is less than two, print "You don't have enough eggs!", otherwise Inform will print
   !        "You have two eggs, just enough!" (which is the case since we set the variable 'eggs'
   !        to 2 before the 'if' statement).
   !
   !            eggs=2;
   !            bacon=4;
   !            if (eggs<2) {
   !                print "You don't have enough eggs!";
   !                if (bacon<4) {
   !                    print "You don't have enough bacon either!";
   !                } else {
   !                    print "You have four strips of bacon though!";
   !                }
   !            } else {
   !                print "You enough eggs!";
   !                if (bacon<4) {
   !                    print "You don't have enough bacon though!";
   !                } else {
   !                    print "You have four strips of bacon too!";
   !                }
   !            }
   !
   !        In the above example, things get more complicated. I'll rewrite it in english so
   !        that you can understand what is happening. Many programmers start out writing
   !        things in english and they call it 'pseudocode'.
   !
   !            set eggs to 2
   !            set bacon to 4
   !
   !            if there are less than two eggs then
   !                print "You don't have enough eggs!"
   !                if there are less than four bacon then
   !                    print "You don't have enough bacon either!"
   !                else
   !                    print "You have four strips of bacon though!"
   !                end if
   !            else
   !                print "You enough eggs!"
   !                if there are less than four bacon then
   !                    print "You don't have enough bacon though!"
   !                else
   !                    print "You have four strips of bacon too!"
   !                end if
   !            end if
   !
   !    Questions:  Q: Why is there a double equal sign in the 'if' statement?
   !
   !                A: Inform will set variables with one equals sign "=" and compare them
   !                   when you put two equals signs "==" together. This is important to
   !                   remember and can cause a lot of 'bugs' in your code. Another exanple
   !                   explaining this is:
   !
   !                        if (eggs=2) print "There are two eggs.";
   !
   !                   This statement will ALWAYS BE TRUE because eggs is being SET to 2, NOT
   !                   compared.
   !
   !                Q: What are the squiggly brackets, '{' and '}', for?
   !
   !                A: They signify the beginning and end of an 'if' statement code block.
   !                   You need them to group more than one statement together. The left
   !                   squiggly bracket begin the code block and the right squiggly bracket
   !                   ends the code block.
   !
   !                   NOTE: You only need the brackets if you have more than one statement
   !                         in the resulting code block. Another example might be:
   !
   !                            if (eggs==2) {
   !                                print "There are a pair of eggs.";
   !                                bacon=4;
   !                            }
   !                            else
   !                                print "There are ", eggs, " eggs.";
   !
   !                         In the above example, squiggly brackets were only needed for
   !                         the 'true' code block because we have two statements where
   !                         there is only one statement for the 'false' code block.
   !
   !                Q: What are the symbols for 'if' statement comparisons?
   !
   !                A: They are as follows:     ~=    not equal
   !                                            ==    equal
   !                                            <    less than
   !                                            <=    less than or equal
   !                                            >    greater than
   !                                            >=    greater than or equal
   !                                            &&    and
   !                                            ||    or
   !
   !                    The '&&' and '||' symbols are used to combine comparisons. For example:
   !
   !                        if (eggs==2 && bacon==4) print "You have two eggs and four bacon!";
   !
   !                        if (eggs==2 || bacon==4) print "You have either 2 eggs or 4 bacon!";
   !
   
   !
   ! Okay, now let's apply our knowledge of the 'if' statement and write an embedded function
   ! that will handle our rock.
   !
   ! We've placed the rock in the den, but we're going to put the action in the backyard
   ! which is a location we're adding in this version of The House. Skip down by the kitchen for
   ! more...
   !
   
   
   Object Den "Den"
       with    description
               "You are in the den of the house.",
       se_to   Right_Front_Door,
       out_to  Right_Front_Door,
       has     light;
   
   !
   ! This is our rock object.
   !
   ! We've added the property 'before' with the arguments 'PutOn','Insert', and
   ! 'ThrowAt:'. When the rock is thrown at or in anything, this function is executed.
   !
   ! In this case, the object being thrown, rock or keys, is the value of the Inform
   ! variable 'noun'. If noun equals the object 'Rock', then the true code block is
   ! executed, otherwise the false code block is executed.
   !
   ! Q: Why is the statement 'rtrue' placed at the end of both code blocks?
   !
   ! A: Normally, the Inform parser handles the action of an object being thrown at
   !    something else. This is the default processing. If you throw the 'right key'
   !    around The House or at the pond, you'll see the 'default' Inform processing.
   !
   !    Since we wanted special processing for the rock, we handled the actions on
   !    our own through our code. But at the end of handling the thrown rock, we have
   !    to let the Inform parser know that we took care of everything and not to do
   !    anything.
   !
   !    If we return true, Inform understands and leaves everything alone.
   !    If we return false, Inform will execute the default processing.
   !
   !    By the way, rtrue and rfalse are shortcuts to the statements:
   !
   !       return true;
   !       return false;
   !
   !
   ! Q: Why is the variable 'second' being compared to the object name 'Pond'?
   !
   ! A: The variable 'second' is an Inform variable set to the second noun of
   !    of a players statement. For example:
   !
   !           > THROW ROCK AT POND
   !
   !    In this statement, 'rock' is the first noun and Inform determines the object
   !    value for 'rock' and sets the variable 'noun' to that value. For the noun
   !    'pond', Inform determines the object value and sets this in the variable
   !    'second'.
   !
   ! Q: Why is '(the)' before 'second' in the print statement below?
   !
   ! A: This is to force Inform to print the article 'the' before the word. In any
   !    object, you can define the article property with a value, such as "the",
   !    "your", "an", or "some", so that Inform understands how to refer to the
   !    object in sentences.
   !
   
   Object -> Rock "rock"
       with    name "rock",
               description
               "It's smooth and flat, perfect for skipping in a pond.",
       before  [;  Insert,PutOn,ThrowAt:
                       if (second==Pond) {
                           print "The rock skips across the water several times and sinks.
                                  Amazingly, after a few moments, the rock washes up at
                                  your feet. Wow, what an undertow!^";
                           move Rock to Backyard;
                           rtrue;
                           !
                           ! Replace rock so that player can try it again....
                           !
                        } else {
                            print "You throw the rock at ",(the) second, " and bounces
                                   back into your stomach. Ouch! That hurt.^";
                           rtrue;
                        }
               ];
   
   Object Foyer "Foyer"
       with  description
             "You are standing in the foyer of the house. It seems as though
              you can go up a staircase, northwest, or back out the front
              door to the east.",
       out_to Front_Porch,
       e_to   Front_Porch,
       nw_to  Hallway,
       u_to   Upper_Hallway,
       has    light;
   
   Object Hallway "Hallway"
       with   description
              "You are in the hallway on the first floor of the house. The
               foyer is southeast and the kitchen is west of here.",
       se_to  Foyer,
       w_to   Kitchen,
       has    light;
   
   !
   ! We've added out_to and w_to for a connection to the backyard as well as
   ! changing the description to help the player know what's going on.
   !
   
   Object Kitchen "Kitchen"
       with   description
              "This is the kitchen of the house. A hallway can be seen to the
               east and an open doorway to the west leads out to the backyard.",
       e_to    Hallway,
       w_to    Backyard,
       out_to    Backyard,
       has        light;
   
   !
   ! This is our new location. Notice we added the name "yard" in case the player
   ! abbreviates their commands.
   !
   Object Backyard "Backyard"
       with    name "yard",
               description
               "This is the backyard behind the house. There is a pond here.",
       e_to    Kitchen,
       in_to    Kitchen,
       has        light;
   
   !
   ! This is where we plan to use the rock....
   !
   
   Object -> Pond "pond"
       with    name "pond" "water",
               description
               "It's a small pond, but wide enough to skip rocks.",
       has        static concealed container open;
   
   Object Upper_Hallway "Upper Hallway"
       with   description
              "This is the second floor hallway. Rooms can be seen north and
               south and a staircase leads down.",
       n_to   North_Bedroom,
       s_to   South_Bedroom,
       d_to   Foyer,
       has    light;
   
   Object North_Bedroom "North Bedroom"
       with   description
              "This is a bedroom on the north side of the house.",
       s_to   Upper_Hallway,
       has    light;
   
   !
   ! Added the article "the"...
   !
   Object -> right_key "right key" with name "right" "key", article "the";
   
   Object South_Bedroom "South Bedroom"
       with   description
              "This is a bedroom on the south side of the house.",
       n_to   Upper_Hallway,
       has    light;
   
   ! ----------------------------------------------------------------------------
   ! Grammar
   !
   ! The grammar section includes the file "Grammar" and will later include
   ! extensions to the standard grammar library.
   !
   ! ----------------------------------------------------------------------------
   
   Include "Grammar";