Skip to content

Commit 3e05d54

Browse files
Updating zork, adding help and info commands
1 parent 947fcdc commit 3e05d54

File tree

4 files changed

+254
-35
lines changed

4 files changed

+254
-35
lines changed

input_router.js

Lines changed: 80 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,87 @@
22

33
var spawn = require('child_process').spawn;
44
var path = require('path');
5+
var number2words = require('number-to-words');
56
var files = require('./files.js');
7+
var strings = require('./strings.js');
68

7-
module.exports = {
8-
tell: {
9-
'quit': 'Goodbye!'
10-
},
11-
ask: {
12-
'main_intent': 'Welcome to Dungeon. We recommend starting the tutorial by saying "tutorial." Otherwise, say "look" to start or "load" to load a saved game.',
13-
'tutorial': 'To start the game, say "look." To quit, say "quit." To save, say "save." This will overwrite your last save. To load from the last time you said save, say "load." You can come back to the tutorial at any time by saying "tutorial." To hear more, say "second tutorial."',
14-
// TODO - help
15-
'second tutorial': 'Sorry, I haven\'t had a chance to write this. Try again later.'
16-
},
17-
do: {
18-
'save': function(app) {
19-
var conversation_save_file = files.getConversationSaveFile(app);
20-
var user_save_file = files.getUserSaveFile(app);
21-
console.log(user_save_file);
22-
console.log(conversation_save_file);
23-
24-
spawn('cp', [conversation_save_file, user_save_file]);
25-
// TODO - error handling
26-
// TODO - confirm.
27-
app.ask("Saved game.");
28-
},
29-
'load': function(app) {
30-
var conversation_save_file = files.getConversationSaveFile(app);
31-
var user_save_file = files.getUserSaveFile(app);
32-
33-
console.log(user_save_file);
34-
console.log(conversation_save_file);
35-
spawn('cp', [user_save_file, conversation_save_file]);
36-
// TODO - error handling
37-
// TODO - confirm.
38-
app.ask("Loaded game.");
39-
}
9+
// Takes a long response with multiple lines and breaks it up into pages for the user.
10+
function page(page_name, string, dict) {
11+
var pages = string.split("\n");
12+
dict[page_name] = `This text has ${number2words.toWords(pages.length)} pages. Say "${page_name} one" to go to the first page, "${page_name} two" to go to the second page, and so on.`;
13+
for (var i = 0; i < pages.length; i++) {
14+
dict[`${page_name} ${number2words.toWords(i+1)}`] = pages[i];
4015
}
16+
}
17+
18+
// Takes a response with sections and explains the sections to the user, allowing them to select one
19+
function sections(header_name, section_name_to_section, dict) {
20+
var section_names = Object.keys(section_name_to_section).reduce(function(acc, val) {
21+
return `${acc}, ${val}`;
22+
});
23+
section_names = section_names.charAt(0).toUpperCase() + section_names.slice(1);
24+
dict[header_name] = `This text has multiple sections. Say ${header_name} and then one of the following to hear more. ${section_names}`;
25+
26+
Object.keys(section_name_to_section).map(function(key) {
27+
dict[`${header_name} ${key}`] = section_name_to_section[key];
28+
});
29+
}
30+
31+
var routes = module.exports = {
32+
// Things we should respond to with a "tell"
33+
tell: {},
34+
// Things we should respond to with an "ask"
35+
ask: {},
36+
// Things we should respond to by running a function
37+
do: {}
38+
};
39+
40+
// tell
41+
routes.tell['quit'] = 'Goodbye!';
42+
43+
// ask
44+
routes.ask['main_intent'] = strings.main_intent;
45+
routes.ask['tutorial'] = strings.tutorial;
46+
page('info', strings.info, routes.ask);
47+
sections(
48+
'help',
49+
{
50+
'commands': strings.commands,
51+
'containment': strings.containment,
52+
'fighting': strings.fighting,
53+
'command parser': strings.command_parser,
54+
'actions': strings.actions,
55+
'directions': strings.directions,
56+
'objects': strings.objects,
57+
'adjectives': strings.adjectives,
58+
'prepositions': strings.prepositions,
59+
'sentences': strings.sentences,
60+
'ambiguity': strings.ambiguity,
61+
'bugs': strings.bugs
62+
},
63+
routes.ask);
64+
65+
// do
66+
routes.do['save'] = function(app) {
67+
var conversation_save_file = files.getConversationSaveFile(app);
68+
var user_save_file = files.getUserSaveFile(app);
69+
console.log(user_save_file);
70+
console.log(conversation_save_file);
71+
72+
spawn('cp', [conversation_save_file, user_save_file]);
73+
// TODO - error handling
74+
// TODO - confirm.
75+
app.ask("Saved game.");
4176
};
77+
routes.do['restore'] = function(app) {
78+
var conversation_save_file = files.getConversationSaveFile(app);
79+
var user_save_file = files.getUserSaveFile(app);
80+
81+
console.log(user_save_file);
82+
console.log(conversation_save_file);
83+
spawn('cp', [user_save_file, conversation_save_file]);
84+
// TODO - error handling
85+
// TODO - confirm.
86+
app.ask("Restored game.");
87+
};
88+

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"actions-on-google": "^1.1.1",
88
"body-parser": "^1.17.2",
99
"express": "^4.15.3",
10-
"http": "0.0.0"
10+
"http": "0.0.0",
11+
"number-to-words": "^1.2.3"
1112
},
1213
"devDependencies": {},
1314
"scripts": {

strings.js

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
module.exports = {
2+
info: `Dungeon is a game of adventure, danger, and low cunning. In it you will explore some of the most amazing territory ever seen by mortal man. Hardened adventurers have run screaming from the terrors contained within.
3+
In Dungeon, the intrepid explorer delves into the forgotten secrets of a lost labyrinth deep in the bowels of the earth, searching for vast treasures long hidden from prying eyes, treasures guarded by fearsome monsters and diabolical traps!
4+
You are near a large dungeon, which is reputed to contain vast quantities of treasure. Naturally, you wish to acquire some of it. In order to do so, you must of course remove it from the dungeon. To receive full credit for it, you must deposit it safely in the trophy case in the living room of the house.
5+
In addition to valuables, the dungeon contains various objects which may or may not be useful in your attempt to get rich. You may need sources of light, since dungeons are often dark, and weapons, since dungeons often have unfriendly things wandering about. Reading material is scattered around the dungeon as well; some of it is rumored to be useful.
6+
To determine how successful you have been, a score is kept. When you find a valuable object and pick it up, you receive a certain number of points, which depends on the difficulty of finding the object. You receive extra points for transporting the treasure safely to the living room and placing it in the trophy case. In addition, some particularly interesting rooms have a value associated with visiting them. The only penalty is for getting yourself killed, which you may do only twice.
7+
Of special note is a thief (always carrying a large bag) who likes to wander around in the dungeon (he has never been seen by the light of day). He likes to take things. Since he steals for pleasure rather than profit and is somewhat sadistic, he only takes things which you have seen. Although he prefers valuables, sometimes in his haste he may take something which is worthless. From time to time, he examines his take and discards objects which he doesn't like. He may occasionally stop in a room you are visiting, but more often he just wanders through and rips you off (he is a skilled pickpocket).`,
8+
9+
tutorial: 'This is Dungeon, a mostly untouched port of the classic 1980\'s text adventure. To start the game, say "look." To quit, say "quit." To save, say "save." This will overwrite your last save. To load from the last time you said save, say "restore." To hear your score, say "score." You can come back to the tutorial at any time by saying "tutorial." To read the help manual, say "help." To hear more info about Dungeon, say "info."',
10+
11+
main_intent: 'Welcome to Dungeon. We recommend starting the tutorial by saying "tutorial." Otherwise, say "look" to start or "restore" to load a saved game.',
12+
13+
commands: `
14+
brief
15+
suppresses printing of long room descriptions
16+
for rooms which have been visited.
17+
18+
superbrief
19+
suppresses
20+
printing of long room descriptions for all rooms.
21+
22+
verbose
23+
restores long descriptions.
24+
25+
info
26+
prints information which might give some idea
27+
of what the game is about.
28+
29+
quit
30+
prints your score and asks whether you wish
31+
to continue playing.
32+
33+
save
34+
saves the state of the game for later continuation.
35+
36+
restore
37+
restores a saved game.
38+
39+
inventory
40+
lists the objects in your possession.
41+
42+
look
43+
prints a description of your surroundings.
44+
45+
score
46+
prints your current score and ranking.
47+
48+
diagnose
49+
reports on your injuries, if any.
50+
`,
51+
52+
containment: `
53+
Some objects can contain other objects. Many such containers can
54+
be opened and closed. The rest are always open. They may or may
55+
not be transparent. For you to access (e.g., take) an object
56+
which is in a container, the container must be open. For you
57+
to see such an object, the container must be either open or
58+
transparent. Containers have a capacity, and objects have sizes;
59+
the number of objects which will fit therefore depends on their
60+
sizes. You may put any object you have access to (it need not be
61+
in your hands) into any other object. At some point, the program
62+
will attempt to pick it up if you don't already have it, which
63+
process may fail if you're carrying too much. Although containers
64+
can contain other containers, the program doesn't access more than
65+
one level down.
66+
`,
67+
68+
fighting: `
69+
Occupants of the dungeon will, as a rule, fight back when
70+
attacked. In some cases, they may attack even if unprovoked.
71+
Useful verbs here are
72+
attack
73+
<villain>
74+
with
75+
<weapon>,
76+
kill ,
77+
etc. Knife-throwing may or may not be useful. You have a
78+
fighting strength which varies with time. Being in a fight,
79+
getting killed, and being injured all lower this strength.
80+
Strength is regained with time. Thus, it is not a good idea to
81+
fight someone immediately after being killed. Other details
82+
should become apparent after a few melees or deaths.
83+
`,
84+
command_parser: `
85+
A command is one line of text terminated by a carriage return.
86+
For reasons of simplicity, all words are distinguished by their
87+
first six letters. All others are ignored. For example, typing
88+
disassemble the encyclopedia
89+
is not only meaningless, it also
90+
creates excess effort for your fingers. Note that this truncation
91+
may produce ambiguities in the intepretation of longer words.
92+
[Also note that upper and lower case are equivalent.]
93+
You are dealing with a fairly stupid parser.
94+
`,
95+
actions: `
96+
Among the more obvious of these, such as
97+
take, put, drop,
98+
etc.
99+
Fairly general forms of these may be used, such as
100+
pick up, put down,
101+
etc.
102+
`,
103+
directions: `
104+
north, south, up, down,
105+
etc. and their various abbreviations.
106+
Other more obscure directions
107+
( land,
108+
cross )
109+
are appropriate in only certain situations.
110+
`,
111+
objects: `
112+
Most objects have names and can be referenced by them.
113+
`,
114+
adjectives: `
115+
Some adjectives are understood and required when there are
116+
two objects which can be referenced with the same 'name' (e.g.,
117+
doors,
118+
buttons ).
119+
`,
120+
prepositions:`
121+
It may be necessary in some cases to include prepositions, but
122+
the parser attempts to handle cases which aren't ambiguous
123+
without. Thus
124+
give car to demon
125+
will work, as will
126+
give demon
127+
car .
128+
give car demon
129+
probably won't do anything interesting.
130+
When a preposition is used, it should be appropriate;
131+
give car with demon
132+
won't parse.
133+
`,
134+
135+
sentences: `
136+
The parser understands a reasonable number of syntactic construc-
137+
tions. In particular, multiple commands (separated by commas)
138+
can be placed on the same line.
139+
`,
140+
141+
ambiguity: `
142+
The parser tries to be clever about what to do in the case of
143+
actions which require objects that are not explicitly specified.
144+
If there is only one possible object, the parser will assume
145+
that it should be used. Otherwise, the parser will ask.
146+
Most questions asked by the parser can be answered.
147+
`,
148+
149+
bugs: `
150+
For those familiar with the MDL version of the game on the ARPAnet,
151+
the following is a list of the major incompatabilties:
152+
153+
-The first six letters of a word are considered
154+
significant, instead of the first five.
155+
156+
-The syntax for
157+
tell, answer,
158+
and
159+
incant
160+
is different.
161+
162+
-Compound objects are not recognized.
163+
164+
-Compound commands can be delimited with comma as well
165+
as period.
166+
167+
Also, the palantir, brochure, and dead man problems are not
168+
implemented.
169+
`
170+
171+
};

zork

Submodule zork updated 1 file

0 commit comments

Comments
 (0)