Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

754 rindas
23KB

  1. (import comparse)
  2. (import srfi-1)
  3. (import srfi-14)
  4. (import (chicken io))
  5. (import srfi-13)
  6. (import matchable)
  7. (import fmt)
  8. (import fmt-color)
  9. (import fmt-unicode)
  10. (import ansi-escape-sequences)
  11. (import (chicken file))
  12. (import breadline)
  13. (import ncurses)
  14. (define (lift fn parser)
  15. (bind parser (compose result fn)))
  16. (define (is-not x)
  17. (satisfies (lambda (y)
  18. (not (eqv? x y)))))
  19. (define (curry fn a)
  20. (lambda (b)
  21. (fn a b)))
  22. (define (applied fn)
  23. (curry apply fn))
  24. (define-syntax thunk
  25. (syntax-rules ()
  26. ((_ exp ...)
  27. (lambda () exp ...))))
  28. (define parse-whitespace
  29. (one-or-more (is #\space)))
  30. (define skip-whitespace
  31. (skip (zero-or-more (is #\space))))
  32. (define +letter-char-set+
  33. (string->char-set "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVwXYZ"))
  34. (define +symbol-char-set+
  35. (char-set-union +letter-char-set+ (string->char-set "-0123456789")))
  36. (define parse-symbol
  37. (lift (compose string->symbol string-downcase list->string (applied append))
  38. (sequence (lift list (in +letter-char-set+)) (zero-or-more (in +symbol-char-set+)))))
  39. (define parse-number
  40. (lift (compose string->number list->string) (one-or-more (in char-set:digit))))
  41. (define parse-string
  42. (lift list->string (enclosed-by (is #\") (one-or-more (is-not #\")) (is #\"))))
  43. (define (followed-by-consuming parser separator)
  44. (sequence* ((value parser) (_ separator))
  45. (result value)))
  46. (define (separated-by separator parser)
  47. (one-or-more (any-of (followed-by-consuming parser separator) parser)))
  48. (define parse-symbol-or-number-or-string
  49. (any-of parse-number parse-symbol parse-string))
  50. (define (completely-parse parser)
  51. (followed-by parser end-of-input))
  52. (define parse-statement
  53. (all-of skip-whitespace (separated-by parse-whitespace parse-symbol-or-number-or-string)))
  54. (define (just fn)
  55. (lambda args
  56. (fn)))
  57. (define (perhaps fn arg)
  58. (if arg
  59. (fn arg)
  60. arg))
  61. (define display-newline
  62. (compose (just newline) display))
  63. (define (display-lines ln)
  64. (perhaps (curry map display-newline) ln))
  65. (define (parse-input)
  66. (parse (completely-parse parse-statement) (read-line)))
  67. (define parse-formatter
  68. (recursive-parser (one-or-more (any-of (followed-by-consuming (char-seq "<b>") (lift fmt-bold parser))
  69. (is-not #\<)))))
  70. (define (type-of elem)
  71. (cond ((pair? elem) 'pair)
  72. ((symbol? elem) 'symbol)
  73. ((number? elem) 'number)
  74. ((char? elem) 'char)
  75. ((string? elem) 'string)
  76. ((boolean? elem) 'boolean)))
  77. (define (show str)
  78. (fmt #t (dsp (wrap-lines str))))
  79. (define (prompt str)
  80. (newline)
  81. (let ((result (readline str)))
  82. (if (equal? "" result)
  83. (prompt str)
  84. (begin
  85. (add-history! result)
  86. result))))
  87. (define (prompt-yn str)
  88. (newline)
  89. (let ((result (string-downcase (readline str))))
  90. (cond ((equal? "yes" result) #t)
  91. ((equal? "no" result) #f)
  92. (else (begin
  93. (newline)
  94. (display "Please answer yes or no.")
  95. (prompt-yn str))))))
  96. (define (prompt-default str default)
  97. (map stuff-char (string->list default))
  98. (let loop ()
  99. (let ((result (readline str)))
  100. (if (equal? "" result)
  101. (loop)
  102. result))))
  103. (define +articles-prepositions+
  104. '(a an the into on to at as))
  105. (define (adventure-prompt)
  106. (let ((result (parse (completely-parse parse-statement) (prompt "> "))))
  107. (if result
  108. (let ((grug-result (filter (compose not (cut member <> +articles-prepositions+)) result)))
  109. (if (not (null? grug-result))
  110. grug-result
  111. (begin (display "I didn't quite understand that.")
  112. (adventure-prompt))))
  113. (begin (display "I didn't quite understand that.")
  114. (adventure-prompt)))))
  115. (define (compose-symbols . ln)
  116. (string->symbol
  117. (let loop ((ln ln))
  118. (case (length ln)
  119. ((0) '())
  120. ((1) (symbol->string (car ln)))
  121. (else (string-append (symbol->string (car ln)) "-" (loop (cdr ln))))))))
  122. (define *database* '())
  123. (define (database-set name key value)
  124. (set! *database* (let loop ((kv *database*))
  125. (if (null? kv)
  126. (list (cons name (list (cons key value))))
  127. (if (equal? name (caar kv))
  128. (cons (cons name (let loop ((kv (cdar kv)))
  129. (if (null? kv)
  130. (list (cons key value))
  131. (if (equal? key (caar kv))
  132. (cons (cons key value) (cdr kv))
  133. (cons (car kv) (loop (cdr kv))))))) (cdr kv))
  134. (cons (car kv) (loop (cdr kv))))))))
  135. (define (database-get name key default)
  136. (let loop ((kv *database*))
  137. (if (null? kv)
  138. default
  139. (if (equal? name (caar kv))
  140. (let loop ((kv (cdar kv)))
  141. (if (null? kv)
  142. default
  143. (if (equal? key (caar kv))
  144. (cdar kv)
  145. (loop (cdr kv)))))
  146. (loop (cdr kv))))))
  147. (define (database-save filename)
  148. (with-output-to-file filename (thunk (write *database*))))
  149. (define (database-load filename)
  150. (with-input-from-file filename (thunk (set! *database* (car (read-list))))))
  151. (define (database-remove name)
  152. (let loop ((kv *database*))
  153. (if (null? kv)
  154. '()
  155. (if (equal? name (caar kv))
  156. (cdr kv)
  157. (cons (car kv) (loop (cdr kv)))))))
  158. (define (get-all-objects)
  159. (map car *database*))
  160. (define (object-exists? object)
  161. (member object (get-all-objects)))
  162. (define (has-property? object property)
  163. (database-get object property #f))
  164. (define (toggle-flag object flag)
  165. (if (has-property? object flag)
  166. (database-set object flag #f)
  167. (database-set object flag #t)))
  168. (define (get-location object)
  169. (database-get object 'location #f))
  170. (define (set-name object name)
  171. (database-set object 'name name))
  172. (define (set-description object description)
  173. (database-set object 'description description))
  174. (define (get-name object)
  175. (database-get object 'name (symbol->string object)))
  176. (define (get-description object)
  177. (database-get object 'description "You see the swirling void of creation."))
  178. (define (get-container object)
  179. (database-get object 'container #f))
  180. (define (get-contents object)
  181. (database-get object 'contents '()))
  182. (define (set-destination object destination)
  183. (database-set object 'destination destination))
  184. (define (get-destination object)
  185. (database-get object 'destination #f))
  186. (define (set-enter-message object msg)
  187. (database-set object 'enter-message msg))
  188. (define (get-enter-message object)
  189. (database-get object 'enter-message #f))
  190. (define (get-aliases object)
  191. (database-get object 'aliases '()))
  192. (define (set-aliases object alias-list)
  193. (database-set object 'aliases alias-list))
  194. (define (add-alias object alias)
  195. (let ((aliases (get-aliases object)))
  196. (if (not (member alias aliases))
  197. (set-aliases object (cons alias aliases)))))
  198. (define (remove-alias object alias)
  199. (let ((aliases (get-aliases object)))
  200. (if (member alias aliases)
  201. (set-aliases object (remove (curry eq? alias) aliases)))))
  202. (define (set-hidden object value)
  203. (database-set object 'hidden value))
  204. (define (get-hidden object)
  205. (database-get object 'hidden #f))
  206. (define (set-fixed object value)
  207. (database-set object 'fixed value))
  208. (define (get-fixed object value)
  209. (database-get object 'hidden #f))
  210. (define (get-put-message object)
  211. (database-get object 'put-message "You put the ~a into the ~a."))
  212. ;; Is development mode enabled?
  213. (define (devmode-enabled?)
  214. (has-property? 'you 'devmode))
  215. (define (toggle-devmode)
  216. (toggle-flag 'you 'devmode))
  217. ;; Is an object fixed in place (e.g. cannot be picked up?)
  218. (define (fixed? object)
  219. (has-property? object 'fixed))
  220. (define (toggle-fixed object)
  221. (toggle-flag object 'fixed))
  222. ;; Match a tag against a list of objects, checking for its tag and its aliases.
  223. (define (match-object tag objects)
  224. (let loop ((objects objects))
  225. (if (null? objects)
  226. #f
  227. (let ((taglist (cons (car objects) (get-aliases (car objects)))))
  228. (if (member tag taglist)
  229. (car objects)
  230. (loop (cdr objects)))))))
  231. (define (create-object tag name description)
  232. (set-name tag name)
  233. (set-description tag description))
  234. (define (move-object object container)
  235. (let ((prev-container (get-container object)))
  236. (database-set object 'container container)
  237. (let ((contents (get-contents container)))
  238. (if (not (member object contents))
  239. (begin
  240. (database-set container 'contents (cons object contents))
  241. (database-set prev-container 'contents (remove (curry eq? object) (get-contents prev-container))))))))
  242. ;; Determine the objects visible to a source object, zork-style
  243. (define (visible-objects source)
  244. (let ((result (get-container source)))
  245. (if (and result (object-exists? result))
  246. (cons (get-container source) (get-contents (get-container source)))
  247. (error "Tried to determine visible objects for object without a container."))))
  248. (define (any-or fn ln thunk)
  249. (let loop ((ln ln))
  250. (if (null? ln)
  251. (thunk)
  252. (let ((result (fn (car ln))))
  253. (if result
  254. result
  255. (loop (cdr ln)))))))
  256. (define (run-lisp body)
  257. (define (lisp body environments lisp-exit)
  258. (define (reference symbol)
  259. (cdr (any-or (curry assoc symbol) (cons lisp-builtins environments) (thunk (lisp-exit (string-append "Undefined reference: " (symbol->string symbol)))))))
  260. (define (lisp-apply function args)
  261. (cond ((procedure? function)
  262. (apply function args))
  263. ((list? function)
  264. (let ((function-arguments (car function))
  265. (function-body (cdr function)))
  266. (lisp function-body (cons (if (= (length function-arguments) (length args))
  267. (map cons function-arguments args)
  268. (lisp-exit "Wrong number of arguments to function")) environments) lisp-exit)))
  269. (else (lisp-exit "attempt to call atom"))))
  270. (define (lisp-eval body)
  271. (cond ((symbol? body) (reference body))
  272. ((atom? body) body)
  273. ((list? body) (lisp-apply (lisp-eval (car body)) (cdr body)))
  274. (else (lisp-exit "Unknown value type in evaluation."))))
  275. (define (bind name value)
  276. (set! environments (cons (let loop ((environment (car environments)))
  277. (if (null? environment)
  278. (list (cons name value))
  279. (if (eq? name (caar environment))
  280. (cons (cons name value) (cdr environment))
  281. (cons (car environment) (loop (cdr environment))))))
  282. (cdr environments))))
  283. (define lisp-builtins
  284. `((test . ,(lambda function-args
  285. (show "test function called")))
  286. (if . ,(lambda function-args
  287. (match function-args
  288. ((e x y) (if (lisp-eval e)
  289. (lisp-eval x)
  290. (lisp-eval y)))
  291. (_ (lisp-exit "malformed if expression")))))
  292. (quote . ,(lambda function-args
  293. (match function-args
  294. ((v) v)
  295. (_ (lisp-exit "malformed quote expression")))))
  296. (cons . ,(lambda function-args
  297. (match function-args
  298. ((a b) (cons (lisp-eval a) (lisp-eval b)))
  299. (_ (lisp-exit "malformed cons expression")))))
  300. (car . ,(lambda function-args
  301. (match function-args
  302. ((a) (let ((e (lisp-eval a)))
  303. (if (atom? e)
  304. (lisp-exit "tried to take car of atom")
  305. (car e))))
  306. (_ (lisp-exit "malformed car expression")))))
  307. (cdr . ,(lambda function-args
  308. (match function-args
  309. ((a) (let ((e (lisp-eval a)))
  310. (if (atom? e)
  311. (lisp-exit "tried to take cdr of atom")
  312. (cdr e))))
  313. (_ (lisp-exit "malformed cdr expression")))))
  314. (atom . ,(lambda function-args
  315. (match function-args
  316. ((a) (let ((e (lisp-eval a)))
  317. (atom? e)))
  318. (_ (lisp-exit "malformed atom expression")))))
  319. (eq . ,(lambda function-args
  320. (match function-args
  321. ((a b) (let ((ea (eval a))
  322. (eb (eval b)))
  323. (equal? ea eb)))
  324. (_ (lisp-exit "malformed eq expression")))))
  325. (set . ,(lambda function-args
  326. (match function-args
  327. ((a b) (let ((ea (eval a))
  328. (eb (eval b)))
  329. (if (symbol? a)
  330. (bind a b)
  331. (lisp-exit "tried to bind to non-symbol"))))
  332. (_ (lisp-exit "malformed set expression")))))
  333. (lambda . ,(lambda function-args
  334. (match function-args
  335. ((args exp . exps)
  336. (if (and (list? args) (every symbol? args))
  337. (cons args (cons exp exps))
  338. (lisp-exit "malformed lambda expression")))
  339. (_ (lisp-exit "malformed lambda expression")))))))
  340. (lisp-eval body))
  341. (call/cc (lambda (lisp-exit)
  342. (cons #t (lisp body (list) (compose lisp-exit (curry cons #f)))))))
  343. (define (print-room-description room)
  344. (newline)
  345. (display (set-text '(bold) (get-name room)))
  346. (if (devmode-enabled?) (display (set-text '(bold fg-green) (string-append " [" (symbol->string room) "]"))))
  347. (newline)
  348. (display " ")
  349. (fmt #t (dsp (wrap-lines (get-description room))))
  350. (newline)
  351. (display "You see: ")
  352. (map (lambda (n) (if (not (get-hidden n)) (begin (display (get-name n)) (display " ") (if (devmode-enabled?) (begin (display (set-text '(bold fg-green) (string-append "[" (symbol->string n) "] ")))))))) (remove (curry eq? 'you) (get-contents room)))
  353. (newline))
  354. (define (do-command-enter tag)
  355. (let ((object (match-object tag (visible-objects 'you))))
  356. (if (not object)
  357. (show "You cannot go that way.")
  358. (let ((destination (get-destination object)))
  359. (if (not destination)
  360. (show "You cannot enter that.")
  361. (begin
  362. (move-object 'you destination)
  363. (perhaps show (get-enter-message object))
  364. (print-room-description (get-container 'you))))))))
  365. (define (do-command-save)
  366. (let ((save-name (prompt-default "Enter save name: " "kekkonen.sav")))
  367. (if (or (not (file-exists? save-name)) (prompt-yn "That file already exists. Overwrite? "))
  368. (begin
  369. (show "Saving database, please wait...")
  370. (database-save save-name)
  371. (show "Done.")))))
  372. (define (do-command-load)
  373. (let ((save-name (prompt-default "Enter save file name to load: " "kekkonen.sav")))
  374. (if (not (file-exists? save-name))
  375. (show "That file does not exist.")
  376. (begin
  377. (show "Loading database, please wait...")
  378. (database-load save-name)
  379. (show "Done.")))))
  380. (define (do-command-look)
  381. (print-room-description (get-container 'you)))
  382. (define (do-command-examine tag)
  383. (let ((object (match-object tag (visible-objects 'you))))
  384. (if (not object)
  385. (show "You cannot see that here.")
  386. (show (get-description object)))))
  387. (define (do-command-inventory)
  388. (map (compose show get-name) (get-contents 'you)))
  389. (define (do-command-take tag)
  390. (if (not (symbol? tag))
  391. (show "I didn't quite understand that.")
  392. (let ((object (match-object tag (if (devmode-enabled?)
  393. (get-all-objects)
  394. (visible-objects 'you)))))
  395. (if (or (not object) (and (fixed? object) (not (devmode-enabled?))))
  396. (if object
  397. (show "That is fixed in place.")
  398. (show "You cannot see that here."))
  399. (begin
  400. (show (string-append "You get " (get-name object) "."))
  401. (move-object object 'you))))))
  402. (define (do-command-drop tag)
  403. (if (not (symbol? tag))
  404. (show "I didn't quite understand that.")
  405. (let ((object (match-object tag (get-contents 'you))))
  406. (if (not object)
  407. (show "You are not carrying that.")
  408. (begin
  409. (show (string-append "You drop " (get-name object) "."))
  410. (move-object object (get-container 'you)))))))
  411. (define (do-command-put tag destination-tag)
  412. (let ((object (match-object tag (get-contents 'you))))
  413. (if (not object)
  414. (show "You are not carrying that.")
  415. (let ((destination-object (match-object destination-tag (visible-objects 'you))))
  416. (if (not destination-object)
  417. (show "You cannot see that here.")
  418. (move-object object (get-destination destination-object)))))))
  419. (define (do-command-devmode)
  420. (toggle-devmode)
  421. (if (devmode-enabled?)
  422. (show "Development mode enabled.")
  423. (show "Development mode disabled.")))
  424. (define (do-command-create tag name description)
  425. (if (not (and (symbol? tag) (string? name) (string? description)))
  426. (show "I didn't quite understand that.")
  427. (if (object-exists? tag)
  428. (show "That object already exists.")
  429. (begin
  430. (create-object tag name description)
  431. (move-object tag (get-container 'you))))))
  432. (define (do-setter-command tag value type? setter)
  433. (if (not (and (symbol? tag) (type? value)))
  434. (show "I didn't quite understand that.")
  435. (let ((object (match-object tag (visible-objects 'you))))
  436. (if (not object)
  437. (show "You can't see that here.")
  438. (begin
  439. (setter object value)
  440. (show "You set a value."))))))
  441. (define (do-command-rename tag name)
  442. (do-setter-command tag name string? set-name))
  443. (define (do-command-describe tag description)
  444. (do-setter-command tag description string? set-description))
  445. (define (do-command-flag tag flag)
  446. (if (not (and (symbol? tag) (symbol? flag)))
  447. (show "I didn't quite understand that.")
  448. (let ((object (match-object tag (visible-objects 'you))))
  449. (if (not object)
  450. (show "You can't see that here.")
  451. (begin
  452. (case flag
  453. ((fixed) (set-fixed object #t))
  454. ((hidden) (set-hidden object #t))
  455. (else (show "Invalid flag name."))))))))
  456. (define (do-command-unflag tag flag)
  457. (if (not (and (symbol? tag) (symbol? flag)))
  458. (show "I didn't quite understand that.")
  459. (let ((object (match-object tag (visible-objects 'you))))
  460. (if (not object)
  461. (show "You can't see that here.")
  462. (begin
  463. (case flag
  464. ((fixed) (set-fixed object #f))
  465. ((hidden) (set-hidden object #f))
  466. (else (show "Invalid flag name."))))))))
  467. (define (do-command-alias tag alias)
  468. (if (not (and (symbol? tag) (symbol? alias)))
  469. (show "I didn't quite understand that.")
  470. (let ((object (match-object tag (visible-objects 'you))))
  471. (if (not object)
  472. (show "You can't see that here.")
  473. (begin
  474. (add-alias object alias)
  475. (show "You add an alias."))))))
  476. (define (do-command-unalias tag alias)
  477. (if (not (and (symbol? tag) (symbol? alias)))
  478. (show "I didn't quite understand that.")
  479. (let ((object (match-object tag (visible-objects 'you))))
  480. (if (not object)
  481. (show "You can't see that here.")
  482. (begin
  483. (remove-alias object alias)
  484. (show "You remove an alias."))))))
  485. (define (do-command-destroy tag)
  486. (if (not (symbol? tag))
  487. (show "I didn't quite understand that.")
  488. (database-remove tag)))
  489. (define (do-command-aliases tag)
  490. (if (not (symbol? tag))
  491. (show "I didn't quite understand that.")
  492. (let ((object (match-object tag (visible-objects 'you))))
  493. (if (not object)
  494. (show "You can't see that here.")
  495. (begin
  496. (newline)
  497. (map (lambda (x) (display x) (display " ")) (get-aliases object))
  498. (newline))))))
  499. (define (do-command-message tag message-tag message)
  500. (if (not (and (symbol? tag) (symbol? message-tag) (string? message)))
  501. (show "I didn't quite understand that.")
  502. (let ((object (match-object tag (visible-objects 'you))))
  503. (if (not object)
  504. (show "You can't see that here.")
  505. (case message-tag
  506. ((enter) (set-enter-message object message))
  507. (else (show "Invalid message name.")))))))
  508. (define (do-command-goto tag)
  509. (if (not (symbol? tag))
  510. (show "I didn't quite understand that.")
  511. (begin
  512. (move-object 'you tag)
  513. (print-room-description (get-container 'you)))))
  514. (define +cardinal-sets+
  515. '((north n)
  516. (northeast ne north-east)
  517. (east e)
  518. (southeast se south-east)
  519. (south s)
  520. (southwest sw south-west)
  521. (west w)
  522. (northwest nw north-west)
  523. (up u)
  524. (down d)))
  525. (define +cardinal-opposites+
  526. '((north . south)
  527. (northeast . southwest)
  528. (east . west)
  529. (southeast . northwest)
  530. (south . north)
  531. (southwest . northeast)
  532. (west . east)
  533. (northwest . southeast)
  534. (up . down)
  535. (down . up)))
  536. (define (get-cardinal-set direction)
  537. (find (curry member direction) +cardinal-sets+))
  538. (define (get-cardinal-aliases direction)
  539. (perhaps (curry remove (curry eq? direction)) (get-cardinal-set direction)))
  540. (define (cardinal-direction? direction)
  541. (list? (member direction (flatten +cardinal-sets+))))
  542. (define (get-inverse-direction direction)
  543. (perhaps cdr (assoc direction +cardinal-opposites+)))
  544. (define (get-canonical-cardinal-direction-name direction)
  545. (perhaps car (get-cardinal-set direction)))
  546. (define (do-command-dig direction destination)
  547. (if (not (and (symbol? direction) (symbol? destination)))
  548. (show "I didn't quite understand that.")
  549. (if (not (cardinal-direction? direction))
  550. (show "You must specify a compass rose direction or up and down.")
  551. (let ((canonical-direction (get-canonical-cardinal-direction-name direction)))
  552. (let ((exit-tag (compose-symbols canonical-direction (get-container 'you) destination)))
  553. (if (object-exists? exit-tag)
  554. (show "An exit like that already exists.")
  555. (begin
  556. (move-object exit-tag (get-container 'you))
  557. (set-hidden exit-tag #t)
  558. (set-destination exit-tag destination)
  559. (map (curry add-alias exit-tag) (get-cardinal-set direction))
  560. (show "You create a passage."))))))))
  561. (define (do-command-exit)
  562. (show "Goodbye, see you later...")
  563. (set! *exit-adventure* #t))
  564. (define (alias-transform input)
  565. (match input
  566. (('quit) '(exit))
  567. (('i) '(inventory))
  568. (('inv) '(inventory))
  569. (('look x) `(examine ,x))
  570. (('go x) `(enter ,x))
  571. (('get x) `(take ,x))
  572. ((x) (if (cardinal-direction? x)
  573. `(enter ,x)
  574. input))
  575. (_ input)))
  576. (define (dispatch-command input)
  577. (let ((success #t))
  578. (match input
  579. (('look) (do-command-look))
  580. (('save) (do-command-save))
  581. (('load) (do-command-load))
  582. (('devmode) (do-command-devmode))
  583. (('exit) (do-command-exit))
  584. (('enter x) (do-command-enter x))
  585. (('take x) (do-command-take x))
  586. (('drop x) (do-command-drop x))
  587. (('inventory) (do-command-inventory))
  588. (('examine x) (do-command-examine x))
  589. (('put x y) (do-command-put x y))
  590. (_ (if (devmode-enabled?)
  591. (match input
  592. (('create x y z) (do-command-create x y z))
  593. (('rename x y) (do-command-rename x y))
  594. (('describe x y) (do-command-describe x y))
  595. (('dig x y) (do-command-dig x y))
  596. (('flag x y) (do-command-flag x y))
  597. (('unflag x y) (do-command-unflag x y))
  598. (('alias x y) (do-command-alias x y))
  599. (('unalias x y) (do-command-unalias x y))
  600. (('destroy x) (do-command-destroy x))
  601. (('aliases x) (do-command-aliases x))
  602. (('message x y z) (do-command-message x y z))
  603. (('goto x) (do-command-goto x))
  604. (_ (set! success #f)))
  605. (set! success #f))))
  606. success))
  607. (create-object 'garden "A Well-Kept Garden" "A french-style garden with topiary in the shape of various animals. A fountain gurgles happily in the middle. A trail leads off into a forest to the north.")
  608. (create-object 'unicorn "a frolicking unicorn" "A white unicorn, with a long spiral horn.")
  609. (create-object 'forest "A Foreboding Forest" "Tall trees bunch around a winding path.")
  610. (create-object 'trail "a trail" "A winding trail.")
  611. (add-alias 'trail 'winding)
  612. (add-alias 'trail 'north)
  613. (add-alias 'trail 'n)
  614. (set-hidden 'trail #t)
  615. (set-enter-message 'trail "You walk along the winding trail...")
  616. (move-object 'you 'garden)
  617. (move-object 'trail 'garden)
  618. (toggle-fixed 'trail)
  619. (set-destination 'trail 'forest)
  620. (move-object 'unicorn 'garden)
  621. (define *exit-adventure* #f)
  622. (define (adventure)
  623. (let ((success (dispatch-command (alias-transform (adventure-prompt)))))
  624. (if (not success)
  625. (begin
  626. (show "I didn't quite understand that.")
  627. (adventure))
  628. (if *exit-adventure*
  629. (display *database*)
  630. (adventure)))))
  631. (print-room-description (get-container 'you))
  632. (adventure)