start new parser for txtadv
parent
6de2df5ceb
commit
cface5b7f9
@ -1,5 +1,5 @@
|
|||||||
#lang br
|
#lang br
|
||||||
|
|
||||||
(module reader br
|
(module reader br
|
||||||
(require "txtadv/reader.rkt")
|
(require "txtadv/reader0.rkt")
|
||||||
(provide (all-from-out "txtadv/reader.rkt")))
|
(provide (all-from-out "txtadv/reader0.rkt")))
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
#lang racket
|
@ -1,5 +0,0 @@
|
|||||||
#lang br
|
|
||||||
|
|
||||||
(module+ reader
|
|
||||||
(require "reader.rkt")
|
|
||||||
(provide (all-from-out "reader.rkt")))
|
|
@ -0,0 +1,15 @@
|
|||||||
|
#lang ragg
|
||||||
|
|
||||||
|
txtadv-program : [verb-section]
|
||||||
|
|
||||||
|
verb-section : verb-heading verb-entry+
|
||||||
|
|
||||||
|
verb-heading : "===VERBS==="
|
||||||
|
|
||||||
|
verb-entry : verb-name+ desc
|
||||||
|
|
||||||
|
verb-name : [","] ID ["_"]
|
||||||
|
|
||||||
|
desc : s-exp
|
||||||
|
|
||||||
|
s-exp : ID | STRING | "(" s-exp* ")"
|
@ -1,160 +1,6 @@
|
|||||||
#lang racket
|
#lang br
|
||||||
(require syntax/readerr)
|
|
||||||
|
|
||||||
(provide (rename-out [txtadv-read-syntax read-syntax])
|
(require br/reader-utils "parser.rkt" "tokenizer.rkt")
|
||||||
;; added at the end to link syntax to colorer:
|
(define-read-and-read-syntax (source-path input-port)
|
||||||
get-info)
|
#`(module txtadv-mod br/demo/txtadv/expander
|
||||||
|
#,(parse source-path (tokenize input-port))))
|
||||||
(define (txtadv-read-syntax src in)
|
|
||||||
(expect-section src in "VERBS")
|
|
||||||
(define verbs (in-section src in read-verb))
|
|
||||||
(expect-section src in "EVERYWHERE")
|
|
||||||
(define actions (in-section src in read-action))
|
|
||||||
(expect-section src in "THINGS")
|
|
||||||
(define things (in-section src in read-thing))
|
|
||||||
(expect-section src in "PLACES")
|
|
||||||
(define places (in-section src in read-place))
|
|
||||||
(datum->syntax
|
|
||||||
#f
|
|
||||||
`(module world br/demo/txtadv/expander
|
|
||||||
(define-verbs all-verbs
|
|
||||||
,@verbs)
|
|
||||||
(define-everywhere everywhere-actions
|
|
||||||
,actions)
|
|
||||||
,@things
|
|
||||||
,@places
|
|
||||||
,(if (null? places)
|
|
||||||
(complain src in "no places defined")
|
|
||||||
(cadar places)))))
|
|
||||||
|
|
||||||
(define (complain src in msg)
|
|
||||||
(define-values (line col pos) (port-next-location in))
|
|
||||||
(raise-read-error msg src line col pos 1))
|
|
||||||
|
|
||||||
(define (skip-whitespace in)
|
|
||||||
(regexp-try-match #px"^\\s+" in))
|
|
||||||
|
|
||||||
(define (expect-section src in name)
|
|
||||||
(skip-whitespace in)
|
|
||||||
(unless (regexp-match-peek (pregexp (format "^===~a===\\s" name))
|
|
||||||
in)
|
|
||||||
(complain src in (format "expected a ===~a=== section" name)))
|
|
||||||
(read-line in)
|
|
||||||
(read-line in))
|
|
||||||
|
|
||||||
(define (in-section src in reader)
|
|
||||||
(skip-whitespace in)
|
|
||||||
(if (or (regexp-match-peek #rx"^===" in)
|
|
||||||
(eof-object? (peek-byte in)))
|
|
||||||
null
|
|
||||||
(cons (reader src in)
|
|
||||||
(in-section src in reader))))
|
|
||||||
|
|
||||||
(define (in-defn src in reader)
|
|
||||||
(skip-whitespace in)
|
|
||||||
(if (or (regexp-match-peek #rx"^(===|---)" in)
|
|
||||||
(eof-object? (peek-byte in)))
|
|
||||||
null
|
|
||||||
(cons (reader src in)
|
|
||||||
(in-defn src in reader))))
|
|
||||||
|
|
||||||
(define (read-name src in)
|
|
||||||
(if (regexp-match-peek #px"^[A-Za-z-]+(?=:$|\\s|[],])" in)
|
|
||||||
(read-syntax src in)
|
|
||||||
(complain src in "expected a name")))
|
|
||||||
|
|
||||||
(define (read-name-sequence src in transitive)
|
|
||||||
(let loop ([names null] [transitive transitive])
|
|
||||||
(define s (read-name src in))
|
|
||||||
(define is-trans?
|
|
||||||
(cond
|
|
||||||
[(regexp-match-peek #rx"^ _" in)
|
|
||||||
(if (or (eq? transitive 'unknown)
|
|
||||||
(eq? transitive #t))
|
|
||||||
(begin
|
|
||||||
(read-char in)
|
|
||||||
(read-char in)
|
|
||||||
#t)
|
|
||||||
(begin
|
|
||||||
(read-char in)
|
|
||||||
(complain src in "unexpected underscore")))]
|
|
||||||
[else
|
|
||||||
(if (eq? transitive #t)
|
|
||||||
(complain src in "inconsistent transitivity")
|
|
||||||
#f)]))
|
|
||||||
(if (regexp-match-peek #rx"^, " in)
|
|
||||||
(begin
|
|
||||||
(read-char in)
|
|
||||||
(read-char in)
|
|
||||||
(loop (cons s names) is-trans?))
|
|
||||||
(values (reverse (cons s names)) is-trans?))))
|
|
||||||
|
|
||||||
(define (read-verb src in)
|
|
||||||
(skip-whitespace in)
|
|
||||||
(define-values (names is-transitive?)
|
|
||||||
(read-name-sequence src in 'unknown))
|
|
||||||
(skip-whitespace in)
|
|
||||||
(define desc
|
|
||||||
(if (regexp-match-peek #rx"^\"" in)
|
|
||||||
(read-syntax src in)
|
|
||||||
(symbol->string (syntax-e (car names)))))
|
|
||||||
`[,(car names)
|
|
||||||
,@(if is-transitive? '(_) '())
|
|
||||||
(= ,@(cdr names))
|
|
||||||
,desc])
|
|
||||||
|
|
||||||
(define (read-action src in)
|
|
||||||
(skip-whitespace in)
|
|
||||||
(define name (read-name src in))
|
|
||||||
(define expr (read-syntax src in))
|
|
||||||
`[,name ,expr])
|
|
||||||
|
|
||||||
(define (read-defn-name src in what)
|
|
||||||
(skip-whitespace in)
|
|
||||||
(unless (regexp-match-peek #px"^---[A-Za-z][A-Za-z0-9-]*---\\s"
|
|
||||||
in)
|
|
||||||
(complain src in (format "expected a ~a definition of the form ---name---" what)))
|
|
||||||
(read-string 3 in)
|
|
||||||
(define-values (line col pos) (port-next-location in))
|
|
||||||
(define name-str (bytes->string/utf-8 (cadr (regexp-match #px"^(.*?)---\\s" in))))
|
|
||||||
(datum->syntax #f
|
|
||||||
(string->symbol name-str)
|
|
||||||
(vector src line col pos (string-length name-str))
|
|
||||||
orig-props))
|
|
||||||
(define orig-props (read-syntax 'src (open-input-string "orig")))
|
|
||||||
|
|
||||||
(define (read-thing src in)
|
|
||||||
(define name (read-defn-name src in "thing"))
|
|
||||||
(define actions (in-defn src in read-action))
|
|
||||||
`(define-thing ,name
|
|
||||||
,@actions))
|
|
||||||
|
|
||||||
(define (read-place src in)
|
|
||||||
(define name (read-defn-name src in "place"))
|
|
||||||
(skip-whitespace in)
|
|
||||||
(define desc (if (regexp-match-peek #rx"^\"" in)
|
|
||||||
(read-syntax src in)
|
|
||||||
(complain src in "expected description string")))
|
|
||||||
(skip-whitespace in)
|
|
||||||
(unless (regexp-match-peek #rx"^[[]" in)
|
|
||||||
(complain src in "expected a square bracket to start a list of things for a place"))
|
|
||||||
(read-char in)
|
|
||||||
(define-values (things _)
|
|
||||||
(if (regexp-match-peek #rx"^[]]" in)
|
|
||||||
(values null #f)
|
|
||||||
(read-name-sequence src in #f)))
|
|
||||||
(unless (regexp-match-peek #rx"^[]]" in)
|
|
||||||
(complain src in "expected a square bracket to end a list of things for a place"))
|
|
||||||
(read-char in)
|
|
||||||
(define actions (in-defn src in read-action))
|
|
||||||
`(define-place ,name ,desc ,things ,actions))
|
|
||||||
|
|
||||||
;; DrRacket asks `get-info' for a 'color-lexer module:
|
|
||||||
(require racket/runtime-path)
|
|
||||||
(define-runtime-path color-lexer-path "color.rkt")
|
|
||||||
(define (get-info in mod line col pos)
|
|
||||||
(lambda (key default)
|
|
||||||
(case key
|
|
||||||
[(color-lexer)
|
|
||||||
(dynamic-require color-lexer-path 'color-lexer)]
|
|
||||||
[else default])))
|
|
||||||
|
@ -0,0 +1,160 @@
|
|||||||
|
#lang racket
|
||||||
|
(require syntax/readerr)
|
||||||
|
|
||||||
|
(provide (rename-out [txtadv-read-syntax read-syntax])
|
||||||
|
;; added at the end to link syntax to colorer:
|
||||||
|
get-info)
|
||||||
|
|
||||||
|
(define (txtadv-read-syntax src in)
|
||||||
|
(expect-section src in "VERBS")
|
||||||
|
(define verbs (in-section src in read-verb))
|
||||||
|
(expect-section src in "EVERYWHERE")
|
||||||
|
(define actions (in-section src in read-action))
|
||||||
|
(expect-section src in "THINGS")
|
||||||
|
(define things (in-section src in read-thing))
|
||||||
|
(expect-section src in "PLACES")
|
||||||
|
(define places (in-section src in read-place))
|
||||||
|
(datum->syntax
|
||||||
|
#f
|
||||||
|
`(module world br/demo/txtadv/expander
|
||||||
|
(define-verbs all-verbs
|
||||||
|
,@verbs)
|
||||||
|
(define-everywhere everywhere-actions
|
||||||
|
,actions)
|
||||||
|
,@things
|
||||||
|
,@places
|
||||||
|
,(if (null? places)
|
||||||
|
(complain src in "no places defined")
|
||||||
|
(cadar places)))))
|
||||||
|
|
||||||
|
(define (complain src in msg)
|
||||||
|
(define-values (line col pos) (port-next-location in))
|
||||||
|
(raise-read-error msg src line col pos 1))
|
||||||
|
|
||||||
|
(define (skip-whitespace in)
|
||||||
|
(regexp-try-match #px"^\\s+" in))
|
||||||
|
|
||||||
|
(define (expect-section src in name)
|
||||||
|
(skip-whitespace in)
|
||||||
|
(unless (regexp-match-peek (pregexp (format "^===~a===\\s" name))
|
||||||
|
in)
|
||||||
|
(complain src in (format "expected a ===~a=== section" name)))
|
||||||
|
(read-line in)
|
||||||
|
(read-line in))
|
||||||
|
|
||||||
|
(define (in-section src in reader)
|
||||||
|
(skip-whitespace in)
|
||||||
|
(if (or (regexp-match-peek #rx"^===" in)
|
||||||
|
(eof-object? (peek-byte in)))
|
||||||
|
null
|
||||||
|
(cons (reader src in)
|
||||||
|
(in-section src in reader))))
|
||||||
|
|
||||||
|
(define (in-defn src in reader)
|
||||||
|
(skip-whitespace in)
|
||||||
|
(if (or (regexp-match-peek #rx"^(===|---)" in)
|
||||||
|
(eof-object? (peek-byte in)))
|
||||||
|
null
|
||||||
|
(cons (reader src in)
|
||||||
|
(in-defn src in reader))))
|
||||||
|
|
||||||
|
(define (read-name src in)
|
||||||
|
(if (regexp-match-peek #px"^[A-Za-z-]+(?=:$|\\s|[],])" in)
|
||||||
|
(read-syntax src in)
|
||||||
|
(complain src in "expected a name")))
|
||||||
|
|
||||||
|
(define (read-name-sequence src in transitive)
|
||||||
|
(let loop ([names null] [transitive transitive])
|
||||||
|
(define s (read-name src in))
|
||||||
|
(define is-trans?
|
||||||
|
(cond
|
||||||
|
[(regexp-match-peek #rx"^ _" in)
|
||||||
|
(if (or (eq? transitive 'unknown)
|
||||||
|
(eq? transitive #t))
|
||||||
|
(begin
|
||||||
|
(read-char in)
|
||||||
|
(read-char in)
|
||||||
|
#t)
|
||||||
|
(begin
|
||||||
|
(read-char in)
|
||||||
|
(complain src in "unexpected underscore")))]
|
||||||
|
[else
|
||||||
|
(if (eq? transitive #t)
|
||||||
|
(complain src in "inconsistent transitivity")
|
||||||
|
#f)]))
|
||||||
|
(if (regexp-match-peek #rx"^, " in)
|
||||||
|
(begin
|
||||||
|
(read-char in)
|
||||||
|
(read-char in)
|
||||||
|
(loop (cons s names) is-trans?))
|
||||||
|
(values (reverse (cons s names)) is-trans?))))
|
||||||
|
|
||||||
|
(define (read-verb src in)
|
||||||
|
(skip-whitespace in)
|
||||||
|
(define-values (names is-transitive?)
|
||||||
|
(read-name-sequence src in 'unknown))
|
||||||
|
(skip-whitespace in)
|
||||||
|
(define desc
|
||||||
|
(if (regexp-match-peek #rx"^\"" in)
|
||||||
|
(read-syntax src in)
|
||||||
|
(symbol->string (syntax-e (car names)))))
|
||||||
|
`[,(car names)
|
||||||
|
,@(if is-transitive? '(_) '())
|
||||||
|
(= ,@(cdr names))
|
||||||
|
,desc])
|
||||||
|
|
||||||
|
(define (read-action src in)
|
||||||
|
(skip-whitespace in)
|
||||||
|
(define name (read-name src in))
|
||||||
|
(define expr (read-syntax src in))
|
||||||
|
`[,name ,expr])
|
||||||
|
|
||||||
|
(define (read-defn-name src in what)
|
||||||
|
(skip-whitespace in)
|
||||||
|
(unless (regexp-match-peek #px"^---[A-Za-z][A-Za-z0-9-]*---\\s"
|
||||||
|
in)
|
||||||
|
(complain src in (format "expected a ~a definition of the form ---name---" what)))
|
||||||
|
(read-string 3 in)
|
||||||
|
(define-values (line col pos) (port-next-location in))
|
||||||
|
(define name-str (bytes->string/utf-8 (cadr (regexp-match #px"^(.*?)---\\s" in))))
|
||||||
|
(datum->syntax #f
|
||||||
|
(string->symbol name-str)
|
||||||
|
(vector src line col pos (string-length name-str))
|
||||||
|
orig-props))
|
||||||
|
(define orig-props (read-syntax 'src (open-input-string "orig")))
|
||||||
|
|
||||||
|
(define (read-thing src in)
|
||||||
|
(define name (read-defn-name src in "thing"))
|
||||||
|
(define actions (in-defn src in read-action))
|
||||||
|
`(define-thing ,name
|
||||||
|
,@actions))
|
||||||
|
|
||||||
|
(define (read-place src in)
|
||||||
|
(define name (read-defn-name src in "place"))
|
||||||
|
(skip-whitespace in)
|
||||||
|
(define desc (if (regexp-match-peek #rx"^\"" in)
|
||||||
|
(read-syntax src in)
|
||||||
|
(complain src in "expected description string")))
|
||||||
|
(skip-whitespace in)
|
||||||
|
(unless (regexp-match-peek #rx"^[[]" in)
|
||||||
|
(complain src in "expected a square bracket to start a list of things for a place"))
|
||||||
|
(read-char in)
|
||||||
|
(define-values (things _)
|
||||||
|
(if (regexp-match-peek #rx"^[]]" in)
|
||||||
|
(values null #f)
|
||||||
|
(read-name-sequence src in #f)))
|
||||||
|
(unless (regexp-match-peek #rx"^[]]" in)
|
||||||
|
(complain src in "expected a square bracket to end a list of things for a place"))
|
||||||
|
(read-char in)
|
||||||
|
(define actions (in-defn src in read-action))
|
||||||
|
`(define-place ,name ,desc ,things ,actions))
|
||||||
|
|
||||||
|
;; DrRacket asks `get-info' for a 'color-lexer module:
|
||||||
|
(require racket/runtime-path)
|
||||||
|
(define-runtime-path color-lexer-path "color.rkt")
|
||||||
|
(define (get-info in mod line col pos)
|
||||||
|
(lambda (key default)
|
||||||
|
(case key
|
||||||
|
[(color-lexer)
|
||||||
|
(dynamic-require color-lexer-path 'color-lexer)]
|
||||||
|
[else default])))
|
@ -0,0 +1,23 @@
|
|||||||
|
#lang br
|
||||||
|
(require parser-tools/lex parser-tools/lex-sre
|
||||||
|
ragg/support
|
||||||
|
racket/string)
|
||||||
|
|
||||||
|
(provide tokenize)
|
||||||
|
(define (tokenize input-port)
|
||||||
|
(define (next-token)
|
||||||
|
(define get-token
|
||||||
|
(lexer
|
||||||
|
[(eof) eof]
|
||||||
|
[(union
|
||||||
|
(seq "/*" (complement (seq any-string "*/" any-string)) "*/")
|
||||||
|
(seq "//" (repetition 1 +inf.0 (char-complement #\newline)) #\newline))
|
||||||
|
(token 'COMMENT lexeme #:skip? #t)]
|
||||||
|
[(union #\tab #\space #\newline) (get-token input-port)]
|
||||||
|
[(repetition 1 +inf.0 (union upper-case (char-set "="))) lexeme]
|
||||||
|
[(seq "\"" (complement (seq any-string "\"" any-string)) "\"") (token 'STRING lexeme)]
|
||||||
|
[(char-set ",_") lexeme]
|
||||||
|
[(repetition 1 +inf.0 (union alphabetic numeric (char-set "-.")))
|
||||||
|
(token 'ID (string->symbol lexeme))]))
|
||||||
|
(get-token input-port))
|
||||||
|
next-token)
|
@ -0,0 +1,41 @@
|
|||||||
|
#lang at-exp racket
|
||||||
|
(require rackunit)
|
||||||
|
(require "world0.rkt")
|
||||||
|
|
||||||
|
(check-equal? (with-output-to-string (λ _ (do-place)))
|
||||||
|
"You're standing in a meadow. There is a house to the north.\n")
|
||||||
|
|
||||||
|
(define-syntax-rule (check-cmd? cmd result)
|
||||||
|
(check-equal? (with-output-to-string (λ _ (do-verb cmd))) result))
|
||||||
|
|
||||||
|
(check-cmd?
|
||||||
|
"s"
|
||||||
|
"You're in a desert. There is nothing for miles around.\nThere is a cactus here.\nThere is a key here.\n")
|
||||||
|
|
||||||
|
(check-cmd?
|
||||||
|
"get cactus"
|
||||||
|
"Ouch!\n")
|
||||||
|
|
||||||
|
(check-cmd?
|
||||||
|
"get key"
|
||||||
|
"You now have the key.\n")
|
||||||
|
|
||||||
|
(check-cmd?
|
||||||
|
"n"
|
||||||
|
"You're standing in a meadow. There is a house to the north.\n")
|
||||||
|
|
||||||
|
(check-cmd?
|
||||||
|
"n"
|
||||||
|
"You are standing in front of a house.\nThere is a door here.\n")
|
||||||
|
|
||||||
|
(check-cmd?
|
||||||
|
"open door"
|
||||||
|
"The door is now unlocked and open.\n")
|
||||||
|
|
||||||
|
(check-cmd?
|
||||||
|
"enter"
|
||||||
|
"You're in the house.\nThere is a trophy here.\n")
|
||||||
|
|
||||||
|
(check-cmd?
|
||||||
|
"get trophy"
|
||||||
|
"You win!\n")
|
@ -0,0 +1,162 @@
|
|||||||
|
#lang br/demo/txtadv
|
||||||
|
|
||||||
|
===VERBS===
|
||||||
|
|
||||||
|
north, n
|
||||||
|
"go north"
|
||||||
|
|
||||||
|
south, s
|
||||||
|
"go south"
|
||||||
|
|
||||||
|
east, e
|
||||||
|
"go east"
|
||||||
|
|
||||||
|
west, w
|
||||||
|
"go west"
|
||||||
|
|
||||||
|
up
|
||||||
|
"go up"
|
||||||
|
|
||||||
|
down
|
||||||
|
"go down"
|
||||||
|
|
||||||
|
in, enter
|
||||||
|
"enter"
|
||||||
|
|
||||||
|
out, leave
|
||||||
|
"leave"
|
||||||
|
|
||||||
|
get _, grab _, take _
|
||||||
|
"take"
|
||||||
|
|
||||||
|
put _, drop _, leave _
|
||||||
|
"drop"
|
||||||
|
|
||||||
|
open _, unlock _
|
||||||
|
"open"
|
||||||
|
|
||||||
|
close _, lock _
|
||||||
|
"close"
|
||||||
|
|
||||||
|
knock _
|
||||||
|
|
||||||
|
quit, exit
|
||||||
|
"quit"
|
||||||
|
|
||||||
|
look, show
|
||||||
|
"look"
|
||||||
|
|
||||||
|
inventory
|
||||||
|
"check inventory"
|
||||||
|
|
||||||
|
|
||||||
|
===EVERYWHERE===
|
||||||
|
|
||||||
|
quit
|
||||||
|
(begin
|
||||||
|
(printf "Bye!\n")
|
||||||
|
(exit))
|
||||||
|
|
||||||
|
look
|
||||||
|
(show-current-place)
|
||||||
|
|
||||||
|
inventory
|
||||||
|
(show-inventory)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
===THINGS===
|
||||||
|
|
||||||
|
---cactus---
|
||||||
|
get
|
||||||
|
"Ouch!"
|
||||||
|
|
||||||
|
---door---
|
||||||
|
open
|
||||||
|
(if (have-thing? key)
|
||||||
|
(begin
|
||||||
|
(set-thing-state! door 'open)
|
||||||
|
"The door is now unlocked and open.")
|
||||||
|
"The door is locked.")
|
||||||
|
|
||||||
|
close
|
||||||
|
(begin
|
||||||
|
(set-thing-state! door #f)
|
||||||
|
"The door is now closed.")
|
||||||
|
|
||||||
|
knock
|
||||||
|
"No one is home."
|
||||||
|
|
||||||
|
---key---
|
||||||
|
|
||||||
|
get
|
||||||
|
(if (have-thing? key)
|
||||||
|
"You already have the key."
|
||||||
|
(begin
|
||||||
|
(take-thing! key)
|
||||||
|
"You now have the key."))
|
||||||
|
|
||||||
|
put
|
||||||
|
(if (have-thing? key)
|
||||||
|
(begin
|
||||||
|
(drop-thing! key)
|
||||||
|
"You have dropped the key.")
|
||||||
|
"You don't have the key.")
|
||||||
|
|
||||||
|
---trophy---
|
||||||
|
|
||||||
|
get
|
||||||
|
(begin
|
||||||
|
(take-thing! trophy)
|
||||||
|
"You win!")
|
||||||
|
|
||||||
|
|
||||||
|
===PLACES===
|
||||||
|
|
||||||
|
---meadow---
|
||||||
|
"You're standing in a meadow. There is a house to the north."
|
||||||
|
[]
|
||||||
|
|
||||||
|
north
|
||||||
|
house-front
|
||||||
|
|
||||||
|
south
|
||||||
|
desert
|
||||||
|
|
||||||
|
|
||||||
|
---house-front---
|
||||||
|
"You are standing in front of a house."
|
||||||
|
[door]
|
||||||
|
|
||||||
|
in
|
||||||
|
(if (eq? (thing-state door) 'open)
|
||||||
|
room
|
||||||
|
"The door is not open.")
|
||||||
|
|
||||||
|
south
|
||||||
|
meadow
|
||||||
|
|
||||||
|
|
||||||
|
---desert---
|
||||||
|
"You're in a desert. There is nothing for miles around."
|
||||||
|
[cactus, key]
|
||||||
|
|
||||||
|
north
|
||||||
|
meadow
|
||||||
|
|
||||||
|
south
|
||||||
|
desert
|
||||||
|
|
||||||
|
east
|
||||||
|
desert
|
||||||
|
|
||||||
|
west
|
||||||
|
desert
|
||||||
|
|
||||||
|
|
||||||
|
---room---
|
||||||
|
"You're in the house."
|
||||||
|
[trophy]
|
||||||
|
|
||||||
|
out
|
||||||
|
house-front
|
Loading…
Reference in New Issue