forked from gever/bwx-adventure
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbwx-game.py
More file actions
executable file
·422 lines (350 loc) · 13.6 KB
/
Copy pathbwx-game.py
File metadata and controls
executable file
·422 lines (350 loc) · 13.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
#!/usr/bin/python
# vim: et sw=2 ts=2 sts=2
from advent import *
# for cloud9
from advent import Game, Location, Connection, Object, Animal, Robot, Pet, Player, Verb, Say, SayOnNoun, SayOnSelf
from advent import NORTH, SOUTH, EAST, WEST, UP, DOWN, RIGHT, LEFT, IN, OUT, FORWARD, BACK, NORTH_WEST, NORTH_EAST, SOUTH_WEST, SOUTH_EAST, NOT_DIRECTION
# comment this line out to skip the devtools for environments like trinket
import advent_devtools
# Set up the game you are going to build on.
# my_game is a top-level container for everything in the game.
game = Game("Brightworks Adventure")
# Create some interesting locations. Locations need a name
# and a description of any doorways or connections to the room, like this:
# variable_name = Location('The Name", "The description")
# The triple quotes (""") below are a way to make multi-line strings in Python.
# The final argument is which word to use in the location title in place of "in"
# in the phrase "You are in the..."
sidewalk = Location(
"Sidewalk",
"""There is a large glass door to the east.
The sign says 'Come In!'
""", "on")
# Custom messages can contain lists of strings and functions which return strings.
vestibule = Location(
"Vestibule",
["A small area at the bottom of a flight of stairs.\n",
game.if_flag('switch_on', "There is a switch next to a lit bulb.\n",
"There is a switch next to an unlit bulb.\n"),
"Up the stars you see the reception desk."])
# You can also create a function to provide the description.
def reception_description(self):
return [
"Behind an opening in the wall you see ",
game.if_flag("switch_on", "a lit", "an unlit", vestibule),
""" room.
You see a score board and a message box with a needle for messages.
There is a locked sliding door to the south, and an intersection to the north."""]
reception = Location("Reception Desk", reception_description)
intersection = Location("Intersection",
"""A boring intersection. There is a passageway to the
north that leads to the shop. To the east is the elevator
landing, to the west is the guest lounge, and to the
south is the reception desk. There is nothing to do here.
""", "at")
elevator = Location("Elevator",
"""The elevator is turned off, but the door is open.
The controls on the elevator do not seem to work.
To the west is an intersection.
""")
# "\n" makes a new line in a Python string.
secret_lab = Location("Secret Laboratory", "This place is spooky. It's dark and \nthere are cobwebs everywhere. There must \nbe a light switch somewhere.")
# Let's add the locations to your game.
game.add_location(sidewalk)
game.add_location(vestibule)
game.add_location(reception)
game.add_location(intersection)
game.add_location(elevator)
# You can also add a simple location with the convience function 'new_location'.
# "\n" makes a new line in a Python string.
game.new_location(
"Secret Laboratory", "This place is spooky. It's dark and \nthere are cobwebs everywhere. There must \nbe a light switch somewhere.")
# Create connections between the different places. Each connection
# needs a name, the two locations to connect, and the two directions
# you can go to get in and out of the space.
# example: variable = Connection("The Connection Name", location_a, location_b, direction_a, direction_b)
#
# You can have more than one way of using a connection by combining them in a list.
# In Python, [] brackets make a list.
# example: new_connection = Connection("The Connection Name", location_a, location_b, [direction_a, other_direction_a], [direction_b, other_direction_b])
big_door = Connection("Big Door", sidewalk, vestibule, [IN, WEST], [OUT, EAST])
# You can omit the 2nd direction and it will just be the opposite of the 1st
stairs = Connection("Stairs", vestibule, reception, UP)
steps_to_reception = Connection("A Few Steps", reception, intersection, NORTH)
# Now add the connections to the game too.
game.add_connection(big_door)
game.add_connection(stairs)
game.add_connection(steps_to_reception)
# You can also create and add a connection with a single convenience function that allows
# you to omit the name of the connection. This is the preferred way to add connections:
game.connect(intersection, elevator, EAST)
# Create some objects to put in your game. You need a name and
# a description for the object you are making.
# example: something = Object("Object Name", "A description for the object")
# If you add True as the last argument, then it's an item that can't be taken.
elev_key = Object("key", "small tarnished brass key")
sidewalk.add_object(elev_key)
pebble = sidewalk.add_object(Object("pebble", "round pebble"))
sidewalk.add_object(Object("Gary the garden gnome",
"a small figure liberated from a nearby garden."))
# You can make rooms require things, like keys, before a player can enter them.
elevator.make_requirement(elev_key)
elevator.make_requirement(pebble)
# Add a verb applicable at this location.
sidewalk.add_verb(Say('The door makes a hollow sound.', 'knock'))
# "scream" is an example of a custom verb defined by a Python
# function. "def" defines a function in Python.
def scream(self, actor, noun, words):
all_words = [noun] + words
print "You hear a scream '%s'." % ' '.join(all_words)
return True
sidewalk.add_verb(Verb(scream, 'scream'))
# Add an animal to roam around. Animals act autonomously (on their own).
cat = Animal("cat")
cat.set_location(sidewalk)
# custom verbs available when the cat is present.
# say_on_self triggers when the cat is the noun: e.g. "pet cat"
cat.add_verb(SayOnSelf("The cat purrs.", "pet"))
cat.add_verb(SayOnSelf("Don't do that, PETA will get you!", "eat"));
cat.add_verb(SayOnSelf("The cat escapes and bites you. Ouch!", "kill"));
# say_on_noun triggers when you tell the cat to do something: e.g. "tell cat lick yourself"
cat.add_verb(SayOnNoun("The cat beings to groom itself.", "yourself", "lick"))
# Add a robot. Robots can take commands to perform actions.
robby = Robot("Robby")
robby.set_location(sidewalk)
# Add a Pet. Pets are like Animals because they can act autonomously,
# but they also are like Robots in that they can take commands to
# perform actions.
fido = Pet("Fido")
fido.set_location(sidewalk)
# Make the player.
hero = Player()
# Add the actors to the game. Players, animals, robots, and pets are
# all kinds of actors.
game.add_actor(hero)
game.add_actor(cat)
game.add_actor(robby)
game.add_actor(fido)
# add a custom actor verb (in this case for the hero)
def throw(self, actor, noun, words):
if noun and actor.get_verb('drop').act(actor, noun, words):
print 'The %s bounces and falls to the floor' % noun
return True
else:
print 'You hurt your arm.'
return False
hero.add_verb(Verb(throw, 'throw'))
# add a custom object verb
# this works for 'hit pebble' as well as 'hit XXX with pebble'
def useless_hit_with_object(self, actor, noun, words):
if not noun or noun == self.name:
self.game.output("Hitting the " + self.name + " was ineffective.")
else:
self.game.output("The " + self.name + " bounces off the " + noun + " with no visible effect.")
return True
pebble.add_verb(Verb(useless_hit_with_object, "hit"))
# Commands are looked up first by the full phrase, then by Verb first on indirect object,
# then object then actor. This catchall for 'hit' is used if no other handler is found.
hero.add_verb(Say("Such violence is appalling.", "hit"))
# The code starting here is for saving games and data that can be shared.
# Don't worry if this doesn't make sense yet.
# Create unique player and session names for non-logged/saved sessions.
player = 'player' + str(time.time())
session = 'session' + str(time.time())
# Create shared data.
# NOTE: you must either set the server with share.set_host(...) or place the host information
# in a file 'share.info' in the local directory. The host must be a webdis host using basic
# authentication. Talk to your collaborator to get this information.
share = Share()
share.set_adventure("bwx-adventure")
share.set_player(player)
share.set_session(session)
share.start()
# custom verb to record things at all locations
# Data can be store
# GLOBAL: available to everyone
# ADVENTURE: available to everyone playing a particular adventure
# PlAYER: available to the specific palyer in the specific adventure
# SESSION: available to the specific palyer in the specific adventure in the specific session
def scribble(self, actor, noun, words):
if not noun or words:
print "You can only scrible a single word."
return False
share.put(share.ADVENTURE, 'crumb.' + actor.location.name, noun.strip())
return True
hero.add_verb(Verb(scribble, 'scribble'))
# custom verb to see things that have been scribbled
def peek(self, actor, noun, words):
v = share.get(share.ADVENTURE, 'crumb.' + actor.location.name)
if not v:
print 'Nothing here.'
return False
print 'Someone scribbled "%s" here.' % v
return True
hero.add_verb(Verb(peek, 'peek'))
# custom verb to count
def more(self, actor, noun, words):
loc_name = "_".join(actor.location.name.split(' '))
share.increment(share.ADVENTURE, 'count.' + loc_name)
print 'The count is %s!' % share.get(share.ADVENTURE, 'count.' + loc_name)
return True
def fewer(self, actor, noun, words):
loc_name = "_".join(actor.location.name.split(' '))
share.decrement(share.ADVENTURE, 'count.' + loc_name)
print 'The count is %s!' % share.get(share.ADVENTURE, 'count.' + loc_name)
return True
def reset(self, actor, noun, words):
loc_name = "_".join(actor.location.name.split(' '))
share.delete(share.ADVENTURE, 'count.' + loc_name)
print 'The count is reset!'
return True
hero.add_verb(Verb(more, 'more'))
hero.add_verb(Verb(fewer, 'fewer'))
hero.add_verb(Verb(reset, 'reset'))
# custom verb to change state of a location
def flip(self, actor, noun, words):
if (noun and noun != "switch") or words:
return False
if self.flag('switch_on'):
self.unset_flag('switch_on')
else:
self.set_flag('switch_on')
print "You flip the switch."
return True
vestibule.add_verb(Verb(flip, 'flip'))
# add a custom description to an object
def describe_candle(self):
if "lit" in self.vars:
return "a lit candle"
else:
return "an unlit candle"
candle = sidewalk.new_object("candle", describe_candle)
# custom verbs to change state of an object
def light(self, actor, noun, words):
if (noun and noun != "candle") or words:
return False
if self.flag('lit'):
self.game.output("The candle is already lit.")
else:
self.set_flag('lit')
self.game.output("You light the candle.")
return True
candle.add_verb(Verb(light, "light"))
def blow_out(self, actor, noun, words):
if (noun and noun != "candle") or words:
return False
if not self.flag('lit'):
self.game.output("The candle is not lit.")
else:
self.unset_flag('lit')
self.game.output("You blow out the candle.")
return True
candle.add_verb(Verb(blow_out, "blow out"))
# custom verb to push and pop messages
# self is the location since that is where the verb was added
def push(self, actor, noun, words):
if not noun:
return False
if noun != 'message':
w = "_".join([noun] + words)
else:
if not words:
return False
w = "_".join(words)
share.push(share.ADVENTURE, 'reception_messages', w)
print "You left a message on the stack of messages."
return True
reception.add_verb(Verb(push, 'push'))
def pop(self, actor, noun, words):
if (noun and noun != "message") or words:
return False
w = share.pop(share.ADVENTURE, 'reception_messages')
if not w:
print "There are no messages on the stack."
return False
words = w.split('_')
print "You pull the top message from the stack and read '%s'." % " ".join(words)
return True
reception.add_verb(Verb(pop, 'pop'))
# custom verb on an object
def rub_key(self, actor, noun, words):
if noun or words:
return False
self.game.output("You rub the key but only succeed in making it more tarnished.")
return True
elev_key.add_verb(Verb(rub_key, 'rub'))
# high score example. When the adventurer's score changes use zadd to add/update the score.
share.delete(share.ADVENTURE, 'highscore')
share.zadd(share.ADVENTURE, 'highscore', 'joe', 10)
share.zadd(share.ADVENTURE, 'highscore', 'bob', 20)
share.zadd(share.ADVENTURE, 'highscore', 'fred', 30)
def top(self, actor, noun, words):
if (noun and noun != "scores") or words:
return False
w = share.ztop(share.ADVENTURE, 'highscore', 10)
if w:
print "Top Players"
for x in w:
print " %s" % x
return True
def scores(self, actor, noun, words):
if (noun and noun != "scoreboard") or words:
return False
w = share.ztop_with_scores(share.ADVENTURE, 'highscore', 10)
if w:
print "High Scores"
for x in w:
print " %s %s" % (x[0], x[1])
return True
reception.add_verb(Verb(top, 'top'))
reception.add_verb(Verb(scores, 'scores'))
reception.add_verb(Verb(scores, 'read'))
# Now that we have created our game and everything in it, we can start the game!
# Start on the sidewalk.
hero.set_location(sidewalk)
def update():
if (game.entering_location(reception)):
if (game.inventory_contains([pebble])):
game.output("The pebble you picked up is suddenly feeling warm to the touch!")
# Create a test script to exercise the features we coded above:
test_script = Script("test",
"""
> look
> tell Fido to follow me
> take candle pebble key
> go in
> pet cat
> flip switch
> look
> flip switch
> light candle
> blow out candle
> throw pebble
> take pebble
> look
> go up
> s
> n
> drop key
> e
> take key
> e
> w
> look
> w
> n
> s
> d
> out
> knock
> scream foo
> look
> end
""")
# Then add the script to a player, or a robot
# with code like the following:
hero.add_script(test_script)
# Now you can run this script from within the game as the hero
# by typing "run test"
# Start playing.
game.run(update)