View Source Document

swl.js

/*
 * SUPER WUMPUS LAND v1.1-2015.0721 (Javascript version)
 * Copyright (c)2013-2015, Chris Pressey, Cat's Eye Technologies.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 *  1. Redistributions of source code must retain the above copyright
 *     notices, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notices, this list of conditions, and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *  3. Neither the names of the copyright holders nor the names of their
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
*/

function launch(prefix, containerId) {
    var deps = [
        "playfield.js",
        "cursor.js",
        "playfield-canvas-view.js",
        "text-terminal.js",
        "line-input-buffer.js",
        "element-factory.js"
    ];
    var loaded = 0;
    for (var i = 0; i < deps.length; i++) {
        var elem = document.createElement('script');
        elem.src = prefix + deps[i];
        elem.onload = function() {
            if (++loaded == deps.length) {
                var container = document.getElementById(containerId);
                var canvas = yoob.makeCanvas(container, 400, 400);
                canvas.tabIndex = "0";
                canvas.style.background = "black";
                canvas.style.border = "5px solid black";

                var t = new yoob.TextTerminal().init(80, 25);
                var view = t.createPlayfieldCanvasView(canvas, 11, 18);
                var swl = new SuperWumpusLand();
                swl.init(t);
                var ib = new yoob.LineInputBuffer().init(canvas, t);
                ib.onupdate = function(str) {
                    view.draw();
                };
                ib.onenter = function(str) {
                    swl.handleInput(str);
                    view.draw();
                };
                view.draw();
                canvas.focus();
            }
        };
        document.body.appendChild(elem);
    }
}

function d(n, s) {
  var c = 0;
  while (n > 0) {
      c += Math.floor(Math.random() * s) + 1;
      n--;
  }
  return c;
}

function rep(ch, num) {
    s = "";
    for (var i = 0; i < num; i ++) {
        s += ch;
    }
    return s;
}

function rjust(str, width) {
    str = '' + str;
    if (str.length >= width) return str;
    return rep(' ', width - str.length) + str;
}

Room = function() {
    this.init = function(desc, exits) {
        this.desc = desc;
        this.exits = exits;
        this.arrows = 0;
        this.carcasses = 0;
        this.cans = 0;
        this.tokens = 0;
        this.guano = 0;
        this.bats = 0;
        this.pits = 0;
    };
};

Wumpus = function() {
    this.init = function() {
        this.room = d(1, 100);
        this.asleep = (d(1, 2) === 1);
    };
}

