miserjs 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,12 @@
1
1
  # MiserJS
2
2
  [![Clean Install, Build, Running All Tests](https://github.com/KristinaRC/MiserJS/actions/workflows/ci_build_test.yml/badge.svg)](https://github.com/KristinaRC/MiserJS/actions/workflows/ci_build_test.yml)
3
+ [![CodeQL](https://github.com/KristinaRC/MiserJS/actions/workflows/codeql.yml/badge.svg)](https://github.com/KristinaRC/MiserJS/actions/workflows/codeql.yml)
4
+ [![NPM Publish](https://github.com/KristinaRC/MiserJS/actions/workflows/publish.yml/badge.svg)](https://github.com/KristinaRC/MiserJS/actions/workflows/publish.yml)
5
+
3
6
 
4
7
  ## Play Online
5
- ![Screenshot of the MiserJS title screen.](https://github.com/user-attachments/assets/cf6ec7c3-139c-4568-8f7b-84a4031c7ad8 "Screenshot from MiserJS running in a web browser.")
6
- ***( Screenshots from MiserJS running in a web browser. )***
8
+ ![Screenshot of the MiserJS title screen.](https://github.com/user-attachments/assets/b737ba3e-36eb-4a39-bd37-66803c08e587 "Video capture and screenshots from MiserJS running in a web browser.")
9
+ ***( Video capture and screenshots from MiserJS running in a web browser. )***
7
10
 
8
11
  This is a JavaScript port of the Miser text adventure game that was originally released in 1981 for the Commodore PET series of computers.
9
12
 
@@ -57,14 +60,10 @@ Run the build script after modifying the src files.
57
60
  1. ```cd``` to your front-end project directory, where you ran ```npm init```.
58
61
  2. ```npm install miserjs```
59
62
 
60
- (Type ```npx miserjs``` to play the game using the locally installed (project dir only) binary. )
63
+ (Type ```npx miserjs``` to play the game using the locally installed binary.)
61
64
 
62
65
  ```
63
66
  import MiserJSEngine from 'miserjs';
64
- // Next is a JSDoc import statement for the object typedefs defined in MiserEngine.
65
- // These will show the object properties and descriptions in your
66
- // JavaScript IDE. (VS Code, WebStorm, Atom, etc.)
67
- /** @import {MiserState, MiserResponse} from 'miserjs' */
68
67
 
69
68
  // Start a new game.
70
69
  // MiserEngine constructor can also take a previously saved MiserState object.
@@ -94,11 +93,16 @@ response = miserJSEngine.request(input);
94
93
  console.log(response.text)
95
94
  ```
96
95
 
97
- In the simple front-end provided here - `miserjs-node.js` - I added
98
- `save` and `load` commands, which are not part of `miserjs-engine.js` .
96
+ A front-end example/starting-point is provided in
97
+ ```src/node/miserjs-node.js``` .
98
+
99
+ I added `save` and `load` commands that show how easy it is
100
+ to save game progress to a local text file.
99
101
 
100
- All that does is JSON.stringify the MiserState object and
101
- write it to a local file.
102
+ All that does is JSON.stringify() the MiserState object and
103
+ write/read it to/from a plain text file.
104
+
105
+ The savegame file size is only around 1,000 (one thousand) bytes, in JSON form without whitespace.
102
106
 
103
107
  ## Play Locally in Node.js
104
108
 
@@ -167,4 +171,12 @@ for the speedrun-commands.txt file.
167
171
  **John Rumpelein** ported Miser to PHP in 2013. [(Link to his page about it.)](https://rumpelein.com/miser-text-adventure/)
168
172
  **Michael J. Fromberger**, [creachadair here on GitHub](https://github.com/creachadair/miser), ported Miser to [Chipmunk BASIC](https://www.nicholson.com/rhn/basic/) in 2018, so he could run it on his Macintosh.
169
173
  **Kelly Hall**, [grumble1965 here on GitHub](https://github.com/grumble1965/PythonMiser), ported Miser to Python in 2021.
170
- **robertorenz**, [here on Github](https://github.com/robertorenz/MiserRemake), created a '2.5D Remake' of Miser in 2026. Click the link to play it in your browser.
174
+ **robertorenz**, [here on Github](https://github.com/robertorenz/MiserRemake), created a '2.5D Remake' of Miser in 2026. Click the link to play it in your browser.
175
+
176
+ ## Special Mentions
177
+
178
+ A review of Miser, from [Renga in Blue](https://bluerenga.blog/2020/03/04/miser-1981/) , which includes information about the CURSOR newsletter subscription service that ran from July 1978 to May 1982. This is where Miser was first released in August 1981.
179
+
180
+ That site is also a great source for fans of interactive fiction in general.
181
+
182
+ [Myles Skinner has a great page](https://tierceron.com/commodore/cursor/intro.php) about CURSOR tapes 1 through 24, with a link to the full set (1-30) of disk images that can be loaded into the [VICE Pet emulator](https://vice-emu.sourceforge.io) on a PC.
@@ -0,0 +1,3 @@
1
+ window.MiserJS = window.MiserJS || {};
2
+
3
+ MiserJS.MiserJSEngine = class {#t="";#e;#s=null;#r=null;static#i=40;constructor(t=null){this.#e=t||JSON.parse(JSON.stringify(MiserJS.MiserJSEngine.#n))}newGame(){this.#e=JSON.parse(JSON.stringify(MiserJS.MiserJSEngine.#n))}request(t){this.#t="";let e=t;if(!e)return this.#o("No input was provided.",!1,!0);e=e.trim(),e.length>MiserJS.MiserJSEngine.#i&&(e=e.substring(0,MiserJS.MiserJSEngine.#i));let s,r,i=0,n=0,o=[];do{" "!==e.charAt(i)?i++:(i>n&&o.push(e.substring(n,i)),i++,n=i)}while(i<e.length);switch(i>n&&o.push(e.substring(n,i)),o.length){case 1:return s=this.#a(o[0]),s>0?(this.#s=o[0],this.#h(s,0)):this.#u();case 2:return s=this.#a(o[0]),s>0?(this.#s=o[0],r=this.#p(o[1]),r>0?(this.#r=o[1],this.#h(s,r)):this.#u()):this.#u();default:return this.#o("Please type a one or two word command.\n")}}#h(t,e){switch(t){case 1:case 2:return this.#l(e);case 3:case 4:case 5:return this.#c(e);case 6:return this.#m(e);case 7:return this.#S(e);case 8:case 29:return this.#d();case 9:return this.#g();case 10:return this.#f(e);case 11:return this.#T(e);case 12:return this.#y(e);case 13:return this.#w(e);case 14:return this.#b(e);case 15:return this.#x();case 16:return this.#k(e);case 17:case 18:return this.#v();case 19:case 20:return this.#I();case 21:case 22:return this.#E();case 23:case 24:return this.#P();case 25:return this.#M();case 26:return this.#Y(e);case 27:return this.#R();case 28:return this.#J();case 30:return this.#O(e);default:throw new Error(`In Action method: Verb '${this.#s}' was defined in the verbs array, but not implemented yet.`)}}#l(t){if(0==t)return this.#u();if(-1==this.#e.pt[t])return this.#o("I am unable to do that.\n");if(-1==this.#G(t))return this.#o("You're already carrying it.\n");if(this.#G(t)!=this.#e.cp)return this.#N();this.#e.ol[this.#e.pt[t]]=-1,this.#t+="Ok\n";let e=this.#e.pt[t];return e>3&&e<9||19===e?(this.#e.gt+=1,this.#t+="You got a treasure!\n",this.#o(this.#t)):(2===t&&-2===this.#e.ol[20]&&(this.#e.ol[20]=0,this.#t+="You find a door key!\n"),this.#o(this.#t))}#c(t){if(0==t)return this.#u();if(13!=t){if(-1==this.#e.pt[t])return this.#o("That item stays put.\n");if(this.#e.ol[this.#e.pt[t]]!=this.#e.cp&&-1!=this.#e.ol[this.#e.pt[t]])return this.#N()}switch(t){case 2:if(-2==this.#e.ol[20])return this.#e.ol[20]=0,this.#o("You find a door key!\n");break;case 10:if(-2==this.#e.ol[16])return this.#t+="You find a trap door!\n",this.#e.ol[16]=6,this.#x();break;case 13:return 5==this.#e.cp&&0==this.#e.rPercent[5][3]?(this.#e.fv=!0,this.#t+="Behind the cabinet is a vault!\n",this.#x()):this.#o("That item stays put.\n")}return this.#o("Moving it reveals nothing.\n")}#m(t){switch(t){case 0:return this.#u();case 7:return this.#o("Try turning it.\n");case 11:if(this.#e.ol[this.#e.pt[t]]==this.#e.cp||-1==this.#e.ol[this.#e.pt[t]])return this.#o("Scrawled in blood on the inside front cover is the message, \"'Victory' is a prize-winning word\".\n");break;case 12:switch(this.#e.cp){case 0:return this.#e.du?this.#o("It's already open.\n"):this.#o("Sorry, the door is locked.\n");case 6:return this.#t+="You open the door. You lean over to peer in, and you fall in!\n",this.#e.cp=47,this.#x()}return this.#N();case 13:return this.#e.ol[26]==this.#e.cp?this.#o("The cabinet is empty and dusty.\nScribbled in dust on one shelf are the words, 'behind me'.\n"):this.#N();case 16:return 21==this.#e.cp?this.#e.gg?-2!=this.#e.ol[24]?(this.#e.ol[24]=-2,this.#e.ol[25]=21,this.#e.ol[17]=21,this.#e.ol[19]=21,this.#t+="As you open it, several objects suddenly appear!\n",this.#x()):this.#o("It's already open.\n"):this.#o("It's stuck shut.\n"):this.#N();case 22:return this.#e.ol[this.#e.pt[t]]==this.#e.cp||-1==this.#e.ol[this.#e.pt[t]]?this.#o("The bag is knotted securely.\nIt won't open.\n"):this.#N();case 27:return 5==this.#e.cp&&this.#e.fv?this.#e.vo?this.#o("It's already open.\n"):this.#o("I can't, it's locked.\n"):this.#N()}return this.#o("I don't know how to open that.\n")}#S(t){if(0==t)return this.#u();if(-1==this.#e.pt[t])return this.#o("There's nothing written on that.\n");if(!this.#j(t))return this.#N();switch(t){case 3:return this.#e.kc=!0,this.#o("It says, '12-35-6'.\nhmm.. looks like a combination.\n");case 11:return this.#o("The front cover is inscribed in Greek.\n");default:return this.#o("There's nothing written on that.\n")}}#d(){this.#t+="You are carrying the following:\n\n";let t=0;for(let e=1;e<28;e++)if(-1==this.#e.ol[e]){if(t=1,this.#t+=`${MiserJS.MiserJSEngine.#D[e]}\n`,1==e&&this.#e.bf){this.#t+=" The bucket is full of water.\n";continue}14==e&&(this.#t+=" (Better fix it)\n")}return 1==t?this.#o(this.#t):this.#o(this.#t+="Nothing at all.\n")}#g(){return this.#o(this.#t,MiserJS.MiserJSEngine.#A.QUIT)}#f(t){if(-1==this.#e.pt[t])return this.#t+="\n?ILLEGAL QUANTITY ERROR IN 8000\n\n",this.#t+="----------------------------------------",this.#t+="** You have encountered a bug that\n",this.#t+="existed in the original Miser program\n",this.#t+="from 1981. **\n\n",this.#t+="This bug is being reproduced here to\n",this.#t+="preserve the experience a player would\n",this.#t+="have had playing this game in 1981 on\n",this.#t+="one of the Commodore PET computers.\n\n",this.#t+="Except for one thing...the game doesn't\n",this.#t+="just end unexpectedly here as it did\n",this.#t+="back then.\n\n",this.#t+="You get to keep playing as if nothing\n",this.#t+="bad happened!\n",this.#o(this.#t);if(-1!=this.#e.ol[this.#e.pt[t]])return this.#o("You aren't carrying it!\n");switch(this.#e.pt[t]){case 4:case 5:case 7:case 8:case 19:return this.#o("Don't drop *treasures*!\n")}switch(t){case 19:if(19==this.#e.cp)return this.#e.rPercent[21][3]=22,this.#e.ol[12]=-2,this.#o("As the penny sinks below the surface of the pool, a fleeting image of a chapel with dancers outside appears.\n");break;case 20:if(22==this.#e.cp)return this.#e.gg=!0,this.#e.ol[11]=-2,this.#o("Even before it hits the ground, the cross fades away!\n\nThe tablet has disintegrated.\n\nYou hear music from the organ.\n")}return this.#e.ol[this.#e.pt[t]]=this.#e.cp,this.#o("Ok\n")}#T(t){switch(t){case 0:return this.#o("Say what???\n");case 14:return 4==this.#e.cp?this.#e.ch?this.#o("Nothing happens.\n"):(this.#e.ch=!0,this.#e.ol[2]=-2,this.#e.ol[3]=4,this.#o("The snake is charmed by the very utterance of your words.\n")):this.#o("Nothing happens.\n");case 15:return 8==this.#e.cp?this.#e.po?this.#o("Nothing happens.\n"):(this.#e.po=!0,this.#e.rPercent[8][1]=17,this.#e.ol[18]=8,this.#o("A portal has opened in the north wall!!\n")):this.#o("Nothing happens.\n");case 29:case 30:return this.#o("A hollow voice says, 'Wrong adventure'.\n");default:return t<29?this.#o(`Okay, '${this.#r}'.\nNothing happens.\n`):this.#u()}}#y(t){if(4!=t)return this.#o("I wouldn't know how.\n");if(!this.#j(t))return this.#N();if(!this.#e.bf)return this.#o("The bucket is already empty.\n");switch(this.#e.cp){case 10:if(this.#e.fb)return this.#e.fb=!1,this.#e.bf=!1,this.#t+="Congratulations! You have vanquished the flames.\n",this.#x();break;case 19:return this.#o("Ok\n")}return this.#o("The water disappears quickly.\n")}#w(t){if(0==t)return this.#u();if(-1==this.#e.pt[t])return this.#o("That wouldn't hold anything.\n");if(!this.#j(t))return this.#N();if(4==t){if(this.#e.bf)return this.#o("It's already full.\n");switch(this.#e.cp){case 19:case 23:return this.#e.bf=!0,this.#o("Your bucket is now full.\n");case 25:if(this.#e.pf)return this.#o("I'd rather stay away from the mercury.\n")}return this.#o("I don't see any water here.\n")}return this.#o("That wouldn't hold anything.\n")}#b(t){switch(t){case 0:return this.#u();case 12:switch(this.#e.cp){case 0:return this.#e.du?this.#o("It's already unlocked.\n"):-1!=this.#e.ol[20]?this.#o("I need a key.\n"):(this.#e.du=!0,this.#t+="The door easily unlocks and swings open.\n",this.#x());case 6:return-2!=this.#e.ol[16]?this.#o("The trapdoor has no lock.\n"):this.#o("I don't see it here.\n");default:return this.#N()}case 27:return 5==this.#e.cp?this.#e.vo?this.#o("It's already open.\n"):this.#e.fv?this.#e.kc?(this.#e.vo=!0,this.#e.rPercent[5][3]=46,this.#t+="Ok, let's see. 12..35..6..\n<CLICK!> The door swings open.",this.#x()):this.#o("I don't know the combination.\n"):this.#N():this.#N();default:return this.#o("I wouldn't know how to unlock one.\n")}}#x(){let t=this.#e.cp;22==t&&this.#e.gg?this.#t+="\nYou are in the chapel.\n":this.#t+=`\nYou are in the ${MiserJS.MiserJSEngine.#B[t]}.\n`;for(let e=1;e<29;e++)this.#e.ol[e]==t&&(24==e&&this.#e.gg?this.#t+="\nThere is a closed organ playing music in the corner here.\n":this.#t+=`\nThere is a ${MiserJS.MiserJSEngine.#D[e]} here.\n`,1==e&&this.#e.bf&&(this.#t+=" The bucket is full of water.\n"));switch(this.#e.cp){case 0:this.#e.du&&(this.#t+="\nAn open door leads north.\n");break;case 5:this.#e.fv&&(this.#t+="\nThere is a vault in the east wall.\n"),this.#e.vo&&(this.#t+="The vault is open.\n");break;case 10:this.#e.fb?this.#t+="\nThere is a hot fire on the south wall!\nIf I go that way I'll burn to death!\n":this.#t+="\nThere is evidence of a recent fire here.\n";break;case 16:this.#t+="\nA rich, full voice says, 'Ritnew is a charming word'.\n";break;case 23:this.#t+="\nThere is a leaky faucet nearby.\n";break;case 25:this.#e.pf?this.#t+="\nThe pool is full of liquid mercury!\n":(this.#t+="\nThe pool's empty.\n",48==this.#e.ol[7]&&(this.#t+="\nI see something shiny in the pool!\n"));break;case 26:this.#t+="\nThere is a valve on one of the pipes.\n";break;case 48:return this.#o(this.#t)}return this.#t+="\nObvious Exits:\n",this.#e.rPercent[this.#e.cp][1]>0&&(this.#t+="N "),this.#e.rPercent[this.#e.cp][2]>0&&(this.#t+="S "),this.#e.rPercent[this.#e.cp][3]>0&&(this.#t+="E "),this.#e.rPercent[this.#e.cp][4]>0&&(this.#t+="W "),this.#t+="\n",this.#o(this.#t)}#k(t){switch(t){case 8:return 48==this.#e.cp?(this.#e.cp=25,this.#x()):this.#N();case 18:switch(this.#e.cp){case 2:return-1==this.#e.ol[9]?(this.#e.cp=27,this.#t+="The suits of armor try to stop you, but you fight them off with your sword.\n",this.#x()):this.#o("The suits of armor prevent you from going up!\n");case 27:return this.#e.cp=2,this.#x();default:return this.#N()}case 28:return this.#e.pf?this.#o("The pool is full of mercury!\n"):(this.#e.cp=48,this.#x());default:return this.#u()}}#v(){return 0!=this.#e.cp||this.#e.du?0==this.#e.rPercent[this.#e.cp][1]?this.#C():(0==this.#e.cp&&(this.#t+="\nThe door slams shut behind you!\n"),this.#e.cp=this.#e.rPercent[this.#e.cp][1],this.#x()):(this.#t+="The door is locked shut.\n",this.#o(this.#t))}#I(){if(10==this.#e.cp&&this.#e.fb)return this.#t+="You have burnt to a crisp!\n",this.#o(this.#t,MiserJS.MiserJSEngine.#A.DIED);const t=this.#H();return null!=t?t:0==this.#e.rPercent[this.#e.cp][2]?this.#C():(this.#e.cp=this.#e.rPercent[this.#e.cp][2],this.#x())}#E(){const t=this.#H();return null!=t?t:0==this.#e.rPercent[this.#e.cp][3]?this.#C():(this.#e.cp=this.#e.rPercent[this.#e.cp][3],this.#x())}#P(){return 0==this.#e.rPercent[this.#e.cp][4]?this.#C():(this.#e.cp=this.#e.rPercent[this.#e.cp][4],this.#x())}#M(){this.#t+=`Your current score is: ${20*this.#e.gt} points.\n(100 possible)\n`;let t=this.#e.gt;this.#e.es&&t++,this.#t+=`\nYour rank is: ${MiserJS.MiserJSEngine.#$[t]}\n`;let e=MiserJS.MiserJSEngine.#$.length-1-t;return this.#t+=0==e?" (You have escaped with ALL available treasure!)\n":1==e?" (There is only one rank left for you to achieve!)\n":` (There are ${e} more ranks you can achieve.)\n`,this.#o(this.#t)}#Y(t){return 7!=t?this.#o("I don't know how to turn such a thing.\n"):26!=this.#e.cp?this.#N():(this.#e.pf=!this.#e.pf,this.#o("With much effort, you turn the valve 5 times. You hear the sound of liquid\nflowing through the pipes.\n"))}#R(){switch(this.#e.cp){case 27:return this.#t+="You jump...\n",this.#e.jm?(this.#t+="Now you've done it. You ignored\nmy warning, and as a result\nyou have broken your neck!\n\nYou are dead.",this.#o(this.#t,MiserJS.MiserJSEngine.#A.DIED)):(this.#e.jm=!0,this.#e.cp=2,this.#t+="You have landed down-stairs,\nand narrowly escaped serious\ninjury. Please don't try it again.\n",this.#x());case 29:case 32:if(this.#t+="You jump...\n",-1==this.#e.ol[14])return this.#t+="There is no way to open the parachute!\n",this.#t+="You hit the ground.\n",this.#t+="You have broken your neck!\n\n",this.#t+="You are dead.",this.#o(this.#t,MiserJS.MiserJSEngine.#A.DIED);if(-1!=this.#e.ol[27])return this.#t+="You hit the ground.\n",this.#t+="You have broken your neck!\n\n",this.#t+="You are dead.",this.#o(this.#t,MiserJS.MiserJSEngine.#A.DIED);if(this.#t+="You yank the ripcord and the\n'chute comes billowing out.\n",32==this.#e.cp)return this.#e.cp=40,this.#x();if(29==this.#e.cp)return this.#t+="You land safely.\n\nCongratulations on escaping!\n",this.#e.es=!0,this.#o(this.#t,MiserJS.MiserJSEngine.#A.ESCAPED);default:return this.#t+="There's nowhere to jump.",this.#o(this.#t)}}#J(){switch(this.#e.cp){case 19:return this.#o("The water is only a few inches deep.\n");case 25:return this.#e.pf?this.#o("In mercury? No way!\n"):this.#o("The pool is empty.\n");default:return this.#o("There's nothing here to swim in!\n")}}#O(t){switch(t){case 0:return this.#u();case 7:return this.#o("I ain't no plumber.\n");case 17:return this.#j(t)?-2==this.#e.ol[14]?this.#o("It's already fixed.\n"):-1!=this.#e.ol[17]?this.#o("I need a ripcord.\n"):(this.#e.ol[27]=this.#e.ol[14],this.#e.ol[14]=-2,this.#e.pt[17]=27,this.#e.ol[17]=0,this.#o("I'm no expert, but I think it'll work.\n")):this.#N();default:return this.#o("I wouldn't know how.\n")}}#H(){return 4!=this.#e.cp||this.#e.ch?null:this.#e.ps?this.#o("The snake bites you!\nYou are dead.\n",MiserJS.MiserJSEngine.#A.DIED):(this.#e.ps=!0,this.#o("The snake is about to attack!\n"))}showFinalOutcome(){this.#t=`\nYou accumulated ${this.#e.gt} treasures, \n for a score of ${20*this.#e.gt} points.\n(100 Possible)\n`;let t=this.#e.gt;return this.#e.es?t++:this.#t+="\nHowever, you did not escape.\n",this.#t+=`\nThis puts you in a class of:\n${MiserJS.MiserJSEngine.#$[t]}\n`,6!=t&&(this.#t+="\nBetter luck next time!\n"),this.#o(this.#t,!0)}#o(t,e=!1,s=!1){return{text:t,gameOver:e,isError:s}}#a(t){(t=t.toLowerCase()).length>4&&(t=t.substring(0,4));for(let e=1;e<MiserJS.MiserJSEngine.#z.length;e++)if(t===MiserJS.MiserJSEngine.#z[e])return e;return 0}#p(t){(t=t.toLowerCase()).length>4&&(t=t.substring(0,4));for(let e=1;e<MiserJS.MiserJSEngine.#F.length;e++)if(t===MiserJS.MiserJSEngine.#F[e])return e;return 0}#u(){return this.#t+=`${MiserJS.MiserJSEngine.#L[this.#e.em]}\n`,this.#e.em=3-this.#e.em,this.#o(this.#t)}#N(){return this.#t+="I don't see it here.\n",this.#o(this.#t)}#C(){return this.#t+="It's impossible to go that way.\n",this.#o(this.#t)}#j(t){return this.#G(t)==this.#e.cp||-1==this.#G(t)}#G(t){return this.#e.ol[this.#e.pt[t]]}getCurrentPosition(){return this.#e.cp}getCurrentPositionShortName(t){return MiserJS.MiserJSEngine.#W[t]}getInventoryItemCount(t){let e=0;for(const s of t.ol)-1==s&&e++;return e}getGameState(){return this.#e}setGameState(t){this.#e=t}isGameInProgress(){return this.#e.cp>0}static#z=["","get","take","move","slid","push","open","read","inve","quit","drop","say","pour","fill","unlo","look","go","nort","n","sout","s","east","e","west","w","scor","turn","jump","swim","i","fix"];static#F=["","ripc","mat","pape","buck","swor","key","valv","ladd","slip","rug","book","door","cabi","ritn","vict","orga","para","stai","penn","cros","leaf","bag",">$<",">$<","ring","pain","vaul","pool","xyzz","plug"];static#L=["","What?","I don't understand that."];static#$=["<Beginner Adventurer>","<Amateur Adventurer>","<Journeyman Adventurer>","<Experienced Adventurer>","<Pro Adventurer>","<Master Adventurer>","<Grandmaster Adventurer>"];static#D=["","plastic bucket","vicious snake","charmed snake","*golden leaf*","*bulging moneybag*",">$<","*diamond ring*","*rare painting*","sword","mat","rusty cross","penny","piece of paper","parachute with no ripcord","oriental rug","trapdoor marked 'danger'","parachute ripcord","portal in the north wall","pair of *ruby slippers*","brass door key","majestic staircase leading up","majestic staircase leading down","battered book","organ in the corner","open organ in the corner","cabinet on rollers against one wall over","repaired parachute","sign saying 'drop coins for luck'"];static#B=["front porch","Foyer to a large house. Dust is everywhere","Great Hall. Suits of armor line the walls","Breakfast Room. It is bright and cheery","Conservatory. Through a window you see a hedge-maze","Red-Walled Room","Formal Parlor","Green Drawing Room","Trophy Room. Animal heads line the walls","Den","Blue Drawing Room","Library. Empty shelves line the walls","Dining Room","Chinese Room","$","Kitchen. It is bare","Pantry. Dust covers the mahogany shelves","Game Room","Smoking Room. The air is stale in here","Portico. A murky pool glimmers on the south side","Hall Of Mirrors - a good place to reflect","Ballroom. It has a beautiful wood dance floor","Chapel. A tablet says 'Drop a religious item or die!!'","back yard","forest","Pool Area. There is a large swimming pool here","Pump House. There is pool machinery installed here","middle of the Western Hallway","West Bedroom","Front Balcony. There is a large road below","$","Master Bedroom. There's a huge four-poster bed","Rear Balcony. Below you see a Hedge Maze","East Bedroom","Closet","Junction of the West Hallway and the North-South Hallway","Center of the North-South Hallway","Junction of the East Hallway and the North-South Hallway","Middle of the East Hallway","South end of the East Hallway","hedge maze","hedge maze","hedge maze","hedge maze","hedge maze","hedge maze","walk-in Vault","Dungeon. There is light above and to the south","bottom of the Swimming Pool. A ladder leads up and out"];static#W=["Front Porch","Foyer","Great Hall","Breakfast Room","Conservatory","Red-Walled Room","Formal Parlor","Green Drawing Room","Trophy Room","Den","Blue Drawing Room","Library","Dining Room","Chinese Room","$","Kitchen","Pantry","Game Room","Smoking Room","Portico","Hall of Mirrors","Ballroom","Chapel","Back Yard","Forest","Pool Area","Pump House","Middle of West Hallway","West Bedroom","Front Balcony","$","Master Bedroom","Rear Balcony","East Bedroom","Closet","West Hallway Junction","Center of North-South Hallway","East Hallway Junction","Middle of East Hallway","South End East Hallway","hedge maze","hedge maze","hedge maze","hedge maze","hedge maze","hedge maze","Vault","Dungeon","Swimming Pool"];static#A=Object.freeze({DIED:"died",ESCAPED:"escaped",QUIT:"quit"});static#n={cp:0,em:1,gt:0,du:!1,pf:!0,fb:!0,bf:!1,fv:!1,vo:!1,po:!1,ch:!1,ps:!1,kc:!1,es:!1,jm:!1,gg:!1,pt:[0,17,10,13,1,9,20,-1,-1,19,15,23,-1,-1,-1,-1,-1,14,-1,12,11,4,5,-1,-1,7,8,-1,-1,-1,-1],ol:[0,26,4,-2,45,46,-2,48,39,13,0,23,28,31,34,6,-2,-2,-2,-2,-2,2,27,11,21,-2,5,-2,19],rPercent:[[0,1,0,0,0],[0,2,0,0,12],[0,3,1,0,0],[0,0,2,4,16],[0,0,5,7,3],[0,4,6,0,0],[0,5,0,10,0],[0,0,0,8,4],[0,0,9,0,7],[0,8,0,0,10],[0,0,11,9,6],[0,10,0,0,0],[0,0,0,1,13],[0,15,0,12,0],[0,0,0,0,0],[0,23,13,16,0],[0,0,0,3,15],[0,0,8,0,18],[0,21,0,17,19],[0,21,0,18,20],[0,21,21,19,19],[0,0,19,0,20],[0,0,0,0,21],[0,24,15,40,25],[0,24,23,24,24],[0,26,0,23,0],[0,0,25,0,0],[0,35,0,31,28],[0,0,0,27,0],[0,39,0,0,0],[0,0,0,0,0],[0,0,0,38,27],[0,0,36,0,0],[0,34,0,0,38],[0,0,33,0,0],[0,0,27,36,0],[0,32,0,37,35],[0,0,38,0,36],[0,37,39,33,31],[0,38,29,0,0],[0,0,42,0,41],[0,44,42,0,0],[0,41,44,43,0],[0,41,23,0,0],[0,0,42,0,45],[0,0,0,44,0],[0,0,0,0,5],[0,0,40,0,0],[0,0,0,0,0]]}}
@@ -0,0 +1 @@
1
+ export default class MiserJSEngine{#t="";#e;#s=null;#r=null;static#i=40;constructor(t=null){this.#e=t||JSON.parse(JSON.stringify(MiserJSEngine.#n))}newGame(){this.#e=JSON.parse(JSON.stringify(MiserJSEngine.#n))}request(t){this.#t="";let e=t;if(!e)return this.#o("No input was provided.",!1,!0);e=e.trim(),e.length>MiserJSEngine.#i&&(e=e.substring(0,MiserJSEngine.#i));let s,r,i=0,n=0,o=[];do{" "!==e.charAt(i)?i++:(i>n&&o.push(e.substring(n,i)),i++,n=i)}while(i<e.length);switch(i>n&&o.push(e.substring(n,i)),o.length){case 1:return s=this.#a(o[0]),s>0?(this.#s=o[0],this.#h(s,0)):this.#u();case 2:return s=this.#a(o[0]),s>0?(this.#s=o[0],r=this.#p(o[1]),r>0?(this.#r=o[1],this.#h(s,r)):this.#u()):this.#u();default:return this.#o("Please type a one or two word command.\n")}}#h(t,e){switch(t){case 1:case 2:return this.#l(e);case 3:case 4:case 5:return this.#c(e);case 6:return this.#m(e);case 7:return this.#S(e);case 8:case 29:return this.#d();case 9:return this.#g();case 10:return this.#f(e);case 11:return this.#T(e);case 12:return this.#y(e);case 13:return this.#w(e);case 14:return this.#b(e);case 15:return this.#x();case 16:return this.#k(e);case 17:case 18:return this.#v();case 19:case 20:return this.#I();case 21:case 22:return this.#E();case 23:case 24:return this.#P();case 25:return this.#M();case 26:return this.#Y(e);case 27:return this.#R();case 28:return this.#J();case 30:return this.#O(e);default:throw new Error(`In Action method: Verb '${this.#s}' was defined in the verbs array, but not implemented yet.`)}}#l(t){if(0==t)return this.#u();if(-1==this.#e.pt[t])return this.#o("I am unable to do that.\n");if(-1==this.#G(t))return this.#o("You're already carrying it.\n");if(this.#G(t)!=this.#e.cp)return this.#N();this.#e.ol[this.#e.pt[t]]=-1,this.#t+="Ok\n";let e=this.#e.pt[t];return e>3&&e<9||19===e?(this.#e.gt+=1,this.#t+="You got a treasure!\n",this.#o(this.#t)):(2===t&&-2===this.#e.ol[20]&&(this.#e.ol[20]=0,this.#t+="You find a door key!\n"),this.#o(this.#t))}#c(t){if(0==t)return this.#u();if(13!=t){if(-1==this.#e.pt[t])return this.#o("That item stays put.\n");if(this.#e.ol[this.#e.pt[t]]!=this.#e.cp&&-1!=this.#e.ol[this.#e.pt[t]])return this.#N()}switch(t){case 2:if(-2==this.#e.ol[20])return this.#e.ol[20]=0,this.#o("You find a door key!\n");break;case 10:if(-2==this.#e.ol[16])return this.#t+="You find a trap door!\n",this.#e.ol[16]=6,this.#x();break;case 13:return 5==this.#e.cp&&0==this.#e.rPercent[5][3]?(this.#e.fv=!0,this.#t+="Behind the cabinet is a vault!\n",this.#x()):this.#o("That item stays put.\n")}return this.#o("Moving it reveals nothing.\n")}#m(t){switch(t){case 0:return this.#u();case 7:return this.#o("Try turning it.\n");case 11:if(this.#e.ol[this.#e.pt[t]]==this.#e.cp||-1==this.#e.ol[this.#e.pt[t]])return this.#o("Scrawled in blood on the inside front cover is the message, \"'Victory' is a prize-winning word\".\n");break;case 12:switch(this.#e.cp){case 0:return this.#e.du?this.#o("It's already open.\n"):this.#o("Sorry, the door is locked.\n");case 6:return this.#t+="You open the door. You lean over to peer in, and you fall in!\n",this.#e.cp=47,this.#x()}return this.#N();case 13:return this.#e.ol[26]==this.#e.cp?this.#o("The cabinet is empty and dusty.\nScribbled in dust on one shelf are the words, 'behind me'.\n"):this.#N();case 16:return 21==this.#e.cp?this.#e.gg?-2!=this.#e.ol[24]?(this.#e.ol[24]=-2,this.#e.ol[25]=21,this.#e.ol[17]=21,this.#e.ol[19]=21,this.#t+="As you open it, several objects suddenly appear!\n",this.#x()):this.#o("It's already open.\n"):this.#o("It's stuck shut.\n"):this.#N();case 22:return this.#e.ol[this.#e.pt[t]]==this.#e.cp||-1==this.#e.ol[this.#e.pt[t]]?this.#o("The bag is knotted securely.\nIt won't open.\n"):this.#N();case 27:return 5==this.#e.cp&&this.#e.fv?this.#e.vo?this.#o("It's already open.\n"):this.#o("I can't, it's locked.\n"):this.#N()}return this.#o("I don't know how to open that.\n")}#S(t){if(0==t)return this.#u();if(-1==this.#e.pt[t])return this.#o("There's nothing written on that.\n");if(!this.#j(t))return this.#N();switch(t){case 3:return this.#e.kc=!0,this.#o("It says, '12-35-6'.\nhmm.. looks like a combination.\n");case 11:return this.#o("The front cover is inscribed in Greek.\n");default:return this.#o("There's nothing written on that.\n")}}#d(){this.#t+="You are carrying the following:\n\n";let t=0;for(let e=1;e<28;e++)if(-1==this.#e.ol[e]){if(t=1,this.#t+=`${MiserJSEngine.#D[e]}\n`,1==e&&this.#e.bf){this.#t+=" The bucket is full of water.\n";continue}14==e&&(this.#t+=" (Better fix it)\n")}return 1==t?this.#o(this.#t):this.#o(this.#t+="Nothing at all.\n")}#g(){return this.#o(this.#t,MiserJSEngine.#A.QUIT)}#f(t){if(-1==this.#e.pt[t])return this.#t+="\n?ILLEGAL QUANTITY ERROR IN 8000\n\n",this.#t+="----------------------------------------",this.#t+="** You have encountered a bug that\n",this.#t+="existed in the original Miser program\n",this.#t+="from 1981. **\n\n",this.#t+="This bug is being reproduced here to\n",this.#t+="preserve the experience a player would\n",this.#t+="have had playing this game in 1981 on\n",this.#t+="one of the Commodore PET computers.\n\n",this.#t+="Except for one thing...the game doesn't\n",this.#t+="just end unexpectedly here as it did\n",this.#t+="back then.\n\n",this.#t+="You get to keep playing as if nothing\n",this.#t+="bad happened!\n",this.#o(this.#t);if(-1!=this.#e.ol[this.#e.pt[t]])return this.#o("You aren't carrying it!\n");switch(this.#e.pt[t]){case 4:case 5:case 7:case 8:case 19:return this.#o("Don't drop *treasures*!\n")}switch(t){case 19:if(19==this.#e.cp)return this.#e.rPercent[21][3]=22,this.#e.ol[12]=-2,this.#o("As the penny sinks below the surface of the pool, a fleeting image of a chapel with dancers outside appears.\n");break;case 20:if(22==this.#e.cp)return this.#e.gg=!0,this.#e.ol[11]=-2,this.#o("Even before it hits the ground, the cross fades away!\n\nThe tablet has disintegrated.\n\nYou hear music from the organ.\n")}return this.#e.ol[this.#e.pt[t]]=this.#e.cp,this.#o("Ok\n")}#T(t){switch(t){case 0:return this.#o("Say what???\n");case 14:return 4==this.#e.cp?this.#e.ch?this.#o("Nothing happens.\n"):(this.#e.ch=!0,this.#e.ol[2]=-2,this.#e.ol[3]=4,this.#o("The snake is charmed by the very utterance of your words.\n")):this.#o("Nothing happens.\n");case 15:return 8==this.#e.cp?this.#e.po?this.#o("Nothing happens.\n"):(this.#e.po=!0,this.#e.rPercent[8][1]=17,this.#e.ol[18]=8,this.#o("A portal has opened in the north wall!!\n")):this.#o("Nothing happens.\n");case 29:case 30:return this.#o("A hollow voice says, 'Wrong adventure'.\n");default:return t<29?this.#o(`Okay, '${this.#r}'.\nNothing happens.\n`):this.#u()}}#y(t){if(4!=t)return this.#o("I wouldn't know how.\n");if(!this.#j(t))return this.#N();if(!this.#e.bf)return this.#o("The bucket is already empty.\n");switch(this.#e.cp){case 10:if(this.#e.fb)return this.#e.fb=!1,this.#e.bf=!1,this.#t+="Congratulations! You have vanquished the flames.\n",this.#x();break;case 19:return this.#o("Ok\n")}return this.#o("The water disappears quickly.\n")}#w(t){if(0==t)return this.#u();if(-1==this.#e.pt[t])return this.#o("That wouldn't hold anything.\n");if(!this.#j(t))return this.#N();if(4==t){if(this.#e.bf)return this.#o("It's already full.\n");switch(this.#e.cp){case 19:case 23:return this.#e.bf=!0,this.#o("Your bucket is now full.\n");case 25:if(this.#e.pf)return this.#o("I'd rather stay away from the mercury.\n")}return this.#o("I don't see any water here.\n")}return this.#o("That wouldn't hold anything.\n")}#b(t){switch(t){case 0:return this.#u();case 12:switch(this.#e.cp){case 0:return this.#e.du?this.#o("It's already unlocked.\n"):-1!=this.#e.ol[20]?this.#o("I need a key.\n"):(this.#e.du=!0,this.#t+="The door easily unlocks and swings open.\n",this.#x());case 6:return-2!=this.#e.ol[16]?this.#o("The trapdoor has no lock.\n"):this.#o("I don't see it here.\n");default:return this.#N()}case 27:return 5==this.#e.cp?this.#e.vo?this.#o("It's already open.\n"):this.#e.fv?this.#e.kc?(this.#e.vo=!0,this.#e.rPercent[5][3]=46,this.#t+="Ok, let's see. 12..35..6..\n<CLICK!> The door swings open.",this.#x()):this.#o("I don't know the combination.\n"):this.#N():this.#N();default:return this.#o("I wouldn't know how to unlock one.\n")}}#x(){let t=this.#e.cp;22==t&&this.#e.gg?this.#t+="\nYou are in the chapel.\n":this.#t+=`\nYou are in the ${MiserJSEngine.#B[t]}.\n`;for(let e=1;e<29;e++)this.#e.ol[e]==t&&(24==e&&this.#e.gg?this.#t+="\nThere is a closed organ playing music in the corner here.\n":this.#t+=`\nThere is a ${MiserJSEngine.#D[e]} here.\n`,1==e&&this.#e.bf&&(this.#t+=" The bucket is full of water.\n"));switch(this.#e.cp){case 0:this.#e.du&&(this.#t+="\nAn open door leads north.\n");break;case 5:this.#e.fv&&(this.#t+="\nThere is a vault in the east wall.\n"),this.#e.vo&&(this.#t+="The vault is open.\n");break;case 10:this.#e.fb?this.#t+="\nThere is a hot fire on the south wall!\nIf I go that way I'll burn to death!\n":this.#t+="\nThere is evidence of a recent fire here.\n";break;case 16:this.#t+="\nA rich, full voice says, 'Ritnew is a charming word'.\n";break;case 23:this.#t+="\nThere is a leaky faucet nearby.\n";break;case 25:this.#e.pf?this.#t+="\nThe pool is full of liquid mercury!\n":(this.#t+="\nThe pool's empty.\n",48==this.#e.ol[7]&&(this.#t+="\nI see something shiny in the pool!\n"));break;case 26:this.#t+="\nThere is a valve on one of the pipes.\n";break;case 48:return this.#o(this.#t)}return this.#t+="\nObvious Exits:\n",this.#e.rPercent[this.#e.cp][1]>0&&(this.#t+="N "),this.#e.rPercent[this.#e.cp][2]>0&&(this.#t+="S "),this.#e.rPercent[this.#e.cp][3]>0&&(this.#t+="E "),this.#e.rPercent[this.#e.cp][4]>0&&(this.#t+="W "),this.#t+="\n",this.#o(this.#t)}#k(t){switch(t){case 8:return 48==this.#e.cp?(this.#e.cp=25,this.#x()):this.#N();case 18:switch(this.#e.cp){case 2:return-1==this.#e.ol[9]?(this.#e.cp=27,this.#t+="The suits of armor try to stop you, but you fight them off with your sword.\n",this.#x()):this.#o("The suits of armor prevent you from going up!\n");case 27:return this.#e.cp=2,this.#x();default:return this.#N()}case 28:return this.#e.pf?this.#o("The pool is full of mercury!\n"):(this.#e.cp=48,this.#x());default:return this.#u()}}#v(){return 0!=this.#e.cp||this.#e.du?0==this.#e.rPercent[this.#e.cp][1]?this.#C():(0==this.#e.cp&&(this.#t+="\nThe door slams shut behind you!\n"),this.#e.cp=this.#e.rPercent[this.#e.cp][1],this.#x()):(this.#t+="The door is locked shut.\n",this.#o(this.#t))}#I(){if(10==this.#e.cp&&this.#e.fb)return this.#t+="You have burnt to a crisp!\n",this.#o(this.#t,MiserJSEngine.#A.DIED);const t=this.#H();return null!=t?t:0==this.#e.rPercent[this.#e.cp][2]?this.#C():(this.#e.cp=this.#e.rPercent[this.#e.cp][2],this.#x())}#E(){const t=this.#H();return null!=t?t:0==this.#e.rPercent[this.#e.cp][3]?this.#C():(this.#e.cp=this.#e.rPercent[this.#e.cp][3],this.#x())}#P(){return 0==this.#e.rPercent[this.#e.cp][4]?this.#C():(this.#e.cp=this.#e.rPercent[this.#e.cp][4],this.#x())}#M(){this.#t+=`Your current score is: ${20*this.#e.gt} points.\n(100 possible)\n`;let t=this.#e.gt;this.#e.es&&t++,this.#t+=`\nYour rank is: ${MiserJSEngine.#$[t]}\n`;let e=MiserJSEngine.#$.length-1-t;return this.#t+=0==e?" (You have escaped with ALL available treasure!)\n":1==e?" (There is only one rank left for you to achieve!)\n":` (There are ${e} more ranks you can achieve.)\n`,this.#o(this.#t)}#Y(t){return 7!=t?this.#o("I don't know how to turn such a thing.\n"):26!=this.#e.cp?this.#N():(this.#e.pf=!this.#e.pf,this.#o("With much effort, you turn the valve 5 times. You hear the sound of liquid\nflowing through the pipes.\n"))}#R(){switch(this.#e.cp){case 27:return this.#t+="You jump...\n",this.#e.jm?(this.#t+="Now you've done it. You ignored\nmy warning, and as a result\nyou have broken your neck!\n\nYou are dead.",this.#o(this.#t,MiserJSEngine.#A.DIED)):(this.#e.jm=!0,this.#e.cp=2,this.#t+="You have landed down-stairs,\nand narrowly escaped serious\ninjury. Please don't try it again.\n",this.#x());case 29:case 32:if(this.#t+="You jump...\n",-1==this.#e.ol[14])return this.#t+="There is no way to open the parachute!\n",this.#t+="You hit the ground.\n",this.#t+="You have broken your neck!\n\n",this.#t+="You are dead.",this.#o(this.#t,MiserJSEngine.#A.DIED);if(-1!=this.#e.ol[27])return this.#t+="You hit the ground.\n",this.#t+="You have broken your neck!\n\n",this.#t+="You are dead.",this.#o(this.#t,MiserJSEngine.#A.DIED);if(this.#t+="You yank the ripcord and the\n'chute comes billowing out.\n",32==this.#e.cp)return this.#e.cp=40,this.#x();if(29==this.#e.cp)return this.#t+="You land safely.\n\nCongratulations on escaping!\n",this.#e.es=!0,this.#o(this.#t,MiserJSEngine.#A.ESCAPED);default:return this.#t+="There's nowhere to jump.",this.#o(this.#t)}}#J(){switch(this.#e.cp){case 19:return this.#o("The water is only a few inches deep.\n");case 25:return this.#e.pf?this.#o("In mercury? No way!\n"):this.#o("The pool is empty.\n");default:return this.#o("There's nothing here to swim in!\n")}}#O(t){switch(t){case 0:return this.#u();case 7:return this.#o("I ain't no plumber.\n");case 17:return this.#j(t)?-2==this.#e.ol[14]?this.#o("It's already fixed.\n"):-1!=this.#e.ol[17]?this.#o("I need a ripcord.\n"):(this.#e.ol[27]=this.#e.ol[14],this.#e.ol[14]=-2,this.#e.pt[17]=27,this.#e.ol[17]=0,this.#o("I'm no expert, but I think it'll work.\n")):this.#N();default:return this.#o("I wouldn't know how.\n")}}#H(){return 4!=this.#e.cp||this.#e.ch?null:this.#e.ps?this.#o("The snake bites you!\nYou are dead.\n",MiserJSEngine.#A.DIED):(this.#e.ps=!0,this.#o("The snake is about to attack!\n"))}showFinalOutcome(){this.#t=`\nYou accumulated ${this.#e.gt} treasures, \n for a score of ${20*this.#e.gt} points.\n(100 Possible)\n`;let t=this.#e.gt;return this.#e.es?t++:this.#t+="\nHowever, you did not escape.\n",this.#t+=`\nThis puts you in a class of:\n${MiserJSEngine.#$[t]}\n`,6!=t&&(this.#t+="\nBetter luck next time!\n"),this.#o(this.#t,!0)}#o(t,e=!1,s=!1){return{text:t,gameOver:e,isError:s}}#a(t){(t=t.toLowerCase()).length>4&&(t=t.substring(0,4));for(let e=1;e<MiserJSEngine.#z.length;e++)if(t===MiserJSEngine.#z[e])return e;return 0}#p(t){(t=t.toLowerCase()).length>4&&(t=t.substring(0,4));for(let e=1;e<MiserJSEngine.#F.length;e++)if(t===MiserJSEngine.#F[e])return e;return 0}#u(){return this.#t+=`${MiserJSEngine.#L[this.#e.em]}\n`,this.#e.em=3-this.#e.em,this.#o(this.#t)}#N(){return this.#t+="I don't see it here.\n",this.#o(this.#t)}#C(){return this.#t+="It's impossible to go that way.\n",this.#o(this.#t)}#j(t){return this.#G(t)==this.#e.cp||-1==this.#G(t)}#G(t){return this.#e.ol[this.#e.pt[t]]}getCurrentPosition(){return this.#e.cp}getCurrentPositionShortName(t){return MiserJSEngine.#W[t]}getInventoryItemCount(t){let e=0;for(const s of t.ol)-1==s&&e++;return e}getGameState(){return this.#e}setGameState(t){this.#e=t}isGameInProgress(){return this.#e.cp>0}static#z=["","get","take","move","slid","push","open","read","inve","quit","drop","say","pour","fill","unlo","look","go","nort","n","sout","s","east","e","west","w","scor","turn","jump","swim","i","fix"];static#F=["","ripc","mat","pape","buck","swor","key","valv","ladd","slip","rug","book","door","cabi","ritn","vict","orga","para","stai","penn","cros","leaf","bag",">$<",">$<","ring","pain","vaul","pool","xyzz","plug"];static#L=["","What?","I don't understand that."];static#$=["<Beginner Adventurer>","<Amateur Adventurer>","<Journeyman Adventurer>","<Experienced Adventurer>","<Pro Adventurer>","<Master Adventurer>","<Grandmaster Adventurer>"];static#D=["","plastic bucket","vicious snake","charmed snake","*golden leaf*","*bulging moneybag*",">$<","*diamond ring*","*rare painting*","sword","mat","rusty cross","penny","piece of paper","parachute with no ripcord","oriental rug","trapdoor marked 'danger'","parachute ripcord","portal in the north wall","pair of *ruby slippers*","brass door key","majestic staircase leading up","majestic staircase leading down","battered book","organ in the corner","open organ in the corner","cabinet on rollers against one wall over","repaired parachute","sign saying 'drop coins for luck'"];static#B=["front porch","Foyer to a large house. Dust is everywhere","Great Hall. Suits of armor line the walls","Breakfast Room. It is bright and cheery","Conservatory. Through a window you see a hedge-maze","Red-Walled Room","Formal Parlor","Green Drawing Room","Trophy Room. Animal heads line the walls","Den","Blue Drawing Room","Library. Empty shelves line the walls","Dining Room","Chinese Room","$","Kitchen. It is bare","Pantry. Dust covers the mahogany shelves","Game Room","Smoking Room. The air is stale in here","Portico. A murky pool glimmers on the south side","Hall Of Mirrors - a good place to reflect","Ballroom. It has a beautiful wood dance floor","Chapel. A tablet says 'Drop a religious item or die!!'","back yard","forest","Pool Area. There is a large swimming pool here","Pump House. There is pool machinery installed here","middle of the Western Hallway","West Bedroom","Front Balcony. There is a large road below","$","Master Bedroom. There's a huge four-poster bed","Rear Balcony. Below you see a Hedge Maze","East Bedroom","Closet","Junction of the West Hallway and the North-South Hallway","Center of the North-South Hallway","Junction of the East Hallway and the North-South Hallway","Middle of the East Hallway","South end of the East Hallway","hedge maze","hedge maze","hedge maze","hedge maze","hedge maze","hedge maze","walk-in Vault","Dungeon. There is light above and to the south","bottom of the Swimming Pool. A ladder leads up and out"];static#W=["Front Porch","Foyer","Great Hall","Breakfast Room","Conservatory","Red-Walled Room","Formal Parlor","Green Drawing Room","Trophy Room","Den","Blue Drawing Room","Library","Dining Room","Chinese Room","$","Kitchen","Pantry","Game Room","Smoking Room","Portico","Hall of Mirrors","Ballroom","Chapel","Back Yard","Forest","Pool Area","Pump House","Middle of West Hallway","West Bedroom","Front Balcony","$","Master Bedroom","Rear Balcony","East Bedroom","Closet","West Hallway Junction","Center of North-South Hallway","East Hallway Junction","Middle of East Hallway","South End East Hallway","hedge maze","hedge maze","hedge maze","hedge maze","hedge maze","hedge maze","Vault","Dungeon","Swimming Pool"];static#A=Object.freeze({DIED:"died",ESCAPED:"escaped",QUIT:"quit"});static#n={cp:0,em:1,gt:0,du:!1,pf:!0,fb:!0,bf:!1,fv:!1,vo:!1,po:!1,ch:!1,ps:!1,kc:!1,es:!1,jm:!1,gg:!1,pt:[0,17,10,13,1,9,20,-1,-1,19,15,23,-1,-1,-1,-1,-1,14,-1,12,11,4,5,-1,-1,7,8,-1,-1,-1,-1],ol:[0,26,4,-2,45,46,-2,48,39,13,0,23,28,31,34,6,-2,-2,-2,-2,-2,2,27,11,21,-2,5,-2,19],rPercent:[[0,1,0,0,0],[0,2,0,0,12],[0,3,1,0,0],[0,0,2,4,16],[0,0,5,7,3],[0,4,6,0,0],[0,5,0,10,0],[0,0,0,8,4],[0,0,9,0,7],[0,8,0,0,10],[0,0,11,9,6],[0,10,0,0,0],[0,0,0,1,13],[0,15,0,12,0],[0,0,0,0,0],[0,23,13,16,0],[0,0,0,3,15],[0,0,8,0,18],[0,21,0,17,19],[0,21,0,18,20],[0,21,21,19,19],[0,0,19,0,20],[0,0,0,0,21],[0,24,15,40,25],[0,24,23,24,24],[0,26,0,23,0],[0,0,25,0,0],[0,35,0,31,28],[0,0,0,27,0],[0,39,0,0,0],[0,0,0,0,0],[0,0,0,38,27],[0,0,36,0,0],[0,34,0,0,38],[0,0,33,0,0],[0,0,27,36,0],[0,32,0,37,35],[0,0,38,0,36],[0,37,39,33,31],[0,38,29,0,0],[0,0,42,0,41],[0,44,42,0,0],[0,41,44,43,0],[0,41,23,0,0],[0,0,42,0,45],[0,0,0,44,0],[0,0,0,0,5],[0,0,40,0,0],[0,0,0,0,0]]}}