SuperWumpusLand = function() {
    this.init = function(tty) {
        this.tty = tty;
        this.resetGame();
        this.splash();
        this.pause('stateAskName');
    };

    this.resetGame = function() {
        this.rooms = [];
        this.visited = [];
        this.wumpi = [];
        this.itinerary = [];

        this.roomNo = 0;

        this.arrows = 0;
        this.hides = 0;
        this.cans = 0;
        this.tokens = 0;

        this.batbgon = 0;
        this.codliver = 0;
        this.camo = 0;
        this.grip = 0;
        this.ustink = 0;

        this.subway = 0;
        this.subwayTurns = 0;

        this.skip = false;
        this.moved = false;

        var loc_adj = [
          'Rocky',
          'Stony',
          'Dusty',
          'Scenic',
          'Dreary',
          'Scorched',
          'Ruinous',
          'Breezy',
          'Humid',
          'Depressing'
        ];

        var loc_noun = [
          'Plain',
          'Steppes',
          'Path',
          'Trail',
          'Passage',
          'Foothills',
          'Cave',
          'Cavern',
          'Ravine',
          'Expanse'
        ];

        var backlinks = [];
        for (var i = 0; i < 10; i++)
        {
            for (var j = 0; j < 10; j++)
            {
                var r = i * 10 + j + 1;
                var r1 = d(1,100);
                var r2 = d(1,100);
                var r3 = d(1,100);
                var room = new Room();
                room.init(loc_adj[i] + ' ' + loc_noun[j], [r1, r2, r3]);
                this.rooms[r] = room;
                backlinks.push([r1, r]);
                backlinks.push([r2, r]);
                backlinks.push([r3, r]);
            }
        }

        for (var i = 0; i < backlinks.length; i++) {
            var src = backlinks[i][0];
            var dest = backlinks[i][1];
            var exit = Math.floor(Math.random() * 3);
            this.rooms[src].exits[exit] = dest;
        }

        for (var i = 0; i < 42; i++)
        {
            if (i < 33) { this.rooms[d(1,100)].arrows++; }
            if (i < 15) { this.rooms[d(1,100)].cans++; }
            if (i < 10) { this.rooms[d(1,100)].tokens++; }
            this.rooms[d(1,100)].guano++;
        }

        for (var i = 0; i < 5; i++)
        {
            this.wumpi[i] = new Wumpus();
            this.wumpi[i].init();
        }
        for (var i = 0; i < 11; i++)
        {
            this.rooms[d(1,100)].bats = 1;
        }
        for (var i = 0; i < 7; i++)
        {
            this.rooms[d(1,100)].pits = 1;
        }

        this.roomNo = d(1,100);
        this.arrows = 1;
    };

    this.splash = function() {
        this.tty.reset();
        var self = this;
        var print = function(str) {
            self.tty.write(str);
        };
        print(rep('*', 72) + "\n");
        for (var i = 1; i <= 20; i++) {
            if (i === 6)
                print("*                S U P E R     W U M P U S     L A N D                 *\n");
            else if (i === 7)
                print("*                ---------     -----------     -------                 *\n");
            else if (i === 9)
                print("*                            v1.1-2015.0721                            *\n");
            else if (i === 10)
                print("*                         (Javascript version)                         *\n");
            else if (i === 14)
                print("*              by Chris Pressey, Cat's Eye Technologies                *\n");
            else if (i === 16)
                print("*              Based on an original game by Gregory Yob                *\n");
            else
                print("*" + rep(' ', 70) + "*\n");
        }
        print(rep('*', 72) + "\n");
    };

    this.score = function() {
        this.tty.reset();
        var self = this;
        var print = function(str) {
            self.tty.write(str);
        };
        print("Scorecard for " + this.name + "\n");
        print(rep('=', 14 + this.name.length) + "\n\n");

        var scoreHides = this.hides * 25;
        print("Wumpus Hides       " +
              rjust(this.hides, 3) +
              " x  25 = " +
              rjust(scoreHides, 9) +
              "\n");

        var scoreArrows = this.arrows * 2;
        print("Arrows Remaining   " +
              rjust(this.arrows, 3) +
              " x   2 = " +
              rjust(scoreArrows, 9) +
              "\n");

        var scoreCans = this.cans * 3;
        print("Aerosol Cans       " +
              rjust(this.cans, 3) +
              " x   3 = " +
              rjust(scoreCans, 9) +
              "\n");

        var scoreTokens = this.tokens * 5;
        print("Subway Tokens      " +
              rjust(this.tokens, 3) +
              " x   5 = " +
              rjust(scoreTokens, 9) +
              "\n");

        var scoreLocations = 0;
        for (var i = 1; i <= 100; i++) {
            if (this.visited[i]) scoreLocations++;
        }
        print("Locations Visited  " +
              rjust(scoreLocations, 3) +
              " x   1 = " +
              rjust(scoreLocations, 9) +
              "\n");

        var scoreTotal = scoreHides + scoreArrows + scoreCans + scoreTokens + scoreLocations;
        print("                               ---------\n");
        print("Total                          " + rjust(scoreTotal, 9) + "\n\n");
    };

    this.pause = function(nextState) {
        this.tty.write("\n[Press ENTER to continue.]  ");
        this.gameState = nextState;
    };

    this.show = function() {
        var room = this.rooms[this.roomNo];
        var desc = this.roomNo + '. ' + room.desc;

        var self = this;
        var print = function(str) {
            self.tty.write(str);
        };

        this.tty.reset();

        this.visited[this.roomNo] = 1;
        print(desc);
        if (this.subway > 0) {
            print(" (aboard subway train)");
        }
        print("\n");

        print(rep('-', desc.length));
        print("\n\n");

        if (room.arrows === 1) {
          print("There is an arrow lying here.\n");
        } else if (room.arrows > 0) {
          print("There are " + room.arrows + " arrows lying here.\n");
        }

        if (room.carcasses === 1) {
            print("There is a dead Wumpus carcass here.\n");
        } else if (room.carcasses > 1) {
            print("There are " + room.carcasses + " dead carcasses of ex-Wumpi here.\n");
        }

        if (room.cans === 1) {
            print("There is an unlabelled aerosol can here.\n");
        } else if (room.cans > 1) {
            print("There are " + room.cans + " unlabelled aerosol cans here.\n");
        }

        if (room.tokens === 1) {
            print("A subway token lies on the ground here.\n");
        } else if (room.tokens > 1) {
            print("" + room.tokens + " subway tokens lie on the ground here.\n");
        }

        if (room.guano > 0) {
            print("\nThere is a ");
            if (room.guano === 1) { print("small"); }
            else if (room.guano === 2) { print("sizable"); }
            else if (room.guano === 3) { print("large"); }
            else if (room.guano === 4) { print("huge"); }
            else { print("gigantic"); }
            print(" pile of Wumpus dung here.\n");
        }

        print("\n");

        var smellWumpus = false;
        for (var i = 0; i < this.wumpi.length; i++) {
            if (this.wumpi[i].room === this.roomNo) {
                if (!this.wumpi[i].asleep) {
                    if (this.subway > 0) {
                        print("* Right outside the train window is a Wumpus!\n");
                    } else if (this.camo) {
                        print("* Good thing the Wumpus here can't see you.\n");
                    } else {
                        print("* Oh No, " + this.name + "!  A Wumpus ATE YOU UP!!!\n");
                        if (this.codliver > 0) {
                            print("  ...and immediately BARFED YOU BACK OUT!!!!\n");
                        } else {
                            this.pause('stateGameOver');
                            return false;
                        }
                    }
                } else {
                    print("* There's a Wumpus asleep RIGHT IN FRONT OF YOU!!\n");
                }
            }
            for (var exit = 0; exit < 3; exit++) {
                if (room.exits[exit] === this.wumpi[i].room) {
                    smellWumpus = true;
                    break;
                }
            }
        }
        if (smellWumpus && !this.ustink) {
            print("* I smell a Wumpus!\n");
        }

        if (room.bats > 0) {
            if (this.subway > 0) {
                print("* Super Bats flutter out of the path of the subway train.\n");
            } else if (this.batbgon > 0) {
                print("* Super Bats in this location stay well away from your awful stench!\n");
            } else {
                print("* Zap!  Super Bat Snatch!  Elsewheresville for you!\n");
                this.roomNo = d(1,100);
                this.skip = 1;
                this.pause('statePrompt');
                return false;
            }
        }
        var batsNearby = false;
        for (var i = 0; i <= 2; i++)
        {
            if (this.rooms[room.exits[i]].bats > 0)
                batsNearby = true;
        }
        if (batsNearby) {
            print("* Bats nearby!\n");
        }

        if (room.pits > 0) {
            if (this.subway > 0) {
                print("* The subway rails take a curving path around a bottomless pit here.\n");
            } else if (this.grip > 0) {
                print("* You deftly stick to the edge of the bottomless pit!\n");
            } else {
                print("* Yiiiieeee!!!  Fell in a pit!\n");
                this.pause('stateGameOver');
                return false;
            }
        }
        var aDraft = false;
        for (var i = 0; i <= 2; i++)
        {
            if (this.rooms[room.exits[i]].pits > 0)
                aDraft = true;
        }
        if (aDraft) {
            print("* I feel a draft...\n");
        }

        print("\nFrom here you can make passage to\n");
        for (var i = 0; i <= 2; i++)
        {
          print("  [" + room.exits[i] + "] ");
          if (this.visited[room.exits[i]]) {
              print(this.rooms[room.exits[i]].desc);
              if (this.rooms[room.exits[i]].bats > 0) { print(" (Bats)"); }
              if (this.rooms[room.exits[i]].pits > 0) { print(" (Pit)"); }
              print("\n");
          } else
          {
              print("(not yet visited)\n");
          }
        }
        print("\n");
        return true;
    };

    this.ask = function() {
        var room = this.rooms[this.roomNo];
        var self = this;
        var print = function(str) {
            self.tty.write(str);
        };

        if (this.arrows === 1)
        {
          print("  [F]ire your crooked arrow\n");
        }
        else if (this.arrows > 1)
        {
          print("  [F]ire one of your " + this.arrows + " crooked arrows\n");
        }

        if (this.cans === 1)
        {
          print("  [A]pply the contents of the aerosol can on yourself\n");
        }
        else if (this.cans > 0)
        {
          print("  [A]pply one of your " + this.cans + " aerosol cans on yourself\n");
        }

        if (this.tokens == 1)
        {
          print("  [R]ide the subway with your token\n");
        }
        else if (this.tokens > 0)
        {
          print("  [R]ide the subway with one of your " + this.tokens + " tokens\n");
        }

        if (room.arrows > 0 || room.cans > 0 || room.tokens > 0)
        {
          print("  [P]ick up the items from this location\n");
        }

        if (room.carcasses === 1)
        {
          print("  [S]kin the ex-Wumpus for it's hide\n");
        }
        else if (room.carcasses > 1)
        {
          print("  [S]kin the ex-Wumpi for their hides\n");
        }
        if (room.guano > 0)
        {
          print("  [D]ig through the Wumpus dung looking for items\n");
        }

        print("  [I]nventory and Score\n\n");
        print("  [Q]uit\n\n");
        print("What would you like to do next, " + this.name + "?  ");

        this.gameState = 'stateProcessCommand';
    };

    this.moveWumpi = function() {
        var self = this;
        var print = function(str) {
            self.tty.write(str);
        };

        for (var i = 0; i < this.wumpi.length; i++) {
            var wumpus = this.wumpi[i];
            if (wumpus.room === 0) {
                if (d(1, 5) === 1) {
                    // restart wumpus
                    wumpus.room = d(1, 100);
                    while (wumpus.room === this.roomNo) {
                        wumpus.room = d(1, 100);
                    }
                    wumpus.asleep = false;
                }
                continue;
            }
            if (wumpus.asleep) {
                if (d(1, 4) === 1) {
                    wumpus.asleep = false;
                    if (d(1, 5) !== 1) {
                        this.rooms[wumpus.room].guano++;
                    }
                }
            } else {
                if (d(1, 3) === 1) {
                    var dest = this.rooms[wumpus.room].exits[d(1,3)-1];
                    if (dest !== this.roomNo || !this.moved) {
                        wumpus.room = dest;
                        if (dest === this.roomNo) {
                            print("From around a corner, a hungry-looking Wumpus appears!!\n");
                            this.pause();
                        }
                    }
                }
                if (d(1,8) === 1) { wumpus.asleep = true; }
                if (d(1,8) === 1) { this.rooms[wumpus.room].guano++; }
            }
        }
    };

    this.entropy = function() {
        var self = this;
        var message = false;
        var print = function(str) {
            self.tty.write(str);
            message = true;
        };
        if (this.batbgon > 0) {
            this.batbgon--;
            if (this.batbgon == 1) { print("Your \"Bat-B-Gon\" is wearing off.\n"); }
            if (this.batbgon == 0) { print("Your \"Bat-B-Gon\" has worn off.\n"); }
        }
        if (this.codliver > 0) {
            this.codliver == 1;
            if (this.codliver == 1) { print("The cod liver oil seems to be wearing off.\n"); }
            if (this.codliver == 0) { print("The cod liver oil seems to have all worn off.\n"); }
        }
        if (this.camo > 0) {
            this.camo--;
            if (this.camo == 1) { print("Your camoflage is peeling.\n"); }
            if (this.camo == 0) { print("Your camoflage is gone.\n"); }
        }
        if (this.grip > 0) {
            this.grip--;
            if (this.grip == 1) { print("Your hands and feet are starting to feel less sticky.\n"); }
            if (this.grip == 0) { print("Your hands and feet are no longer sticky.\n"); }
        }
        if (this.ustink > 0) {
            this.ustink--;
            if (this.ustink == 0) { print("Your sense of smell seems to have returned.\n"); }
        }
        return message;
    };

    // returns true if you didn't die
    this.fireArrow = function() {
        var self = this;
        var print = function(str) {
            self.tty.write(str);
        };
        print("Twang!... ");
        this.arrows--;

        var arrowLoc = this.roomNo;
        while (this.itinerary.length > 0) {
            var arrowDest = this.itinerary.shift();
            var room = this.rooms[arrowLoc];
            if ((arrowLoc === arrowDest) ||
                (room.exits[0] === arrowDest) ||
                (room.exits[1] === arrowDest) ||
                (room.exits[2] === arrowDest)) {
                arrowLoc = arrowDest;
                for (var i = 0; i < this.wumpi.length; i++) {
                    var wumpus = this.wumpi[i];
                    if (wumpus.room === arrowLoc) {
                        print("...*SPLAK*!  Got something!\n");
                        wumpus.room = 0;
                        this.rooms[arrowLoc].carcasses++;
                        return true;
                    }
                }
                if (arrowLoc === this.roomNo) {
                    print("...*ZOINKS!*\n\nYou shot yourself in the foot, " + this.name + "!!!\n");
                    return false;
                }
                print("...whoosh... ");
            } else {
                print("...*clang*\n\n");
                this.itinerary = [];
                if (d(1, 3) === 1) room.arrows++;
                return true;
            }
        }

        var room = this.rooms[arrowLoc];
        if (room.pits === 0) {
            print("...*thud*");
            room.arrows++;
        }
        return true;
    };

    /* -*-*-*- GAME STATES -*-*-*- */

    this.stateAskName = function(input) {
        this.tty.reset();
        this.tty.write("\n\n\n\n\n\n\n\n\n\n\n                 What is your name?  ");
        this.gameState = 'stateReadName';
    };

    this.stateReadName = function(input) {
        this.name = input;
        if (this.name === '') {
            this.name = ["Cuddles", "Sweetie-Pie", "Snookums", "Honeybunch"][d(1,4)-1];
            this.tty.write("  Fine, I'll just call you " + this.name + " then.\n");
            this.pause('statePrompt');
        } else {
            this.statePrompt(input);
        }
    };

    this.statePrompt = function(input) {
        if (this.show()) {
            this.ask();
        }
    };

    this.stateArrowPrompt = function(input) {
        var self = this;
        var print = function(str) {
            self.tty.write(str);
        };
        var dest = parseInt(input, 10);
        if (isNaN(dest)) {
            print("Not a valid location, try again> ");
            this.gameState = 'stateArrowPrompt';
        } else if (dest === 0) {
            if (this.fireArrow()) {
                this.pause('statePrompt');
            } else {
                this.gameState = 'stateGameOver';
            }
        } else {
            this.itinerary.push(dest);
            print("Enter next location to fire into, or 0 to commence> ");
            this.gameState = 'stateArrowPrompt';
        }
    };

    this.stateSubwayPrompt = function(input) {
        var self = this;
        var print = function(str) {
            self.tty.write(str);
        };
        var dest = parseInt(input, 10);
        if (isNaN(dest) || dest < 1 || dest > 100) {
            print("OK, keep your token, if that's the way you feel.\n");
            this.pause('statePrompt');
        } else {
            this.tokens--;
            this.subway = dest;
            this.subwayTurns = 3;
            print("\n  \"All aboard!\"\n\n");
            this.pause('stateRidingSubway');
        }
    };

    this.stateRidingSubway = function(input) {
        var self = this;
        var print = function(str) {
            self.tty.write(str);
        };
        this.roomNo = d(1, 100);
        this.show();
        this.subwayTurns--;
        if (this.subwayTurns === 0) {
            print("\n  \"Next stop, " + this.subway + ", " + this.rooms[this.subway].desc + "...\"\n\n");
            this.roomNo = this.subway;
            this.subway = 0;
            this.pause('statePrompt');
        } else {
            print("\n  ...chug chug...\n\n");
            this.pause('stateRidingSubway');
        }
    };

    this.stateGameOver = function(input) {
        this.score();
        this.tty.write("\nYou want to play again, right, " + this.name + "?  ");
        this.gameState = 'stateAskPlayAgain';
    };

    this.stateAskPlayAgain = function(input) {
        if (input.length > 0 && (input.substr(0, 1) === 'y' || input.substr(0, 1) === 'Y')) {
            this.resetGame();
            this.statePrompt();
        } else {
            this.gameState = 'stateBroken';
        }
    };

    this.stateProcessCommand = function(input) {
        var self = this;
        var print = function(str) {
            self.tty.write(str);
        };
        var room = this.rooms[this.roomNo];

        input = input.toUpperCase();
        if (input === 'Q') {
            this.pause('stateGameOver');
            return;
        } else if (input === 'I') {
            this.score();
            this.pause('statePrompt');
            return;
        } else if (input === 'A' && this.cans > 0) {
            this.cans--;
            print("\n  * * * *** fshhhhhhhhhhfft *** * * *\n\n");
            //sleep 1;
            print("  Turns out it was ... ");
            //sleep 2;
            var c = d(1, 7);
            if (c === 1) {
              print("new car smell!\n");
            } else if (c === 2) {
              print("\"Bat-B-Gon!\"\n");
              this.batbgon += d(4,4);
            } else if (c === 3) {
              print("pepper spray!!!!  AIIIGGGGHHHH!!!\n\n");
              //sleep 1;
              print("  AAAAIIIIIIIIIIIIIIGGGGGGHHHHH!!!\n\n");
              //sleep 2;
              print("  AAAAAAAIIIIIIIIIIIIIIIIIIIIGGGGGGGGHHHHHH!!!\n\n");
              //sleep 3;
              print("  AAAAAAAAAAIIIIIIIIIIIIIIIIIIIIIIIIIIGGGGGGGGGGHHHHHHH!!!\n\n");
              //sleep 4;
              print("You run around screaming for a while until the burning subsides...\n");
              this.roomNo = d(1,100);
            } else if (c === 4) {
              print("\"Super Sticky Grip Goop\"!\n");
              this.grip += d(4,4);
            } else if (c === 5) {
              print("cod liver oil!\n");
              this.codliver += d(4,4);
            } else if (c === 6) {
              print("camoflage paint!\n");
              this.camo += d(4,4);
            } else if (c === 7) {
              print("\"E-Z-F Oven Cleaner!\"\n");
              if (this.grip > 0) this.grip = 1;
              if (this.camo > 0) this.camo = 1;
              if (this.codliver > 0) this.codliver = 1;
              if (this.batbgon > 0) this.batbgon = 1;
            }
            this.pause('statePrompt');
            return;
        } else if (input === 'F' && this.arrows > 0) {
            this.itinerary = [];
            print("Enter the first location to fire into> ");
            this.gameState = 'stateArrowPrompt';
            return;
        } else if (input === 'S' && room.carcasses > 0) {
            this.hides += room.carcasses;
            room.carcasses = 0;
        } else if (input === 'R' && this.tokens > 0) {
            print("Where do you want to take the subway to? [1-100]  ");
            this.gameState = 'stateSubwayPrompt';
            return;
        } else if (input === 'D' && room.guano > 0) {
            this.ustink += d(3,3);
            room.guano--;
            if (d(1,3)  == 1) { room.arrows++; }
            if (d(1,6)  == 1) { room.cans++; }
            if (d(1,12) == 1) { room.tokens++; }
            print("\nEw.  You now stink so bad that you can't smell anything but yourself.\n");
            this.pause('statePrompt');
            return;
        } else if (input === 'P') {
            this.arrows += room.arrows; room.arrows = 0;
            this.cans += room.cans; room.cans = 0;
            this.tokens += room.tokens; room.tokens = 0;
        } else {
            var dest = parseInt(input, 10);
            if (!isNaN(dest)) {
                if (room.exits[0] === dest ||
                    room.exits[1] === dest ||
                    room.exits[2] === dest) {
                    this.roomNo = dest;
                    this.moved = true;
                }
            }
        }

        this.moveWumpi();
        if (this.entropy()) {
            this.pause('statePrompt');
            return;
        }

        if (this.show()) {
            this.ask();
        }
    };

    this.handleInput = function(input) {
        this[this.gameState](input);
    };
};